vitaminc_aead/plaintext/
path.rs1use vitaminc_protected::OpaqueDebug;
4
5#[derive(Clone, PartialEq, Eq, OpaqueDebug)]
14pub enum Step {
15 Index(#[non_sensitive] usize),
17 Key(String),
19}
20
21#[derive(Clone, Default, PartialEq, Eq, OpaqueDebug)]
29pub struct Path(#[non_sensitive] Vec<Step>);
30
31impl Path {
32 pub fn new(steps: Vec<Step>) -> Self {
34 Self(steps)
35 }
36
37 pub fn steps(&self) -> &[Step] {
39 &self.0
40 }
41}
42
43#[cfg(any(test, feature = "test-support"))]
51#[doc(hidden)]
52pub fn render(path: &Path) -> String {
53 path.steps()
54 .iter()
55 .map(|step| match step {
56 Step::Index(i) => format!("[{i}]"),
57 Step::Key(k) => format!(".{k}"),
58 })
59 .collect()
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn render_writes_keys_and_indexes() {
68 let path = Path::new(vec![
69 Step::Key("m".into()),
70 Step::Index(0),
71 Step::Key("k".into()),
72 ]);
73 assert_eq!(render(&path), ".m[0].k");
74 assert_eq!(render(&Path::default()), "");
75 }
76
77 #[test]
78 fn steps_are_kept_root_first() {
79 let path = Path::new(vec![Step::Key("a".into()), Step::Index(2)]);
80 assert_eq!(path.steps(), [Step::Key("a".into()), Step::Index(2)]);
81 assert!(Path::default().steps().is_empty());
82 }
83
84 #[test]
85 fn paths_compare_step_by_step() {
86 let path = |steps: Vec<Step>| Path::new(steps);
87 let a = path(vec![Step::Key("a".into()), Step::Index(2)]);
88 assert_eq!(a, a.clone());
89 assert_ne!(a, path(vec![Step::Key("b".into()), Step::Index(2)]));
90 assert_ne!(a, path(vec![Step::Key("a".into()), Step::Index(3)]));
91 assert_ne!(a, path(vec![Step::Key("a".into())]));
92 assert_ne!(Step::Index(0), Step::Key("0".into()));
93 assert_eq!(Path::default(), path(Vec::new()));
94 }
95
96 #[test]
97 fn debug_shows_indexes_and_masks_keys() {
98 let path = Path::new(vec![Step::Key("ada@example.com".into()), Step::Index(2)]);
99 let shown = format!("{path:?}");
100 assert!(!shown.contains("ada"), "{shown}");
101 assert!(shown.contains("Key(\"***\")"), "{shown}");
102 assert!(shown.contains("Index(2)"), "{shown}");
103 }
104}