1use std::fmt;
11
12#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
14pub struct LensPathElement {
15 id: u64,
16}
17
18impl LensPathElement {
19 pub fn new(id: u64) -> LensPathElement {
20 LensPathElement { id }
21 }
22}
23
24#[derive(PartialEq, Eq, PartialOrd, Ord, Clone)]
26pub struct LensPath {
27 pub elements: Vec<LensPathElement>,
29}
30
31impl LensPath {
32 pub fn empty() -> LensPath {
34 LensPath { elements: vec![] }
35 }
36
37 pub fn new(id: u64) -> LensPath {
39 LensPath {
40 elements: vec![LensPathElement::new(id)],
41 }
42 }
43
44 pub fn from_index(index: usize) -> LensPath {
46 LensPath::new(index as u64)
47 }
48
49 pub fn from_pair(id0: u64, id1: u64) -> LensPath {
51 LensPath {
52 elements: vec![LensPathElement::new(id0), LensPathElement::new(id1)],
53 }
54 }
55
56 pub fn from_vec(ids: Vec<u64>) -> LensPath {
58 LensPath {
59 elements: ids.into_iter().map(LensPathElement::new).collect(),
60 }
61 }
62
63 pub fn concat(lhs: LensPath, rhs: LensPath) -> LensPath {
65 let mut elements = lhs.elements;
66 elements.extend(rhs.elements);
67 LensPath { elements }
68 }
69}
70
71impl fmt::Debug for LensPath {
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 write!(
74 f,
75 "[{}]",
76 self.elements
77 .iter()
78 .map(|elem| elem.id.to_string())
79 .collect::<Vec<_>>()
80 .join(", ")
81 )
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use super::{LensPath, LensPathElement};
88
89 #[test]
90 fn lens_path_constructors_should_work() {
91 assert_eq!(LensPath::empty().elements, Vec::<LensPathElement>::new());
92 assert_eq!(LensPath::new(4).elements, vec![LensPathElement::new(4)]);
93 assert_eq!(LensPath::from_index(2), LensPath::new(2));
94 assert_eq!(
95 LensPath::from_pair(1, 3).elements,
96 vec![LensPathElement::new(1), LensPathElement::new(3)]
97 );
98 assert_eq!(
99 LensPath::from_vec(vec![1, 2, 3]).elements,
100 vec![
101 LensPathElement::new(1),
102 LensPathElement::new(2),
103 LensPathElement::new(3),
104 ]
105 );
106 }
107
108 #[test]
109 fn lens_path_concat_should_work() {
110 let p0 = LensPath::from_vec(vec![1, 2, 3]);
111 let p1 = LensPath::from_vec(vec![4, 5]);
112 let p2 = LensPath::concat(p0, p1);
113 assert_eq!(p2, LensPath::from_vec(vec![1, 2, 3, 4, 5]));
114 }
115
116 #[test]
117 fn lens_path_debug_should_work() {
118 let path = LensPath::from_vec(vec![1, 2, 3, 4, 5]);
119 assert_eq!(format!("{path:?}"), "[1, 2, 3, 4, 5]");
120 }
121}