1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use crate::ConfigurationSection;
use tokens::ChangeToken;
pub trait Configuration {
fn get(&self, key: &str) -> Option<&str>;
fn section(&self, key: &str) -> Box<dyn ConfigurationSection>;
fn children(&self) -> Vec<Box<dyn ConfigurationSection>>;
fn reload_token(&self) -> Box<dyn ChangeToken>;
fn as_section(&self) -> Option<&dyn ConfigurationSection> {
None
}
fn iter(&self) -> Box<dyn Iterator<Item = (String, String)>> {
self.iter_relative(false)
}
fn iter_relative(
&self,
make_paths_relative: bool,
) -> Box<dyn Iterator<Item = (String, String)>>;
}
pub struct ConfigurationIterator {
stack: Vec<Box<dyn ConfigurationSection>>,
first: Option<(String, String)>,
prefix_length: usize,
}
impl ConfigurationIterator {
pub fn new(configuration: &dyn Configuration, make_paths_relative: bool) -> Self {
let stack: Vec<_> = configuration.children().into_iter().collect();
let mut first = None;
let mut prefix_length = 0;
if let Some(root) = configuration.as_section() {
if make_paths_relative {
prefix_length = root.path().len() + 1;
}
if !make_paths_relative {
let key = root.path()[prefix_length..].to_owned();
let value = root.value().to_owned();
first = Some((key, value));
}
}
Self {
stack,
first,
prefix_length,
}
}
}
impl Iterator for ConfigurationIterator {
type Item = (String, String);
fn next(&mut self) -> Option<Self::Item> {
if let Some(first) = self.first.take() {
return Some(first);
}
while let Some(config) = self.stack.pop() {
self.stack.extend(config.children().into_iter());
if let Some(section) = config.as_section() {
let key = section.path()[self.prefix_length..].to_owned();
let value = section.value().to_owned();
return Some((key, value));
}
}
None
}
}