Mercurial > hg
diff rust/hg-core/src/config/config.rs @ 48451:4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
This fixes some but not all failures in `tests/test-hgignore.t` when running
with `rhg status` enabled.
Differential Revision: https://phab.mercurial-scm.org/D11907
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Fri, 10 Dec 2021 14:27:00 +0100 |
parents | 1d940d76571b |
children | 1aaf11e35aec |
line wrap: on
line diff
--- a/rust/hg-core/src/config/config.rs Fri Dec 10 17:20:21 2021 +0100 +++ b/rust/hg-core/src/config/config.rs Fri Dec 10 14:27:00 2021 +0100 @@ -419,6 +419,59 @@ .any(|layer| layer.has_non_empty_section(section)) } + /// Yields (key, value) pairs for everything in the given section + pub fn iter_section<'a>( + &'a self, + section: &'a [u8], + ) -> impl Iterator<Item = (&[u8], &[u8])> + 'a { + // TODO: Use `Iterator`’s `.peekable()` when its `peek_mut` is + // available: + // https://doc.rust-lang.org/nightly/std/iter/struct.Peekable.html#method.peek_mut + struct Peekable<I: Iterator> { + iter: I, + /// Remember a peeked value, even if it was None. + peeked: Option<Option<I::Item>>, + } + + impl<I: Iterator> Peekable<I> { + fn new(iter: I) -> Self { + Self { iter, peeked: None } + } + + fn next(&mut self) { + self.peeked = None + } + + fn peek_mut(&mut self) -> Option<&mut I::Item> { + let iter = &mut self.iter; + self.peeked.get_or_insert_with(|| iter.next()).as_mut() + } + } + + // Deduplicate keys redefined in multiple layers + let mut keys_already_seen = HashSet::new(); + let mut key_is_new = + move |&(key, _value): &(&'a [u8], &'a [u8])| -> bool { + keys_already_seen.insert(key) + }; + // This is similar to `flat_map` + `filter_map`, except with a single + // closure that owns `key_is_new` (and therefore the + // `keys_already_seen` set): + let mut layer_iters = Peekable::new( + self.layers + .iter() + .rev() + .map(move |layer| layer.iter_section(section)), + ); + std::iter::from_fn(move || loop { + if let Some(pair) = layer_iters.peek_mut()?.find(&mut key_is_new) { + return Some(pair); + } else { + layer_iters.next(); + } + }) + } + /// Get raw values bytes from all layers (even untrusted ones) in order /// of precedence. #[cfg(test)]