summaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs66
1 files changed, 47 insertions, 19 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 33d1d2d..bec32c1 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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);