1#![deny(missing_docs)]
32
33mod subtree_path;
34mod subtree_path_builder;
35mod subtree_path_iter;
36mod util;
37
38pub use subtree_path::SubtreePath;
39pub use subtree_path_builder::SubtreePathBuilder;
40pub use subtree_path_iter::SubtreePathIter;
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45 use crate::util::calculate_hash;
46
47 fn assert_path_properties<B>(path: SubtreePath<'_, B>, reference: Vec<Vec<u8>>)
48 where
49 B: AsRef<[u8]> + std::fmt::Debug,
50 {
51 assert_eq!(path.to_vec(), reference);
53
54 assert!(path.clone().into_reverse_iter().eq(reference.iter().rev()));
56
57 assert_eq!(path, SubtreePath::from(reference.as_slice()));
59
60 let subtree_path_ref = SubtreePath::from(reference.as_slice());
62 let subtree_path_builder = subtree_path_ref.derive_owned();
63 assert_eq!(calculate_hash(&path), calculate_hash(&subtree_path_ref));
64 assert_eq!(calculate_hash(&path), calculate_hash(&subtree_path_builder));
65 assert_eq!(path.len(), reference.len());
66 }
67
68 #[test]
69 fn test_root_and_roots_child_derivation_slice() {
70 let path_array = [b"one", b"two"];
72 let path = SubtreePath::from(path_array.as_ref());
73
74 let (root, child) = path.derive_parent().unwrap().0.derive_parent().unwrap();
75
76 assert_eq!(child, b"one");
77 assert_eq!(root.to_vec(), Vec::<&[u8]>::new());
78
79 assert_eq!(root.derive_parent(), None);
80 }
81
82 #[test]
83 fn test_root_and_roots_child_derivation_builder() {
84 let mut builder = SubtreePathBuilder::new();
85 builder.push_segment(b"one");
86 builder.push_segment(b"two");
87 let path: SubtreePath<[u8; 0]> = (&builder).into();
88
89 let (root, child) = path.derive_parent().unwrap().0.derive_parent().unwrap();
90
91 assert_eq!(child, b"one");
92 assert_eq!(root.to_vec(), Vec::<&[u8]>::new());
93
94 assert_eq!(root.derive_parent(), None);
95 }
96
97 #[test]
98 fn test_hashes_are_equal() {
99 let path_array = [
100 b"one".to_vec(),
101 b"two".to_vec(),
102 b"three".to_vec(),
103 b"four".to_vec(),
104 b"five".to_vec(),
105 ];
106 let path_array_refs = [
107 b"one".as_ref(),
108 b"two".as_ref(),
109 b"three".as_ref(),
110 b"four".as_ref(),
111 b"five".as_ref(),
112 ];
113 let path_base_slice_slices = SubtreePath::from(path_array_refs.as_ref());
114
115 let path_array_refs_six = [
116 b"one".as_ref(),
117 b"two".as_ref(),
118 b"three".as_ref(),
119 b"four".as_ref(),
120 b"five".as_ref(),
121 b"six".as_ref(),
122 ];
123 let path_base_slice_too_much = SubtreePath::from(path_array_refs_six.as_ref());
124 let path_base_unfinished = SubtreePath::from([b"one", b"two"].as_ref());
125 let path_empty = SubtreePathBuilder::new();
126
127 let path_derived_11 = path_empty.derive_owned_with_child(b"one".as_ref());
128 let path_derived_12 = path_derived_11.derive_owned_with_child(b"two".as_ref());
129 let path_derived_13 = path_derived_12.derive_owned_with_child(b"three".as_ref());
130 let path_derived_14 = path_derived_13.derive_owned_with_child(b"four".to_vec());
131 let path_derived_1 = path_derived_14.derive_owned_with_child(b"five".as_ref());
132
133 let (path_derived_2, _) = path_base_slice_too_much.derive_parent().unwrap();
134
135 let path_derived_31 = path_base_unfinished.derive_owned_with_child(b"three".to_vec());
136 let path_derived_32 = path_derived_31.derive_owned_with_child(b"four".as_ref());
137 let path_derived_3 = path_derived_32.derive_owned_with_child(b"five".as_ref());
138
139 assert_path_properties(path_base_slice_slices, path_array.to_vec());
140 assert_path_properties(SubtreePath::from(&path_derived_1), path_array.to_vec());
141 assert_path_properties(path_derived_2, path_array.to_vec());
142 assert_path_properties(SubtreePath::from(&path_derived_3), path_array.to_vec());
143 }
144
145 #[test]
146 fn test_is_root() {
147 let path_empty = SubtreePathBuilder::new();
148 assert!(path_empty.is_root());
149
150 let path_derived = path_empty.derive_owned_with_child(b"two".as_ref());
151 assert!(!path_derived.is_root());
152 assert!(path_derived.derive_parent().unwrap().0.is_root());
153
154 let path_not_empty = SubtreePath::from([b"one"].as_ref());
155 assert!(!path_not_empty.is_root());
156 assert!(path_not_empty.derive_parent().unwrap().0.is_root());
157 }
158
159 #[test]
160 fn test_complex_derivation() {
161 let base = SubtreePath::from([b"one", b"two"].as_ref());
163 let with_child_1 = base.derive_owned_with_child(b"three".to_vec());
164 let mut with_child_inplace = with_child_1.derive_owned_with_child(b"four");
165 with_child_inplace.push_segment(b"five");
166 with_child_inplace.push_segment(b"six");
167 with_child_inplace.push_segment(b"seven");
168 with_child_inplace.push_segment(b"eight");
169
170 assert_eq!(
173 with_child_inplace.reverse_iter().fold(0, |acc, _| acc + 1),
174 8
175 );
176 assert_path_properties(
177 (&with_child_inplace).into(),
178 vec![
179 b"one".to_vec(),
180 b"two".to_vec(),
181 b"three".to_vec(),
182 b"four".to_vec(),
183 b"five".to_vec(),
184 b"six".to_vec(),
185 b"seven".to_vec(),
186 b"eight".to_vec(),
187 ],
188 );
189
190 let points_five = with_child_inplace
193 .derive_parent()
194 .unwrap()
195 .0
196 .derive_parent()
197 .unwrap()
198 .0
199 .derive_parent()
200 .unwrap()
201 .0;
202
203 assert_path_properties(
204 points_five.clone(),
205 vec![
206 b"one".to_vec(),
207 b"two".to_vec(),
208 b"three".to_vec(),
209 b"four".to_vec(),
210 b"five".to_vec(),
211 ],
212 );
213
214 let after_five_1 = points_five.derive_owned_with_child(b"four");
216 let after_five_2 = after_five_1.derive_owned_with_child(b"twenty");
217 let mut after_five_3 = after_five_2.derive_owned();
218 after_five_3.push_segment(b"thirteen");
219 after_five_3.push_segment(b"thirtyseven");
220
221 assert_path_properties(
225 (&after_five_3).into(),
226 vec![
227 b"one".to_vec(),
228 b"two".to_vec(),
229 b"three".to_vec(),
230 b"four".to_vec(),
231 b"five".to_vec(),
232 b"four".to_vec(),
233 b"twenty".to_vec(),
234 b"thirteen".to_vec(),
235 b"thirtyseven".to_vec(),
236 ],
237 );
238 }
239}