diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 66 |
1 files changed, 47 insertions, 19 deletions
@@ -742,16 +742,11 @@ impl Configuration { /// /// The order of items returned is arbitrary and may change /// in future versions without notice. - pub fn keys(&self) -> impl '_ + Iterator<Item = &str> { - let mut prev = None; - self.items.iter().filter_map(move |(key, _)| { - let first_component: &str = key.split_once('.').map_or(key.as_ref(), |(c, _)| c); - if prev == Some(first_component) { - return None; - } - prev = Some(first_component); - Some(first_component) - }) + pub fn keys(&self) -> Keys<'_> { + Keys { + iter: self.items.iter(), + prev: None, + } } /// Get all defined keys in this configuration, including nested ones, @@ -942,20 +937,17 @@ impl Configuration { /// /// Beware of race conditions when using this function in a multithreaded program /// (you should wait for all threads to finish reading the configuration before calling this). - pub fn unread_keys(&self) -> impl '_ + Iterator<Item = &str> { - self.items.iter().filter_map(|(k, v)| { - if !v.read.load(Ordering::Relaxed) { - Some(k.as_ref()) - } else { - None - } - }) + pub fn unread_keys(&self) -> UnreadKeys<'_> { + UnreadKeys(self.items.iter()) } } +// Type returned by `Configuration.items.iter()` +type ItemsIter<'a> = core::slice::Iter<'a, (Box<str>, Arc<Value>)>; + /// Opaque type returned by [`Configuration::iter`]. #[derive(Clone, Debug)] -pub struct ConfigurationIter<'a>(core::slice::Iter<'a, (Box<str>, Arc<Value>)>); +pub struct ConfigurationIter<'a>(ItemsIter<'a>); impl<'a> Iterator for ConfigurationIter<'a> { type Item = (&'a str, &'a str); @@ -965,6 +957,42 @@ impl<'a> Iterator for ConfigurationIter<'a> { } } +/// Opaque type returned by [`Configuration::keys`]. +#[derive(Clone, Debug)] +pub struct Keys<'a> { + prev: Option<&'a str>, + iter: ItemsIter<'a>, +} +impl<'a> Iterator for Keys<'a> { + type Item = &'a str; + fn next(&mut self) -> Option<Self::Item> { + loop { + let (key, _) = self.iter.next()?; + let first_component: &str = key.split_once('.').map_or(key.as_ref(), |(c, _)| c); + if self.prev != Some(first_component) { + self.prev = Some(first_component); + return Some(first_component); + } + } + } +} + +/// Opaque type returned by [`Configuration::unread_keys`]. +#[derive(Clone, Debug)] +pub struct UnreadKeys<'a>(ItemsIter<'a>); + +impl<'a> Iterator for UnreadKeys<'a> { + type Item = &'a str; + fn next(&mut self) -> Option<Self::Item> { + loop { + let (k, v) = self.0.next()?; + if !v.read.load(Ordering::Relaxed) { + return Some(k.as_ref()); + } + } + } +} + impl<'a> IntoIterator for &'a Configuration { type IntoIter = ConfigurationIter<'a>; type Item = (&'a str, &'a str); |