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
|
use crate::Configuration;
use std::collections::HashSet;
mod parsing;
fn check_configs_equal(
cfg1: &Configuration,
cfg2: &Configuration,
) -> Result<(), Box<dyn std::error::Error>> {
fn check_configs_equal_at(
cfg1: &Configuration,
cfg2: &Configuration,
prefix: &str,
) -> Result<(), Box<dyn std::error::Error>> {
let (keys1, keys2): (HashSet<&str>, HashSet<&str>) =
if let Some(k) = prefix.strip_suffix('.') {
(cfg1.subkeys(k).collect(), cfg2.subkeys(k).collect())
} else {
(cfg1.keys().collect(), cfg2.keys().collect())
};
for key in keys1.difference(&keys2) {
return Err(format!(
"Key {prefix}{key} appears at {}, but not in other configuration",
cfg1.location(&format!("{prefix}{key}")).unwrap()
)
.into());
}
for key in keys2.difference(&keys1) {
return Err(format!(
"Key {prefix}{key} appears at {}, but not in other configuration",
cfg2.location(&format!("{prefix}{key}")).unwrap()
)
.into());
}
for key in &keys1 {
let full_key = format!("{prefix}{key}");
let val1 = cfg1.get(&full_key);
let val2 = cfg2.get(&full_key);
if val1 != val2 {
return Err(format!(
"Mismatch between values for key {full_key}
defined as {val1:?} at {},
but defined as {val2:?} at {}",
cfg1.location(&full_key)
.map_or("<nowhere>".into(), |x| format!("{x}")),
cfg2.location(&full_key)
.map_or("<nowhere>".into(), |x| format!("{x}")),
)
.into());
}
check_configs_equal_at(cfg1, cfg2, &format!("{full_key}."))?;
}
Ok(())
}
check_configs_equal_at(cfg1, cfg2, "")
}
|