facet_diff_core/
path.rs

1//! Path types for navigating diff trees.
2
3use std::borrow::Cow;
4
5/// A path segment describing how to reach a child.
6#[derive(Debug, Clone, PartialEq, Eq, Hash)]
7pub enum PathSegment {
8    /// A named field in a struct
9    Field(Cow<'static, str>),
10    /// An index in a list/array
11    Index(usize),
12    /// A key in a map
13    Key(Cow<'static, str>),
14    /// An enum variant
15    Variant(Cow<'static, str>),
16}
17
18/// A path from root to a node.
19#[derive(Debug, Clone, PartialEq, Eq, Default, Hash)]
20pub struct Path(pub Vec<PathSegment>);
21
22impl Path {
23    /// Create a new empty path.
24    pub fn new() -> Self {
25        Self(Vec::new())
26    }
27
28    /// Append a segment to this path.
29    pub fn push(&mut self, segment: PathSegment) {
30        self.0.push(segment);
31    }
32
33    /// Create a new path with an additional segment.
34    pub fn with(&self, segment: PathSegment) -> Self {
35        let mut new = self.clone();
36        new.push(segment);
37        new
38    }
39}
40
41impl core::fmt::Display for Path {
42    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
43        for (i, segment) in self.0.iter().enumerate() {
44            if i > 0 {
45                write!(f, ".")?;
46            }
47            match segment {
48                PathSegment::Field(name) => write!(f, "{}", name)?,
49                PathSegment::Index(idx) => write!(f, "[{}]", idx)?,
50                PathSegment::Key(key) => write!(f, "[{:?}]", key)?,
51                PathSegment::Variant(name) => write!(f, "::{}", name)?,
52            }
53        }
54        Ok(())
55    }
56}