Mercurial > public > mercurial-scm > hg-stable
comparison rust/hg-core/src/utils.rs @ 51189:aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Adding a function merge_join_results_by, a version of
itertools::merge_join_by that works on "fallible" iterators
(iterators that can produce errors)
author | Arseniy Alekseyev <aalekseyev@janestreet.com> |
---|---|
date | Wed, 15 Nov 2023 18:41:33 +0000 |
parents | 331a3cbe1c9e |
children | e6a44bc91bc2 |
comparison
equal
deleted
inserted
replaced
51188:976403c95ba3 | 51189:aba622c7dc7e |
---|---|
9 | 9 |
10 use crate::errors::{HgError, IoErrorContext}; | 10 use crate::errors::{HgError, IoErrorContext}; |
11 use crate::utils::hg_path::HgPath; | 11 use crate::utils::hg_path::HgPath; |
12 use im_rc::ordmap::DiffItem; | 12 use im_rc::ordmap::DiffItem; |
13 use im_rc::ordmap::OrdMap; | 13 use im_rc::ordmap::OrdMap; |
14 use itertools::EitherOrBoth; | |
15 use itertools::Itertools; | |
14 use std::cell::Cell; | 16 use std::cell::Cell; |
17 use std::cmp::Ordering; | |
15 use std::fmt; | 18 use std::fmt; |
16 use std::{io::Write, ops::Deref}; | 19 use std::{io::Write, ops::Deref}; |
17 | 20 |
18 pub mod debug; | 21 pub mod debug; |
19 pub mod files; | 22 pub mod files; |
497 Ok(node) => f(node).transpose(), | 500 Ok(node) => f(node).transpose(), |
498 Err(e) => Some(Err(e)), | 501 Err(e) => Some(Err(e)), |
499 }) | 502 }) |
500 } | 503 } |
501 | 504 |
505 /// Like `itertools::merge_join_by`, but merges fallible iterators. | |
506 /// | |
507 /// The callback is only used for Ok values. Errors are passed through as-is. | |
508 /// Errors compare less than Ok values, which makes the error handling | |
509 /// conservative. | |
510 pub fn merge_join_results_by<'a, I1, I2, F, A, B, E>( | |
511 iter1: I1, | |
512 iter2: I2, | |
513 f: F, | |
514 ) -> impl Iterator<Item = Result<EitherOrBoth<A, B>, E>> + 'a | |
515 where | |
516 I1: Iterator<Item = Result<A, E>> + 'a, | |
517 I2: Iterator<Item = Result<B, E>> + 'a, | |
518 F: FnMut(&A, &B) -> Ordering + 'a, | |
519 { | |
520 let mut g = f; | |
521 iter1 | |
522 .merge_join_by(iter2, move |i1, i2| match i1 { | |
523 Err(_) => Ordering::Less, | |
524 Ok(i1) => match i2 { | |
525 Err(_) => Ordering::Greater, | |
526 Ok(i2) => g(i1, i2), | |
527 }, | |
528 }) | |
529 .map(|result| match result { | |
530 EitherOrBoth::Left(Err(e)) => Err(e), | |
531 EitherOrBoth::Right(Err(e)) => Err(e), | |
532 EitherOrBoth::Both(Err(e), _) => Err(e), | |
533 EitherOrBoth::Both(_, Err(e)) => Err(e), | |
534 EitherOrBoth::Left(Ok(v)) => Ok(EitherOrBoth::Left(v)), | |
535 EitherOrBoth::Right(Ok(v)) => Ok(EitherOrBoth::Right(v)), | |
536 EitherOrBoth::Both(Ok(v1), Ok(v2)) => { | |
537 Ok(EitherOrBoth::Both(v1, v2)) | |
538 } | |
539 }) | |
540 } | |
541 | |
502 /// Force the global rayon threadpool to not exceed 16 concurrent threads | 542 /// Force the global rayon threadpool to not exceed 16 concurrent threads |
503 /// unless the user has specified a value. | 543 /// unless the user has specified a value. |
504 /// This is a stop-gap measure until we figure out why using more than 16 | 544 /// This is a stop-gap measure until we figure out why using more than 16 |
505 /// threads makes `status` slower for each additional thread. | 545 /// threads makes `status` slower for each additional thread. |
506 /// | 546 /// |