1use std::hash::{Hash, Hasher};
33
34use crate::{
35 subtree_path::SubtreePathInner,
36 util::{CompactBytes, CowLike},
37 SubtreePath, SubtreePathIter,
38};
39
40#[derive(Debug)]
42pub struct SubtreePathBuilder<'b, B> {
43 pub(crate) base: SubtreePath<'b, B>,
45 pub(crate) relative: SubtreePathRelative<'b>,
47}
48
49impl<'b, B: AsRef<[u8]>> Hash for SubtreePathBuilder<'b, B> {
52 fn hash<H: Hasher>(&self, state: &mut H) {
53 self.relative.hash(state);
54 self.base.hash(state);
55 }
56}
57
58impl<'bl, 'br, BL, BR> PartialEq<SubtreePathBuilder<'br, BR>> for SubtreePathBuilder<'bl, BL>
59where
60 BL: AsRef<[u8]>,
61 BR: AsRef<[u8]>,
62{
63 fn eq(&self, other: &SubtreePathBuilder<'br, BR>) -> bool {
64 self.reverse_iter().eq(other.reverse_iter())
65 }
66}
67
68impl<'bl, 'br, BL, BR> PartialEq<SubtreePathBuilder<'br, BR>> for SubtreePath<'bl, BL>
69where
70 BL: AsRef<[u8]>,
71 BR: AsRef<[u8]>,
72{
73 fn eq(&self, other: &SubtreePathBuilder<'br, BR>) -> bool {
74 self.clone().into_reverse_iter().eq(other.reverse_iter())
75 }
76}
77
78impl<'bl, 'br, BL, BR> PartialEq<SubtreePath<'br, BR>> for SubtreePathBuilder<'bl, BL>
79where
80 BL: AsRef<[u8]>,
81 BR: AsRef<[u8]>,
82{
83 fn eq(&self, other: &SubtreePath<'br, BR>) -> bool {
84 self.reverse_iter().eq(other.clone().into_reverse_iter())
85 }
86}
87
88impl<'b, B: AsRef<[u8]>> Eq for SubtreePathBuilder<'b, B> {}
89
90impl<'s, 'b, B> From<&'s SubtreePath<'b, B>> for SubtreePathBuilder<'b, B> {
91 fn from(value: &'s SubtreePath<'b, B>) -> Self {
92 SubtreePathBuilder {
93 base: value.clone(),
94 relative: SubtreePathRelative::Empty,
95 }
96 }
97}
98
99#[derive(Debug)]
101pub(crate) enum SubtreePathRelative<'r> {
102 Empty,
104 Single(CowLike<'r>),
106 Multi(CompactBytes),
108}
109
110impl SubtreePathRelative<'_> {
111 pub fn len(&self) -> usize {
112 match self {
113 SubtreePathRelative::Empty => 0,
114 SubtreePathRelative::Single(_) => 1,
115 SubtreePathRelative::Multi(cb) => cb.len(),
116 }
117 }
118
119 pub fn is_empty(&self) -> bool {
120 matches!(self, SubtreePathRelative::Empty)
121 }
122}
123
124impl Hash for SubtreePathRelative<'_> {
125 fn hash<H: Hasher>(&self, state: &mut H) {
126 match self {
127 SubtreePathRelative::Empty => {}
128 SubtreePathRelative::Single(segment) => segment.hash(state),
129 SubtreePathRelative::Multi(bytes) => {
130 bytes.reverse_iter().for_each(|segment| segment.hash(state))
131 }
132 }
133 }
134}
135
136impl SubtreePathBuilder<'static, [u8; 0]> {
137 pub fn new() -> Self {
139 SubtreePathBuilder {
140 base: [].as_ref().into(),
141 relative: SubtreePathRelative::Empty,
142 }
143 }
144}
145
146impl Default for SubtreePathBuilder<'static, [u8; 0]> {
147 fn default() -> Self {
148 Self::new()
149 }
150}
151
152impl<B> SubtreePathBuilder<'_, B> {
153 pub fn len(&self) -> usize {
155 self.base.len() + self.relative.len()
156 }
157
158 pub fn is_empty(&self) -> bool {
160 self.base.is_empty() && self.relative.is_empty()
161 }
162}
163
164impl<'b, B: AsRef<[u8]>> SubtreePathBuilder<'b, B> {
165 pub fn derive_owned(&'b self) -> SubtreePathBuilder<'b, B> {
168 match self.relative {
169 SubtreePathRelative::Empty => self.base.derive_owned(),
171 _ => SubtreePathBuilder {
173 base: SubtreePathInner::SubtreePath(self).into(),
174 relative: SubtreePathRelative::Empty,
175 },
176 }
177 }
178
179 pub fn derive_parent(&self) -> Option<(SubtreePath<B>, &[u8])> {
183 match &self.relative {
184 SubtreePathRelative::Empty => self.base.derive_parent(),
185 SubtreePathRelative::Single(relative) => Some((self.base.clone(), relative.as_ref())),
186 SubtreePathRelative::Multi(_) => {
187 let mut iter = self.reverse_iter();
188 iter.next()
189 .map(|segment| (SubtreePathInner::SubtreePathIter(iter).into(), segment))
190 }
191 }
192 }
193
194 pub fn derive_owned_with_child<'s, S>(&'b self, segment: S) -> SubtreePathBuilder<'b, B>
196 where
197 S: Into<CowLike<'s>>,
198 's: 'b,
199 {
200 SubtreePathBuilder {
201 base: SubtreePathInner::SubtreePath(self).into(),
202 relative: SubtreePathRelative::Single(segment.into()),
203 }
204 }
205
206 pub fn push_segment(&mut self, segment: &[u8]) {
208 match &mut self.relative {
209 SubtreePathRelative::Empty => {
210 let mut bytes = CompactBytes::new();
211 bytes.add_segment(segment);
212 self.relative = SubtreePathRelative::Multi(bytes);
213 }
214 SubtreePathRelative::Single(old_segment) => {
215 let mut bytes = CompactBytes::new();
216 bytes.add_segment(old_segment);
217 bytes.add_segment(segment);
218 self.relative = SubtreePathRelative::Multi(bytes);
219 }
220 SubtreePathRelative::Multi(bytes) => bytes.add_segment(segment),
221 }
222 }
223
224 pub fn reverse_iter(&'b self) -> SubtreePathIter<'b, B> {
226 match &self.relative {
227 SubtreePathRelative::Empty => self.base.clone().into_reverse_iter(),
228 SubtreePathRelative::Single(item) => {
229 SubtreePathIter::new_with_next(item.as_ref(), &self.base)
230 }
231 SubtreePathRelative::Multi(bytes) => {
232 SubtreePathIter::new_with_next(bytes.reverse_iter(), &self.base)
233 }
234 }
235 }
236
237 pub fn to_vec(&self) -> Vec<Vec<u8>> {
240 let mut result = Vec::new();
241
242 match &self.relative {
245 SubtreePathRelative::Empty => {}
246 SubtreePathRelative::Single(s) => result.push(s.to_vec()),
247 SubtreePathRelative::Multi(bytes) => {
248 bytes.reverse_iter().for_each(|s| result.push(s.to_vec()))
249 }
250 }
251
252 match &self.base.ref_variant {
253 SubtreePathInner::Slice(slice) => slice
254 .iter()
255 .rev()
256 .for_each(|x| result.push(x.as_ref().to_vec())),
257 SubtreePathInner::SubtreePath(path) => {
258 path.reverse_iter().for_each(|x| result.push(x.to_vec()))
259 }
260 SubtreePathInner::SubtreePathIter(iter) => {
261 iter.clone().for_each(|x| result.push(x.as_ref().to_vec()))
262 }
263 };
264
265 result.reverse();
266 result
267 }
268
269 pub fn is_root(&self) -> bool {
272 match self {
273 Self {
274 base,
275 relative: SubtreePathRelative::Empty,
276 } => base.is_root(),
277 _ => false,
278 }
279 }
280}
281
282#[cfg(test)]
283mod tests {
284 use super::*;
285
286 #[test]
287 fn to_vec() {
288 let base: SubtreePath<_> = (&[b"one" as &[u8], b"two", b"three"]).into();
289 let mut builder = base.derive_owned_with_child(b"four");
290 builder.push_segment(b"five");
291 builder.push_segment(b"six");
292 builder.push_segment(b"seven");
293
294 let as_vec = builder.to_vec();
295 let reference_vec = vec![
296 b"one".to_vec(),
297 b"two".to_vec(),
298 b"three".to_vec(),
299 b"four".to_vec(),
300 b"five".to_vec(),
301 b"six".to_vec(),
302 b"seven".to_vec(),
303 ];
304
305 assert_eq!(as_vec, reference_vec);
306 assert_eq!(builder.len(), reference_vec.len());
307 }
308}