statime_config/tree/
path.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7enum PathSegment {
8 Field(&'static str),
9 Index(usize),
10}
11
12#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct ConfigPath(Vec<PathSegment>);
16
17impl ConfigPath {
18 pub fn root() -> Self {
19 Self(vec![])
20 }
21
22 pub fn at<R>(&mut self, field: &'static str, f: impl FnOnce(&mut Self) -> R) -> R {
24 self.push_field(field);
25 let result = f(self);
26 self.pop();
27 result
28 }
29
30 pub(crate) fn at_index<R>(&mut self, index: usize, f: impl FnOnce(&mut Self) -> R) -> R {
32 self.0.push(PathSegment::Index(index));
33 let result = f(self);
34 self.pop();
35 result
36 }
37
38 pub(crate) fn push_field(&mut self, field: &'static str) {
39 self.0.push(PathSegment::Field(field));
40 }
41
42 pub(crate) fn pop(&mut self) {
43 self.0.pop();
44 }
45}
46
47impl std::fmt::Display for ConfigPath {
48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49 for (pos, segment) in self.0.iter().enumerate() {
50 match segment {
51 PathSegment::Field(field) => {
52 if pos != 0 {
53 write!(f, ".")?;
54 }
55 write!(f, "{field}")?
56 }
57 PathSegment::Index(index) => write!(f, "[{index}]")?,
58 }
59 }
60
61 Ok(())
62 }
63}