willow_data_model/paths/
mod.rs

1//! Functionality around Willow [Paths](https://willowprotocol.org/specs/data-model/index.html#Path).
2//!
3//! The central type of this module is the [`Path`] struct, which represents a single willow Path. [`Paths`](Path) are *immutable*, which means any operation that would traditionally mutate paths (for example, appending a new component) returns a new, independent value instead.
4//!
5//! The [`Path`] struct is generic over three const generic parameters, corresponding to the Willow parameters which limit the size of paths:
6//!
7//! - the `MCL` parameter gives the ([**m**ax\_**c**omponent\_**l**ength](https://willowprotocol.org/specs/data-model/index.html#max_component_length)),
8//! - the `MCC` parameter gives the ([**m**ax\_**c**omponent\_**c**ount](https://willowprotocol.org/specs/data-model/index.html#max_component_count)), and
9//! - the `MPL` parameter gives the ([**m**ax\_**p**ath\_**l**ength](https://willowprotocol.org/specs/data-model/index.html#max_path_length)).
10//!
11//! All (safely created) [`Paths`](Path)respect those parameters. The functions in this module return [`PathErrors`](PathError) or [`PathFromComponentsErrors`](PathFromComponentsError) when those invariants would be violated.
12//!
13//! The type-level docs of [`Path`] list all the ways in which you can build up paths dynamically.
14//!
15//! The [`Path`] struct provides methods for checking various properties of paths: from simple properties ("[how many components does this have](Path::component_count)") to various comparisons ("[is this path a prefix of some other](Path::is_prefix_of)"), the methods should have you covered.
16//!
17//! Because [path prefixes](https://willowprotocol.org/specs/data-model/index.html#path_prefix) play such a [central role for deletion](https://willowprotocol.org/specs/data-model/index.html#prefix_pruning) in Willow, the functionality around prefixes is optimised. [Creating a prefix](Path::create_prefix) or even iterating over [all prefixes](Path::all_prefixes) performs no memory allocations.
18//!
19//! The [`Component`] type represents individual path [Components](https://willowprotocol.org/specs/data-model/index.html#Component). This type is a thin wrapper around `[u8]` (enforcing a maximal length of `MCL` bytes); like `[u8]` it must always be used as part of a pointer type — for example, `&Component<MCL>`. Alternatively, the [`OwnedComponent`] type can be used by itself — keeping an [`OwnedComponent`] alive will also keep around the heap allocation for the full [`Path`] from which it was constructed, though. Generally speaking, the more lightweight [`Component`] should be preferred over [`OwnedComponent`] where possible.
20
21#[cfg(feature = "dev")]
22use arbitrary::{Arbitrary, Error as ArbitraryError, Unstructured, size_hint::and_all};
23use order_theory::{
24    GreatestElement, LeastElement, LowerSemilattice, PredecessorExceptForLeast,
25    SuccessorExceptForGreatest, TryPredecessor, TrySuccessor, UpperSemilattice,
26};
27
28// The `Path` struct is tested in `fuzz/path.rs`, `fuzz/path2.rs`, `fuzz/path3.rs`, `fuzz/path3.rs` by comparing against a non-optimised reference implementation.
29// Further, the `successor` and `greater_but_not_prefixed` methods of that reference implementation are tested in `fuzz/path_successor.rs` and friends, and `fuzz/path_successor_of_prefix.rs` and friends.
30
31use core::cmp::Ordering;
32use core::fmt::Debug;
33use core::hash::Hash;
34use core::mem::size_of;
35use core::{convert::AsRef, fmt};
36
37use bytes::{BufMut, Bytes, BytesMut};
38
39mod builder;
40pub use builder::PathBuilder;
41
42mod representation;
43use representation::Representation;
44
45mod component;
46pub use component::*;
47
48#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
49/// An error arising from trying to construct an invalid [`Path`] from valid [`Component`]s.
50///
51/// #### Examples
52///
53/// ```
54/// use willow_data_model::prelude::*;
55/// assert_eq!(
56///     Path::<4, 4, 2>::from_component(Component::new(b"oops").unwrap()),
57///     Err(PathFromComponentsError::PathTooLong),
58/// );
59/// assert_eq!(
60///     Path::<4, 1, 9>::from_components(&[
61///         Component::new(b"").unwrap(),
62///         Component::new(b"").unwrap()
63///     ]),
64///     Err(PathFromComponentsError::TooManyComponents),
65/// );
66/// ```
67pub enum PathFromComponentsError {
68    /// The [`Path`]'s total length in bytes would have been greater than the [max\_path\_length](https://willowprotocol.org/specs/data-model/index.html#max_path_length).
69    PathTooLong,
70    /// The [`Path`] would have had more [`Component`] than the [max\_component\_count](https://willowprotocol.org/specs/data-model/index.html#max_component_count).
71    TooManyComponents,
72}
73
74impl core::fmt::Display for PathFromComponentsError {
75    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
76        match self {
77            PathFromComponentsError::PathTooLong => {
78                write!(
79                    f,
80                    "Total length of a path in bytes exceeded the maximum path length"
81                )
82            }
83            PathFromComponentsError::TooManyComponents => {
84                write!(
85                    f,
86                    "Number of components of a path exceeded the maximum component count"
87                )
88            }
89        }
90    }
91}
92
93impl core::error::Error for PathFromComponentsError {}
94
95/// An error arising from trying to construct an invalid [`Path`].
96///
97/// #### Examples
98///
99/// ```
100/// use willow_data_model::prelude::*;
101/// assert_eq!(Path::<4, 4, 2>::from_slice(b"oops"), Err(PathError::PathTooLong));
102/// assert_eq!(Path::<2, 2, 9>::from_slices(&[b"", b"", b""]), Err(PathError::TooManyComponents));
103/// assert_eq!(Path::<4, 4, 9>::from_slice(b"oopsie"), Err(PathError::ComponentTooLong));
104/// ```
105#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
106pub enum PathError {
107    /// The [`Path`]'s total length in bytes would have been greater than the [max\_path\_length](https://willowprotocol.org/specs/data-model/index.html#max_path_length).
108    PathTooLong,
109    /// The [`Path`] would have had more [`Component`] than the [max\_component\_count](https://willowprotocol.org/specs/data-model/index.html#max_component_count).
110    TooManyComponents,
111    /// The [`Path`] would have contained a [`Component`] of length greater than the [max\_component\_length](https://willowprotocol.org/specs/data-model/index.html#max_component_length)
112    ComponentTooLong,
113}
114
115impl core::fmt::Display for PathError {
116    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
117        match self {
118            PathError::PathTooLong => {
119                write!(
120                    f,
121                    "Total length of a path in bytes exceeded the maximum path length"
122                )
123            }
124            PathError::TooManyComponents => {
125                write!(
126                    f,
127                    "Number of components of a path exceeded the maximum component count"
128                )
129            }
130            PathError::ComponentTooLong => {
131                write!(
132                    f,
133                    "Length of a path component exceeded the maximum component length"
134                )
135            }
136        }
137    }
138}
139
140impl core::error::Error for PathError {}
141
142impl From<PathFromComponentsError> for PathError {
143    fn from(value: PathFromComponentsError) -> Self {
144        match value {
145            PathFromComponentsError::PathTooLong => Self::PathTooLong,
146            PathFromComponentsError::TooManyComponents => Self::TooManyComponents,
147        }
148    }
149}
150
151impl From<InvalidComponentError> for PathError {
152    fn from(_value: InvalidComponentError) -> Self {
153        Self::ComponentTooLong
154    }
155}
156
157/// An immutable Willow [Path](https://willowprotocol.org/specs/data-model/index.html#Path). Thread-safe, cheap to clone, cheap to take prefixes of, expensive to append to (linear time complexity).
158///
159/// A Willow Path is any sequence of bytestrings — called [Components](https://willowprotocol.org/specs/data-model/index.html#Component) — fulfilling certain constraints:
160///
161/// - each [`Component`] has a length of at most `MCL` ([**m**ax\_**c**omponent\_**l**ength](https://willowprotocol.org/specs/data-model/index.html#max_component_length)),
162/// - each [`Path`] has at most `MCC` ([**m**ax\_**c**omponent\_**c**ount](https://willowprotocol.org/specs/data-model/index.html#max_component_count)) components, and
163/// - the total size in bytes of all [`Component`]s is at most `MPL` ([**m**ax\_**p**ath\_**l**ength](https://willowprotocol.org/specs/data-model/index.html#max_path_length)).
164///
165/// This type statically enforces these invariants for all (safely) created instances.
166///
167/// Because appending [`Component`]s takes time linear in the length of the full [`Path`], you should not build up [`Path`]s this way. Instead, use [`Path::from_components`], [`Path::from_slices`], [`Path::from_components_iter`], [`Path::from_slices_iter`], or a [`PathBuilder`].
168///
169/// ```
170/// use willow_data_model::prelude::*;
171/// let p: Path<4, 4, 4> = Path::from_slices(&[b"hi", b"ho"])?;
172///
173/// assert_eq!(p.component_count(), 2);
174/// assert_eq!(p.component(1), Some(Component::new(b"ho")?));
175/// assert_eq!(p.total_length(), 4);
176/// assert!(p.is_prefixed_by(&Path::from_slice(b"hi")?));
177/// assert_eq!(
178///     p.longest_common_prefix(&Path::from_slices(&[b"hi", b"he"])?),
179///     Path::from_slice(b"hi")?
180/// );
181/// # Ok::<(), PathError>(())
182/// ```
183#[derive(Clone)]
184pub struct Path<const MCL: usize, const MCC: usize, const MPL: usize> {
185    /// The data of the underlying path.
186    data: Bytes,
187    /// Number of components of the `data` to consider for this particular path (starting from the first component). Must be less than or equal to the total number of components.
188    /// This field enables cheap prefix creation by cloning the heap data (which is reference counted) and adjusting the `component_count`.
189    component_count: usize,
190}
191
192/// The default [`Path`] is the empty [`Path`].
193impl<const MCL: usize, const MCC: usize, const MPL: usize> Default for Path<MCL, MCC, MPL> {
194    /// Returns an empty [`Path`].
195    ///
196    /// #### Examples
197    ///
198    /// ```
199    /// use willow_data_model::prelude::*;
200    /// assert_eq!(Path::<4, 4, 4>::default().component_count(), 0);
201    /// assert_eq!(Path::<4, 4, 4>::default(), Path::<4, 4, 4>::new());
202    /// ```
203    fn default() -> Self {
204        Self::new()
205    }
206}
207
208impl<const MCL: usize, const MCC: usize, const MPL: usize> Path<MCL, MCC, MPL> {
209    /// Returns an empty [`Path`], i.e., a [`Path`] of zero [`Component`]s.
210    ///
211    /// #### Complexity
212    ///
213    /// Runs in `O(1)`.
214    ///
215    /// #### Examples
216    ///
217    /// ```
218    /// use willow_data_model::prelude::*;
219    /// assert_eq!(Path::<4, 4, 4>::new().component_count(), 0);
220    /// assert_eq!(Path::<4, 4, 4>::new(), Path::<4, 4, 4>::default());
221    /// ```
222    pub fn new() -> Self {
223        PathBuilder::new(0, 0)
224            .expect("The empty path is legal for every choice of of MCL, MCC, and MPL.")
225            .build()
226    }
227
228    /// Creates a singleton [`Path`], consisting of exactly one [`Component`].
229    ///
230    /// Copies the bytes of the [`Component`] into an owned allocation on the heap.
231    ///
232    /// #### Complexity
233    ///
234    /// Runs in `O(n)`, where `n` is the length of the [`Component`]. Performs a single allocation of `O(n)` bytes.
235    ///
236    /// #### Examples
237    ///
238    /// ```
239    /// use willow_data_model::prelude::*;
240    /// let p = Path::<4, 4, 4>::from_component(Component::new(b"hi!")?)?;
241    /// assert_eq!(p.component_count(), 1);
242    ///
243    /// assert_eq!(
244    ///     Path::<4, 4, 2>::from_component(Component::new(b"hi!")?),
245    ///     Err(PathFromComponentsError::PathTooLong),
246    /// );
247    /// # Ok::<(), PathError>(())
248    /// ```
249    pub fn from_component(comp: &Component<MCL>) -> Result<Self, PathFromComponentsError> {
250        let mut builder = PathBuilder::new(comp.as_ref().len(), 1)?;
251        builder.append_component(comp);
252        Ok(builder.build())
253    }
254
255    /// Creates a singleton [`Path`], consisting of exactly one [`Component`], from a raw slice of bytes.
256    ///
257    /// Copies the bytes into an owned allocation on the heap.
258    ///
259    /// #### Complexity
260    ///
261    /// Runs in `O(n)`, where `n` is the length of the [`Component`]. Performs a single allocation of `O(n)` bytes.
262    ///
263    /// #### Examples
264    ///
265    /// ```
266    /// use willow_data_model::prelude::*;
267    /// let p = Path::<4, 4, 4>::from_slice(b"hi!")?;
268    /// assert_eq!(p.component_count(), 1);
269    ///
270    /// assert_eq!(
271    ///     Path::<4, 4, 4>::from_slice(b"too_long_for_single_component"),
272    ///     Err(PathError::ComponentTooLong),
273    /// );
274    /// assert_eq!(
275    ///     Path::<4, 3, 1>::from_slice(b"nope"),
276    ///     Err(PathError::PathTooLong),
277    /// );
278    /// # Ok::<(), PathError>(())
279    /// ```
280    pub fn from_slice(comp: &[u8]) -> Result<Self, PathError> {
281        Ok(Self::from_component(Component::new(comp)?)?)
282    }
283
284    /// Creates a [`Path`] from a slice of [`Component`]s.
285    ///
286    /// Copies the bytes of the [`Component`]s into an owned allocation on the heap.
287    ///
288    /// #### Complexity
289    ///
290    /// Runs in `O(n + m)`, where `n` is the total length of the created [`Path`] in bytes, and `m` is the number of its [`Component`]s. Performs a single allocation of `O(n + m)` bytes.
291    ///
292    /// #### Examples
293    ///
294    /// ```
295    /// use willow_data_model::prelude::*;
296    /// let components: Vec<&Component<4>> = vec![
297    ///     &Component::new(b"hi")?,
298    ///     &Component::new(b"!")?,
299    /// ];
300    ///
301    /// assert!(Path::<4, 4, 4>::from_components(&components[..]).is_ok());
302    /// # Ok::<(), PathError>(())
303    /// ```
304    pub fn from_components(
305        components: &[&Component<MCL>],
306    ) -> Result<Self, PathFromComponentsError> {
307        let mut total_length = 0;
308        for comp in components {
309            total_length += comp.as_ref().len();
310        }
311
312        Self::from_components_iter(total_length, &mut components.iter().cloned())
313    }
314
315    /// Create a new [`Path`] from a slice of byte slices.
316    ///
317    /// #### Complexity
318    ///
319    /// Runs in `O(n + m)`, where `n` is the total length of the created [`Path`] in bytes, and `m` is the number of its [`Component`]s. Performs a single allocation of `O(n + m)` bytes.
320    ///
321    /// # Example
322    ///
323    /// ```
324    /// use willow_data_model::prelude::*;
325    /// // Ok
326    /// let path = Path::<12, 3, 30>::from_slices(&[b"alfie", b"notes"]).unwrap();
327    ///
328    /// // Err
329    /// let result1 = Path::<12, 3, 30>::from_slices(&[b"themaxpath", b"lengthis30", b"thisislonger"]);
330    /// assert_eq!(result1, Err(PathError::PathTooLong));
331    ///
332    /// // Err
333    /// let result2 = Path::<12, 3, 30>::from_slices(&[b"too", b"many", b"components", b"error"]);
334    /// assert_eq!(result2, Err(PathError::TooManyComponents));
335    ///
336    /// // Err
337    /// let result3 = Path::<12, 3, 30>::from_slices(&[b"overencumbered"]);
338    /// assert_eq!(result3, Err(PathError::ComponentTooLong));
339    /// ```
340    pub fn from_slices(slices: &[&[u8]]) -> Result<Self, PathError> {
341        let total_length = slices.iter().map(|it| it.as_ref().len()).sum();
342        let mut builder = PathBuilder::new(total_length, slices.len())?;
343
344        for component_slice in slices {
345            builder.append_slice(component_slice.as_ref())?;
346        }
347
348        Ok(builder.build())
349    }
350
351    /// Creates a [`Path`] of known total length from an [`ExactSizeIterator`] of [`Component`]s.
352    ///
353    /// Copies the bytes of the [`Component`]s into an owned allocation on the heap.
354    ///
355    /// Panics if the claimed `total_length` does not match the sum of the lengths of all the [`Component`]s.
356    ///
357    /// #### Complexity
358    ///
359    /// Runs in `O(n + m)`, where `n` is the total length of the created [`Path`] in bytes, and `m` is the number of its [`Component`]s. Performs a single allocation of `O(n + m)` bytes.
360    ///
361    /// #### Examples
362    ///
363    /// ```
364    /// use willow_data_model::prelude::*;
365    /// let components: Vec<&Component<4>> = vec![
366    ///     &Component::new(b"hi")?,
367    ///     &Component::new(b"!")?,
368    /// ];
369    ///
370    /// assert!(Path::<4, 4, 4>::from_components_iter(3, &mut components.into_iter()).is_ok());
371    /// # Ok::<(), PathError>(())
372    /// ```
373    pub fn from_components_iter<'c, I>(
374        total_length: usize,
375        iter: &mut I,
376    ) -> Result<Self, PathFromComponentsError>
377    where
378        I: ExactSizeIterator<Item = &'c Component<MCL>>,
379    {
380        let mut builder = PathBuilder::new(total_length, iter.len())?;
381
382        for component in iter {
383            builder.append_component(component);
384        }
385
386        Ok(builder.build())
387    }
388
389    /// Creates a [`Path`] of known total length from an [`ExactSizeIterator`] of byte slices.
390    ///
391    /// Copies the bytes of the [`Component`]s into an owned allocation on the heap.
392    ///
393    /// Panics if the claimed `total_length` does not match the sum of the lengths of all the [`Component`]s.
394    ///
395    /// #### Complexity
396    ///
397    /// Runs in `O(n + m)`, where `n` is the total length of the created [`Path`] in bytes, and `m` is the number of its [`Component`]s. Performs a single allocation of `O(n + m)` bytes.
398    ///
399    /// #### Examples
400    ///
401    /// ```
402    /// use willow_data_model::prelude::*;
403    /// let components: Vec<&[u8]> = vec![b"hi", b"!"];
404    /// assert!(Path::<4, 4, 4>::from_slices_iter(3, &mut components.into_iter()).is_ok());
405    /// # Ok::<(), PathError>(())
406    /// ```
407    pub fn from_slices_iter<'a, I>(total_length: usize, iter: &mut I) -> Result<Self, PathError>
408    where
409        I: ExactSizeIterator<Item = &'a [u8]>,
410    {
411        let mut builder = PathBuilder::new(total_length, iter.len())?;
412
413        for slice in iter {
414            builder.append_slice(slice.as_ref())?;
415        }
416
417        Ok(builder.build())
418    }
419
420    /// Creates a new [`Path`] by appending a [`Component`] to `&self`.
421    ///
422    /// Creates a fully separate copy of the new data on the heap; which includes cloning all data in `&self`. To efficiently construct [`Path`]s, use [`Path::from_components`], [`Path::from_slices`], [`Path::from_components_iter`], [`Path::from_slices_iter`], or a [`PathBuilder`].
423    ///
424    /// #### Complexity
425    ///
426    /// Runs in `O(n + m)`, where `n` is the total length of the resulting [`Path`] in bytes, and `m` is the number of its [`Component`]s. Performs a single allocation of `O(n + m)` bytes.
427    ///
428    /// #### Examples
429    ///
430    /// ```
431    /// use willow_data_model::prelude::*;
432    /// let p0: Path<4, 4, 4> = Path::new();
433    /// let p1 = p0.append_component(Component::new(b"hi")?)?;
434    /// let p2 = p1.append_component(Component::new(b"!")?)?;
435    /// assert_eq!(
436    ///     p2.append_component(Component::new(b"no!")?),
437    ///     Err(PathFromComponentsError::PathTooLong),
438    /// );
439    /// # Ok::<(), PathError>(())
440    /// ```
441    pub fn append_component(&self, comp: &Component<MCL>) -> Result<Self, PathFromComponentsError> {
442        let mut builder = PathBuilder::new(
443            self.total_length() + comp.as_ref().len(),
444            self.component_count() + 1,
445        )?;
446
447        for component in self.components() {
448            builder.append_component(component);
449        }
450        builder.append_component(comp);
451
452        Ok(builder.build())
453    }
454
455    /// Creates a new [`Path`] by appending a [`Component`] to `&self`.
456    ///
457    /// Creates a fully separate copy of the new data on the heap; which includes cloning all data in `&self`. To efficiently construct [`Path`]s, use [`Path::from_components`], [`Path::from_slices`], [`Path::from_components_iter`], [`Path::from_slices_iter`], or a [`PathBuilder`].
458    ///
459    /// #### Complexity
460    ///
461    /// Runs in `O(n + m)`, where `n` is the total length of the resulting [`Path`] in bytes, and `m` is the number of its [`Component`]s. Performs a single allocation of `O(n + m)` bytes.
462    ///
463    /// #### Examples
464    ///
465    /// ```
466    /// use willow_data_model::prelude::*;
467    /// let p0: Path<4, 4, 4> = Path::new();
468    /// let p1 = p0.append_slice(b"hi")?;
469    /// let p2 = p1.append_slice(b"!")?;
470    /// assert_eq!(
471    ///     p2.append_slice(b"no!"),
472    ///     Err(PathError::PathTooLong),
473    /// );
474    /// # Ok::<(), PathError>(())
475    /// ```
476    pub fn append_slice(&self, comp: &[u8]) -> Result<Self, PathError> {
477        Ok(self.append_component(Component::new(comp)?)?)
478    }
479
480    /// Creates a new [`Path`] by appending a slice of [`Component`]s to `&self`.
481    ///
482    /// Creates a fully separate copy of the new data on the heap; which includes cloning all data in `&self`. To efficiently construct [`Path`]s, use [`Path::from_components`], [`Path::from_slices`], [`Path::from_components_iter`], [`Path::from_slices_iter`], or a [`PathBuilder`].
483    ///
484    /// #### Complexity
485    ///
486    /// Runs in `O(n + m)`, where `n` is the total length of the resulting [`Path`] in bytes, and `m` is the number of its [`Component`]s. Performs a single allocation of `O(n + m)` bytes.
487    ///
488    /// #### Examples
489    ///
490    /// ```
491    /// use willow_data_model::prelude::*;
492    /// let p0: Path<4, 4, 4> = Path::new();
493    /// let p1 = p0.append_components(&[Component::new(b"hi")?, Component::new(b"!")?])?;
494    /// assert_eq!(
495    ///     p1.append_components(&[Component::new(b"no!")?]),
496    ///     Err(PathFromComponentsError::PathTooLong),
497    /// );
498    /// # Ok::<(), PathError>(())
499    /// ```
500    pub fn append_components(
501        &self,
502        components: &[&Component<MCL>],
503    ) -> Result<Self, PathFromComponentsError> {
504        let mut total_length = self.total_length();
505        for comp in components {
506            total_length += comp.as_ref().len();
507        }
508
509        let mut builder = PathBuilder::new_from_prefix(
510            total_length,
511            self.component_count() + components.len(),
512            self,
513            self.component_count(),
514        )?;
515
516        for additional_component in components {
517            builder.append_component(*additional_component);
518        }
519
520        Ok(builder.build())
521    }
522
523    /// Creates a new [`Path`] by appending a slice of [`Component`]s to `&self`.
524    ///
525    /// Creates a fully separate copy of the new data on the heap; which includes cloning all data in `&self`. To efficiently construct [`Path`]s, use [`Path::from_components`], [`Path::from_slices`], [`Path::from_components_iter`], [`Path::from_slices_iter`], or a [`PathBuilder`].
526    ///
527    /// #### Complexity
528    ///
529    /// Runs in `O(n + m)`, where `n` is the total length of the resulting [`Path`] in bytes, and `m` is the number of its [`Component`]s. Performs a single allocation of `O(n + m)` bytes.
530    ///
531    /// #### Examples
532    ///
533    /// ```
534    /// use willow_data_model::prelude::*;
535    /// let p0: Path<4, 4, 4> = Path::new();
536    /// let p1 = p0.append_slices(&[b"hi", b"ho"])?;
537    /// assert_eq!(
538    ///     p1.append_slices(&[b"no!"]),
539    ///     Err(PathError::PathTooLong),
540    /// );
541    /// # Ok::<(), PathError>(())
542    /// ```
543    pub fn append_slices(&self, components: &[&[u8]]) -> Result<Self, PathError> {
544        let mut total_length = self.total_length();
545        for comp in components {
546            total_length += comp.as_ref().len();
547        }
548
549        let mut builder = PathBuilder::new_from_prefix(
550            total_length,
551            self.component_count() + components.len(),
552            self,
553            self.component_count(),
554        )?;
555
556        for additional_component in components {
557            builder.append_slice(additional_component.as_ref())?;
558        }
559
560        Ok(builder.build())
561    }
562
563    /// Creates a new [`Path`] by appending another [`Path`] to `&self`.
564    ///
565    /// Creates a fully separate copy of the new data on the heap; which includes cloning all data in `&self` and in `&other`.
566    ///
567    /// #### Complexity
568    ///
569    /// Runs in `O(n + m)`, where `n` is the total length of the resulting [`Path`] in bytes, and `m` is the number of its [`Component`]s. Performs a single allocation of `O(n + m)` bytes.
570    ///
571    /// #### Examples
572    ///
573    /// ```
574    /// use willow_data_model::prelude::*;
575    /// let p0: Path<4, 4, 4> = Path::new();
576    /// let p1 = p0.append_path(&Path::from_slices(&[b"hi", b"ho"])?)?;
577    /// assert_eq!(
578    ///     p1.append_path(&Path::from_slice(b"no!")?),
579    ///     Err(PathFromComponentsError::PathTooLong),
580    /// );
581    /// # Ok::<(), PathError>(())
582    /// ```
583    pub fn append_path(
584        &self,
585        other: &Path<MCL, MCC, MPL>,
586    ) -> Result<Self, PathFromComponentsError> {
587        let total_length = self.total_length() + other.total_length();
588
589        let mut builder = PathBuilder::new_from_prefix(
590            total_length,
591            self.component_count() + other.component_count(),
592            self,
593            self.component_count(),
594        )?;
595
596        for additional_component in other.components() {
597            builder.append_component(additional_component);
598        }
599
600        Ok(builder.build())
601    }
602
603    /// Returns the least [`Path`] which is strictly greater (lexicographically) than `self` and which is not [prefixed by](https://willowprotocol.org/specs/data-model/index.html#path_prefix) `self`; or [`None`] if no such [`Path`] exists.
604    ///
605    /// #### Complexity
606    ///
607    /// Runs in `O(n + m)`, where `n` is the total length of the [`Path`] in bytes, and `m` is the number of [`Component`]s. Performs a single allocation of `O(n + m)` bytes.
608    pub fn greater_but_not_prefixed(&self) -> Option<Self> {
609        // We iterate through all components in reverse order. For each component, we check whether we can replace it by another cmponent that is strictly greater but not prefixed by the original component. If that is possible, we do replace it with the least such component and drop all later components. If that is impossible, we try again with the previous component. If this impossible for all components, then this function returns `None`.
610
611        for (i, component) in self.components().enumerate().rev() {
612            // If it is possible to append a zero byte to a component, then doing so yields its successor.
613            if component.len() < MCL
614                && Representation::sum_of_lengths_for_component(self.data.as_ref(), i) < MPL
615            {
616                let mut buf = clone_prefix_and_lengthen_final_component(&self.data, i, 1);
617                buf.put_u8(0);
618
619                return Some(Path {
620                    data: buf.freeze(),
621                    component_count: i + 1,
622                });
623            }
624
625            // Next, we check whether the i-th component can be changed into the least component that is greater but not prefixed by the original. If so, do that and cut off all later components.
626            let mut next_component_length = None;
627            for (j, comp_byte) in component.iter().enumerate().rev() {
628                if *comp_byte < 255 {
629                    next_component_length = Some(j + 1);
630                    break;
631                }
632            }
633
634            if let Some(next_component_length) = next_component_length {
635                // Yay, we can replace the i-th comopnent and then we are done.
636
637                let mut buf = clone_prefix_and_lengthen_final_component(&self.data, i, 0);
638                let length_of_prefix = Representation::sum_of_lengths_for_component(&buf, i);
639
640                // Update the length of the final component.
641                buf_set_final_component_length(
642                    buf.as_mut(),
643                    i,
644                    length_of_prefix - (component.len() - next_component_length),
645                );
646
647                // Increment the byte at position `next_component_length` of the final component.
648                let offset = Representation::start_offset_of_component(buf.as_ref(), i)
649                    + next_component_length
650                    - 1;
651                let byte = buf.as_ref()[offset]; // guaranteed < 255...
652                buf.as_mut()[offset] = byte + 1; // ... hence no overflow here.
653
654                return Some(Path {
655                    data: buf.freeze(),
656                    component_count: i + 1,
657                });
658            }
659        }
660
661        None
662    }
663
664    /// Returns the number of [`Component`]s in `&self`.
665    ///
666    /// Guaranteed to be at most `MCC`.
667    ///
668    /// #### Complexity
669    ///
670    /// Runs in `O(1)`, performs no allocations.
671    ///
672    /// #### Examples
673    ///
674    /// ```
675    /// use willow_data_model::prelude::*;
676    /// let p: Path<4, 4, 4> = Path::from_slices(&[b"hi", b"ho"])?;
677    /// assert_eq!(p.component_count(), 2);
678    /// # Ok::<(), PathError>(())
679    /// ```
680    pub fn component_count(&self) -> usize {
681        self.component_count
682    }
683
684    /// Returns whether `&self` has zero [`Component`]s.
685    ///
686    /// #### Complexity
687    ///
688    /// Runs in `O(1)`, performs no allocations.
689    ///
690    /// #### Examples
691    ///
692    /// ```
693    /// use willow_data_model::prelude::*;
694    /// assert_eq!(Path::<4, 4, 4>::new().is_empty(), true);
695    ///
696    /// let p: Path<4, 4, 4> = Path::from_slices(&[b"hi", b"ho"])?;
697    /// assert_eq!(p.is_empty(), false);
698    /// # Ok::<(), PathError>(())
699    /// ```
700    pub fn is_empty(&self) -> bool {
701        self.component_count() == 0
702    }
703
704    /// Returns the sum of the lengths of all [`Component`]s in `&self`.
705    ///
706    /// Guaranteed to be at most `MCC`.
707    ///
708    /// #### Complexity
709    ///
710    /// Runs in `O(1)`, performs no allocations.
711    ///
712    /// #### Examples
713    ///
714    /// ```
715    /// use willow_data_model::prelude::*;
716    /// let p: Path<4, 4, 4> = Path::from_slices(&[b"hi", b"ho"])?;
717    /// assert_eq!(p.total_length(), 4);
718    /// # Ok::<(), PathError>(())
719    /// ```
720    pub fn total_length(&self) -> usize {
721        self.total_length_of_prefix(self.component_count())
722    }
723
724    /// Returns the sum of the lengths of the first `i` [`Component`]s in `&self`; panics if `i >= self.component_count()`. More efficient than `path.create_prefix(i).path_length()`.
725    ///
726    /// Guaranteed to be at most `MCC`.
727    ///
728    /// #### Complexity
729    ///
730    /// Runs in `O(1)`, performs no allocations.
731    ///
732    /// #### Examples
733    ///
734    /// ```
735    /// use willow_data_model::prelude::*;
736    /// let p: Path<4, 4, 4> = Path::from_slices(&[b"hi", b"ho"])?;
737    /// assert_eq!(p.total_length_of_prefix(0), 0);
738    /// assert_eq!(p.total_length_of_prefix(1), 2);
739    /// assert_eq!(p.total_length_of_prefix(2), 4);
740    /// # Ok::<(), PathError>(())
741    /// ```
742    pub fn total_length_of_prefix(&self, i: usize) -> usize {
743        Representation::total_length(&self.data, i)
744    }
745
746    /// Tests whether `&self` is a [prefix](https://willowprotocol.org/specs/data-model/index.html#path_prefix) of the given [`Path`].
747    /// [`Path`]s are always a prefix of themselves, and the empty [`Path`] is a prefix of every [`Path`].
748    ///
749    /// #### Complexity
750    ///
751    /// Runs in `O(n + m)`, where `n` is the total length of the longer [`Path`] in bytes, and `m` is the greatest number of [`Component`]s.
752    ///
753    /// #### Examples
754    ///
755    /// ```
756    /// use willow_data_model::prelude::*;
757    /// let p: Path<4, 4, 4> = Path::from_slices(&[b"hi", b"ho"])?;
758    /// assert!(Path::new().is_prefix_of(&p));
759    /// assert!(Path::from_slice(b"hi")?.is_prefix_of(&p));
760    /// assert!(Path::from_slices(&[b"hi", b"ho"])?.is_prefix_of(&p));
761    /// assert!(!Path::from_slices(&[b"hi", b"gh"])?.is_prefix_of(&p));
762    /// # Ok::<(), PathError>(())
763    /// ```
764    pub fn is_prefix_of(&self, other: &Self) -> bool {
765        self.prefix_cmp(other)
766            .map(|ord| ord.is_le())
767            .unwrap_or(false)
768    }
769
770    /// Tests whether `&self` is [prefixed by](https://willowprotocol.org/specs/data-model/index.html#path_prefix) the given [`Path`].
771    /// [`Path`]s are always prefixed by themselves, and by the empty [`Path`].
772    ///
773    /// #### Complexity
774    ///
775    /// Runs in `O(n + m)`, where `n` is the total length of the longer [`Path`] in bytes, and `m` is the greatest number of [`Component`]s.
776    ///
777    /// #### Examples
778    ///
779    /// ```
780    /// use willow_data_model::prelude::*;
781    /// let p: Path<4, 4, 4> = Path::from_slices(&[b"hi", b"ho"])?;
782    /// assert!(p.is_prefixed_by(&Path::new()));
783    /// assert!(p.is_prefixed_by(&Path::from_slice(b"hi")?));
784    /// assert!(p.is_prefixed_by(&Path::from_slices(&[b"hi", b"ho"])?));
785    /// assert!(!p.is_prefixed_by(&Path::from_slices(&[b"hi", b"gh"])?));
786    /// # Ok::<(), PathError>(())
787    /// ```
788    pub fn is_prefixed_by(&self, other: &Self) -> bool {
789        other.is_prefix_of(self)
790    }
791
792    /// Tests whether `&self` is [related](https://willowprotocol.org/specs/data-model/index.html#path_related) to the given [`Path`], that is, whether either one is a [prefix](https://willowprotocol.org/specs/data-model/index.html#path_prefix) of the other.
793    ///
794    /// #### Complexity
795    ///
796    /// Runs in `O(n + m)`, where `n` is the total length of the longer [`Path`] in bytes, and `m` is the greatest number of [`Component`]s.
797    ///
798    /// #### Examples
799    ///
800    /// ```
801    /// use willow_data_model::prelude::*;
802    /// let p: Path<4, 4, 4> = Path::from_slice(b"hi")?;
803    /// assert!(p.is_related_to(&Path::new()));
804    /// assert!(p.is_related_to(&Path::from_slice(b"hi")?));
805    /// assert!(p.is_related_to(&Path::from_slices(&[b"hi", b"ho"])?));
806    /// assert!(!p.is_related_to(&Path::from_slices(&[b"no"])?));
807    /// # Ok::<(), PathError>(())
808    /// ```
809    pub fn is_related_to(&self, other: &Self) -> bool {
810        self.prefix_cmp(other).is_some()
811    }
812
813    /// Returns the [`Ordering`] describing the prefix relation between `self` and `other`.
814    ///
815    /// #### Complexity
816    ///
817    /// Runs in `O(n + m)`, where `n` is the total length of the longer [`Path`] in bytes, and `m` is the greatest number of [`Component`]s.
818    ///
819    /// #### Examples
820    ///
821    /// ```
822    /// use core::cmp::Ordering;
823    /// use willow_data_model::prelude::*;
824    /// let p: Path<4, 4, 4> = Path::from_slice(b"hi")?;
825    /// assert_eq!(p.prefix_cmp(&Path::new()), Some(Ordering::Greater));
826    /// assert_eq!(p.prefix_cmp(&Path::from_slice(b"hi")?), Some(Ordering::Equal));
827    /// assert_eq!(p.prefix_cmp(&Path::from_slices(&[b"hi", b"ho"])?), Some(Ordering::Less));
828    /// assert_eq!(p.prefix_cmp(&Path::from_slice(b"no")?), None);
829    /// # Ok::<(), PathError>(())
830    /// ```
831    pub fn prefix_cmp(&self, other: &Self) -> Option<Ordering> {
832        for (comp_a, comp_b) in self.components().zip(other.components()) {
833            if comp_a != comp_b {
834                return None;
835            }
836        }
837
838        self.component_count().partial_cmp(&other.component_count())
839    }
840
841    /// Returns the `i`-th [`Component`] of `&self`.
842    ///
843    /// #### Complexity
844    ///
845    /// Runs in `O(1)`, performs no allocations.
846    ///
847    /// #### Examples
848    ///
849    /// ```
850    /// use willow_data_model::prelude::*;
851    /// let p: Path<4, 4, 4> = Path::from_slices(&[b"hi", b"ho"])?;
852    /// assert_eq!(p.component(0), Some(Component::new(b"hi")?));
853    /// assert_eq!(p.component(1), Some(Component::new(b"ho")?));
854    /// assert_eq!(p.component(2), None);
855    /// # Ok::<(), PathError>(())
856    /// ```
857    pub fn component(&self, i: usize) -> Option<&Component<MCL>> {
858        if i < self.component_count {
859            Some(Representation::component(&self.data, i))
860        } else {
861            None
862        }
863    }
864
865    /// Returns the `i`-th [`Component`] of `&self`, without checking whether `i < self.component_count()`.
866    ///
867    /// #### Safety
868    ///
869    /// Undefined behaviour if `i >= self.component_count()`.
870    ///
871    /// #### Complexity
872    ///
873    /// Runs in `O(1)`, performs no allocations.
874    ///
875    /// #### Examples
876    ///
877    /// ```
878    /// use willow_data_model::prelude::*;
879    /// let p: Path<4, 4, 4> = Path::from_slices(&[b"hi", b"ho"])?;
880    /// assert_eq!(unsafe { p.component_unchecked(0) }, Component::new(b"hi")?);
881    /// assert_eq!(unsafe { p.component_unchecked(1) }, Component::new(b"ho")?);
882    /// # Ok::<(), PathError>(())
883    /// ```
884    pub unsafe fn component_unchecked(&self, i: usize) -> &Component<MCL> {
885        Representation::component(&self.data, i)
886    }
887
888    /// Returns an [owned handle](OwnedComponent) to the `i`-th component of `&self`.
889    ///
890    /// #### Complexity
891    ///
892    /// Runs in `O(1)`, performs no allocations.
893    ///
894    /// #### Examples
895    ///
896    /// ```
897    /// use willow_data_model::prelude::*;
898    /// let p: Path<4, 4, 4> = Path::from_slices(&[b"hi", b"ho"])?;
899    /// assert_eq!(p.owned_component(0), Some(OwnedComponent::new(b"hi")?));
900    /// assert_eq!(p.owned_component(1), Some(OwnedComponent::new(b"ho")?));
901    /// assert_eq!(p.owned_component(2), None);
902    /// # Ok::<(), PathError>(())
903    /// ```
904    pub fn owned_component(&self, i: usize) -> Option<OwnedComponent<MCL>> {
905        if i < self.component_count {
906            let start = Representation::start_offset_of_component(&self.data, i);
907            let end = Representation::end_offset_of_component(&self.data, i);
908            Some(OwnedComponent(self.data.slice(start..end)))
909        } else {
910            None
911        }
912    }
913
914    /// Returns an [owned handle](OwnedComponent) to the `i`-th component of `&self`, without checking whether `i < self.component_count()`.
915    ///
916    /// #### Safety
917    ///
918    /// Undefined behaviour if `i >= self.component_count()`.
919    ///
920    /// #### Complexity
921    ///
922    /// Runs in `O(1)`, performs no allocations.
923    ///
924    /// #### Examples
925    ///
926    /// ```
927    /// use willow_data_model::prelude::*;
928    /// let p: Path<4, 4, 4> = Path::from_slices(&[b"hi", b"ho"])?;
929    /// assert_eq!(p.owned_component(0), Some(OwnedComponent::new(b"hi")?));
930    /// assert_eq!(p.owned_component(1), Some(OwnedComponent::new(b"ho")?));
931    /// assert_eq!(p.owned_component(2), None);
932    /// # Ok::<(), PathError>(())
933    /// ```
934    pub unsafe fn owned_component_unchecked(&self, i: usize) -> OwnedComponent<MCL> {
935        let start = Representation::start_offset_of_component(&self.data, i);
936        let end = Representation::end_offset_of_component(&self.data, i);
937        OwnedComponent(self.data.slice(start..end))
938    }
939
940    /// Creates an iterator over the [`Component`]s of `&self`.
941    ///
942    /// Stepping the iterator takes `O(1)` time and performs no memory allocations.
943    ///
944    /// #### Complexity
945    ///
946    /// Runs in `O(1)`, performs no allocations.
947    ///
948    /// #### Examples
949    ///
950    /// ```
951    /// use willow_data_model::prelude::*;
952    /// let p: Path<4, 4, 4> = Path::from_slices(&[b"hi", b"ho"])?;
953    /// let mut comps = p.components();
954    /// assert_eq!(comps.next(), Some(Component::new(b"hi")?));
955    /// assert_eq!(comps.next(), Some(Component::new(b"ho")?));
956    /// assert_eq!(comps.next(), None);
957    /// # Ok::<(), PathError>(())
958    /// ```
959    pub fn components(
960        &self,
961    ) -> impl DoubleEndedIterator<Item = &Component<MCL>> + ExactSizeIterator<Item = &Component<MCL>>
962    {
963        self.suffix_components(0)
964    }
965
966    /// Creates an iterator over the [`Component`]s of `&self`, starting at the `i`-th [`Component`]. If `i` is greater than or equal to the number of [`Component`]s, the iterator yields zero items.
967    ///
968    /// Stepping the iterator takes `O(1)` time and performs no memory allocations.
969    ///
970    /// #### Complexity
971    ///
972    /// Runs in `O(1)`, performs no allocations.
973    ///
974    /// #### Examples
975    ///
976    /// ```
977    /// use willow_data_model::prelude::*;
978    /// let p: Path<4, 4, 4> = Path::from_slices(&[b"hi", b"ho"])?;
979    /// let mut comps = p.suffix_components(1);
980    /// assert_eq!(comps.next(), Some(Component::new(b"ho")?));
981    /// assert_eq!(comps.next(), None);
982    /// # Ok::<(), PathError>(())
983    /// ```
984    pub fn suffix_components(
985        &'_ self,
986        i: usize,
987    ) -> impl DoubleEndedIterator<Item = &Component<MCL>> + ExactSizeIterator<Item = &Component<MCL>>
988    {
989        (i..self.component_count()).map(|i| {
990            self.component(i).unwrap() // Only `None` if `i >= self.component_count()`
991        })
992    }
993
994    /// Creates an iterator over [owned handles](OwnedComponent) to the components of `&self`.
995    ///
996    /// Stepping the iterator takes `O(1)` time and performs no memory allocations.
997    ///
998    /// #### Complexity
999    ///
1000    /// Runs in `O(1)`, performs no allocations.
1001    ///
1002    /// #### Examples
1003    ///
1004    /// ```
1005    /// use willow_data_model::prelude::*;
1006    /// let p: Path<4, 4, 4> = Path::from_slices(&[b"hi", b"ho"])?;
1007    /// let mut comps = p.owned_components();
1008    /// assert_eq!(comps.next(), Some(OwnedComponent::new(b"hi")?));
1009    /// assert_eq!(comps.next(), Some(OwnedComponent::new(b"ho")?));
1010    /// assert_eq!(comps.next(), None);
1011    /// # Ok::<(), PathError>(())
1012    /// ```
1013    pub fn owned_components(
1014        &self,
1015    ) -> impl DoubleEndedIterator<Item = OwnedComponent<MCL>>
1016    + ExactSizeIterator<Item = OwnedComponent<MCL>>
1017    + '_ {
1018        self.suffix_owned_components(0)
1019    }
1020
1021    /// Creates an iterator over [owned handles](OwnedComponent) to the components of `&self`, starting at the `i`-th [`OwnedComponent`]. If `i` is greater than or equal to the number of [`OwnedComponent`], the iterator yields zero items.
1022    ///
1023    /// Stepping the iterator takes `O(1)` time and performs no memory allocations.
1024    ///
1025    /// #### Complexity
1026    ///
1027    /// Runs in `O(1)`, performs no allocations.
1028    ///
1029    /// #### Examples
1030    ///
1031    /// ```
1032    /// use willow_data_model::prelude::*;
1033    /// let p: Path<4, 4, 4> = Path::from_slices(&[b"hi", b"ho"])?;
1034    /// let mut comps = p.suffix_owned_components(1);
1035    /// assert_eq!(comps.next(), Some(OwnedComponent::new(b"ho")?));
1036    /// assert_eq!(comps.next(), None);
1037    /// # Ok::<(), PathError>(())
1038    /// ```
1039    pub fn suffix_owned_components(
1040        &self,
1041        i: usize,
1042    ) -> impl DoubleEndedIterator<Item = OwnedComponent<MCL>>
1043    + ExactSizeIterator<Item = OwnedComponent<MCL>>
1044    + '_ {
1045        (i..self.component_count()).map(|i| {
1046            self.owned_component(i).unwrap() // Only `None` if `i >= self.component_count()`
1047        })
1048    }
1049
1050    /// Creates a new [`Path`] that consists of the first `component_count` [`Component`]s of `&self`. More efficient than creating a new [`Path`] from scratch.
1051    ///
1052    /// Returns [`None`] if `component_count` is greater than `self.get_component_count()`.
1053    ///
1054    /// #### Complexity
1055    ///
1056    /// Runs in `O(1)`, performs no allocations.
1057    ///
1058    /// #### Examples
1059    ///
1060    /// ```
1061    /// use willow_data_model::prelude::*;
1062    /// let p: Path<4, 4, 4> = Path::from_slices(&[b"hi", b"ho"])?;
1063    /// assert_eq!(p.create_prefix(0), Some(Path::new()));
1064    /// assert_eq!(p.create_prefix(1), Some(Path::from_slice(b"hi")?));
1065    /// assert_eq!(p.create_prefix(2), Some(Path::from_slices(&[b"hi", b"ho"])?));
1066    /// assert_eq!(p.create_prefix(3), None);
1067    /// # Ok::<(), PathError>(())
1068    /// ```
1069    pub fn create_prefix(&self, component_count: usize) -> Option<Self> {
1070        if component_count > self.component_count() {
1071            None
1072        } else {
1073            Some(unsafe { self.create_prefix_unchecked(component_count) })
1074        }
1075    }
1076
1077    /// Creates a new [`Path`] that consists of the first `component_count` [`Component`]s of `&self`. More efficient than creating a new [`Path`] from scratch.
1078    ///
1079    /// #### Safety
1080    ///
1081    /// Undefined behaviour if `component_count` is greater than `self.component_count()`. May manifest directly, or at any later
1082    /// function invocation that operates on the resulting [`Path`].
1083    ///
1084    /// #### Complexity
1085    ///
1086    /// Runs in `O(1)`, performs no allocations.
1087    ///
1088    /// #### Examples
1089    ///
1090    /// ```
1091    /// use willow_data_model::prelude::*;
1092    /// let p: Path<4, 4, 4> = Path::from_slices(&[b"hi", b"ho"])?;
1093    /// assert_eq!(unsafe { p.create_prefix_unchecked(0) }, Path::new());
1094    /// assert_eq!(unsafe { p.create_prefix_unchecked(1) }, Path::from_slice(b"hi")?);
1095    /// assert_eq!(unsafe { p.create_prefix_unchecked(2) }, Path::from_slices(&[b"hi", b"ho"])?);
1096    /// # Ok::<(), PathError>(())
1097    /// ```
1098    pub unsafe fn create_prefix_unchecked(&self, component_count: usize) -> Self {
1099        Self {
1100            data: self.data.clone(),
1101            component_count,
1102        }
1103    }
1104
1105    /// Creates an iterator over all [prefixes](https://willowprotocol.org/specs/data-model/index.html#path_prefix) of `&self` (including the empty [`Path`] and `&self` itself).
1106    ///
1107    /// Stepping the iterator takes `O(1)` time and performs no memory allocations.
1108    ///
1109    /// #### Complexity
1110    ///
1111    /// Runs in `O(1)`, performs no allocations.
1112    ///
1113    /// #### Examples
1114    ///
1115    /// ```
1116    /// use willow_data_model::prelude::*;
1117    /// let p: Path<4, 4, 4> = Path::from_slices(&[b"hi", b"ho"])?;
1118    /// let mut prefixes = p.all_prefixes();
1119    /// assert_eq!(prefixes.next(), Some(Path::new()));
1120    /// assert_eq!(prefixes.next(), Some(Path::from_slice(b"hi")?));
1121    /// assert_eq!(prefixes.next(), Some(Path::from_slices(&[b"hi", b"ho"])?));
1122    /// assert_eq!(prefixes.next(), None);
1123    /// # Ok::<(), PathError>(())
1124    /// ```
1125    pub fn all_prefixes(&self) -> impl DoubleEndedIterator<Item = Self> + '_ {
1126        (0..=self.component_count()).map(|i| {
1127            unsafe {
1128                self.create_prefix_unchecked(i) // safe to call for i <= self.component_count()
1129            }
1130        })
1131    }
1132
1133    /// Returns the longest common [prefix](https://willowprotocol.org/specs/data-model/index.html#path_prefix) of `&self` and the given [`Path`].
1134    ///
1135    /// #### Complexity
1136    ///
1137    /// Runs in `O(n + m)`, where `n` is the total length of the shorter of the two [`Path`]s, and `m` is the lesser number of [`Component`]s. Performs a single allocation of `O(n + m)` bytes to create the return value.
1138    ///
1139    /// #### Examples
1140    ///
1141    /// ```
1142    /// use willow_data_model::prelude::*;
1143    /// let p1: Path<4, 4, 4> = Path::from_slices(&[b"hi", b"ho"])?;
1144    /// let p2: Path<4, 4, 4> = Path::from_slices(&[b"hi", b"he"])?;
1145    /// assert_eq!(p1.longest_common_prefix(&p2), Path::from_slice(b"hi")?);
1146    /// # Ok::<(), PathError>(())
1147    /// ```
1148    pub fn longest_common_prefix(&self, other: &Self) -> Self {
1149        let mut lcp_len = 0;
1150
1151        for (comp_a, comp_b) in self.components().zip(other.components()) {
1152            if comp_a != comp_b {
1153                break;
1154            }
1155
1156            lcp_len += 1
1157        }
1158
1159        self.create_prefix(lcp_len).unwrap() // zip ensures that lcp_len <= self.component_count()
1160    }
1161}
1162
1163impl<const MCL: usize, const MCC: usize, const MPL: usize> PartialEq for Path<MCL, MCC, MPL> {
1164    fn eq(&self, other: &Self) -> bool {
1165        if self.component_count != other.component_count {
1166            false
1167        } else {
1168            self.components().eq(other.components())
1169        }
1170    }
1171}
1172
1173impl<const MCL: usize, const MCC: usize, const MPL: usize> Eq for Path<MCL, MCC, MPL> {}
1174
1175impl<const MCL: usize, const MCC: usize, const MPL: usize> Hash for Path<MCL, MCC, MPL> {
1176    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
1177        self.component_count.hash(state);
1178
1179        for comp in self.components() {
1180            comp.hash(state);
1181        }
1182    }
1183}
1184
1185impl<const MCL: usize, const MCC: usize, const MPL: usize> PartialOrd for Path<MCL, MCC, MPL> {
1186    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1187        Some(self.cmp(other))
1188    }
1189}
1190
1191/// Compares paths lexicographically, since that is the path ordering that the Willow spec always uses.
1192impl<const MCL: usize, const MCC: usize, const MPL: usize> Ord for Path<MCL, MCC, MPL> {
1193    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1194        self.components().cmp(other.components())
1195    }
1196}
1197
1198/// The least path is the empty path.
1199impl<const MCL: usize, const MCC: usize, const MPL: usize> LeastElement for Path<MCL, MCC, MPL> {
1200    /// Returns the least path.
1201    fn least() -> Self {
1202        Self::new()
1203    }
1204}
1205
1206impl<const MCL: usize, const MCC: usize, const MPL: usize> GreatestElement for Path<MCL, MCC, MPL> {
1207    /// Creates the greatest possible [`Path`] (with respect to lexicographical ordering, which is also the [`Ord`] implementation of [`Path`]).
1208    ///
1209    /// #### Complexity
1210    ///
1211    /// Runs in `O(MCC + MPL)`. Performs a single allocation of `O(MPL)` bytes.
1212    ///
1213    /// #### Examples
1214    ///
1215    /// ```
1216    /// use willow_data_model::prelude::*;
1217    /// use order_theory::GreatestElement;
1218    ///
1219    /// let p = Path::<4, 4, 4>::greatest();
1220    /// assert_eq!(p.component_count(), 4);
1221    /// assert_eq!(p.component(0).unwrap().as_ref(), &[255, 255, 255, 255]);
1222    /// assert!(p.component(1).unwrap().is_empty());
1223    /// assert!(p.component(2).unwrap().is_empty());
1224    /// assert!(p.component(3).unwrap().is_empty());
1225    /// ```
1226    fn greatest() -> Self {
1227        let max_comp_bytes = [255; MCL];
1228
1229        let mut num_comps = if MCL == 0 {
1230            MCC
1231        } else {
1232            core::cmp::min(MCC, MPL.div_ceil(MCL))
1233        };
1234        let mut path_builder = PathBuilder::new(MPL, MCC).unwrap();
1235
1236        let mut len_so_far = 0;
1237
1238        for _ in 0..num_comps {
1239            let comp_len = core::cmp::min(MCL, MPL - len_so_far);
1240            let component = unsafe { Component::new_unchecked(&max_comp_bytes[..comp_len]) };
1241            path_builder.append_component(component);
1242
1243            len_so_far += comp_len;
1244        }
1245
1246        while num_comps < MCC {
1247            path_builder.append_component(Component::new_empty());
1248            num_comps += 1;
1249        }
1250
1251        path_builder.build()
1252    }
1253}
1254
1255impl<const MCL: usize, const MCC: usize, const MPL: usize> LowerSemilattice
1256    for Path<MCL, MCC, MPL>
1257{
1258    fn greatest_lower_bound(&self, other: &Self) -> Self {
1259        if self <= other {
1260            self.clone()
1261        } else {
1262            other.clone()
1263        }
1264    }
1265}
1266
1267impl<const MCL: usize, const MCC: usize, const MPL: usize> UpperSemilattice
1268    for Path<MCL, MCC, MPL>
1269{
1270    fn least_upper_bound(&self, other: &Self) -> Self {
1271        if self >= other {
1272            self.clone()
1273        } else {
1274            other.clone()
1275        }
1276    }
1277}
1278
1279impl<const MCL: usize, const MCC: usize, const MPL: usize> TryPredecessor for Path<MCL, MCC, MPL> {
1280    fn try_predecessor(&self) -> Option<Self> {
1281        if self.component_count() == 0 {
1282            // We are the empty path, so we do not have a predecessor.
1283            None
1284        } else {
1285            let final_component = self.component(self.component_count() - 1).unwrap();
1286
1287            // We have a component. Our predecessor depends only on the final component, with several options depending on the final byte:
1288            if final_component.as_bytes().is_empty() {
1289                // If the final component is empty, we simply remove it to obtain the predecessor.
1290                Some(unsafe { self.create_prefix_unchecked(self.component_count() - 1) })
1291            } else {
1292                let final_byte = final_component.as_bytes()[final_component.len() - 1];
1293
1294                // The final component was non-empty. We now decrement the final component, and then fill up the path with maximally many maximal components.
1295
1296                // Create a builder for the new component, which will be of maximal length, maximal component count, and starting with `self` sans the final_component.
1297                let predecessor_total_len = core::cmp::min(
1298                    MPL,
1299                    self.total_length_of_prefix(self.component_count() - 1) // unchanged components
1300                        + if final_byte == 0 { final_component.len() - 1 } else { MCL } // replacement of self.final_comp
1301                        + ((MCC - self.component_count()) * MCL), // padding 255 bytes
1302                );
1303                let mut builder = PathBuilder::new_from_prefix(
1304                    predecessor_total_len,
1305                    MCC,
1306                    self,
1307                    self.component_count() - 1,
1308                )
1309                .unwrap();
1310
1311                // The meaning of "decrement the final component" depends on the final byte.
1312                // In either case we do not actually construct a coponent, but merely apend the decremented component to the builder.
1313                if final_byte == 0 {
1314                    // If the final byte is zero, we simply remove it from the component.
1315                    builder.append_component(unsafe {
1316                        Component::<MCL>::new_unchecked(
1317                            &final_component[..final_component.len() - 1],
1318                        )
1319                    });
1320                } else {
1321                    // If the final byte is not zero, we decrement the final byte by one and then append 255 bytes until hitting the MCL or the MPL, whichever happens first..
1322
1323                    // The way we actually implement this is by creating a mutable array of MCL many 255 bytes, overwriting the start of it, and then feeding the correct prefix into the builder.
1324                    let mut arr = [255; MCL];
1325
1326                    arr[0..final_component.len()].copy_from_slice(&final_component[..]);
1327                    arr[final_component.len() - 1] = final_byte - 1;
1328
1329                    builder.append_component(unsafe {
1330                        Component::<MCL>::new_unchecked(
1331                            &arr[..core::cmp::min(
1332                                MCL,
1333                                MPL - self.total_length_of_prefix(self.component_count() - 1),
1334                            )],
1335                        )
1336                    });
1337                }
1338
1339                while builder.component_count() < MCC {
1340                    // We have decremented the final component. Now we append maximal components while we can.
1341                    let comp_len = core::cmp::min(MCL, MPL - builder.total_length());
1342
1343                    let arr = [255; MCL];
1344                    builder.append_component(unsafe {
1345                        Component::<MCL>::new_unchecked(&arr[..comp_len])
1346                    });
1347                }
1348
1349                Some(builder.build())
1350            }
1351        }
1352    }
1353}
1354
1355impl<const MCL: usize, const MCC: usize, const MPL: usize> PredecessorExceptForLeast
1356    for Path<MCL, MCC, MPL>
1357{
1358}
1359
1360impl<const MCL: usize, const MCC: usize, const MPL: usize> TrySuccessor for Path<MCL, MCC, MPL> {
1361    /// Returns the least path which is strictly greater than `self`, or return `None` if `self` is the greatest possible path.
1362    ///
1363    /// #### Complexity
1364    ///
1365    /// Runs in `O(n + m)`, where `n` is the total length of the [`Path`] in bytes, and `m` is the number of [`Component`]s. Performs a single allocation of `O(n + m)` bytes.
1366    ///
1367    /// #### Examples
1368    ///
1369    /// ```
1370    /// use willow_data_model::prelude::*;
1371    /// use order_theory::TrySuccessor;
1372    ///
1373    /// let p: Path<3, 3, 3> = Path::from_slices(&[
1374    ///     [255].as_slice(),
1375    ///     [9, 255].as_slice(),
1376    ///     [].as_slice(),
1377    /// ])?;
1378    /// assert_eq!(p.try_successor(), Some(Path::from_slices(&[
1379    ///     [255].as_slice(),
1380    ///     [10].as_slice(),
1381    /// ])?));
1382    /// # Ok::<(), PathError>(())
1383    /// ```
1384    fn try_successor(&self) -> Option<Self> {
1385        // If it is possible to append an empty component, then doing so yields the successor.
1386        if let Ok(path) = self.append_component(Component::new_empty()) {
1387            return Some(path);
1388        }
1389
1390        // Otherwise, we try incrementing the final component. If that fails,
1391        // we try to increment the second-to-final component, and so on.
1392        // All components that come after the incremented component are discarded.
1393        // If *no* component can be incremented, `self` is the maximal path and we return `None`.
1394
1395        for (i, component) in self.components().enumerate().rev() {
1396            // It would be nice to call a `try_increment_component` function, but in order to avoid
1397            // memory allocations, we write some lower-level but more efficient code.
1398
1399            // If it is possible to append a zero byte to a component, then doing so yields its successor.
1400            if component.len() < MCL
1401                && Representation::sum_of_lengths_for_component(self.data.as_ref(), i) < MPL
1402            {
1403                // We now know how to construct the path successor of `self`:
1404                // Take the first `i` components (this *excludes* the current `component`),
1405                // then append `component` with an additional zero byte at the end.
1406                let mut buf = clone_prefix_and_lengthen_final_component(&self.data, i, 1);
1407                buf.put_u8(0);
1408
1409                return Some(Path {
1410                    data: buf.freeze(),
1411                    component_count: i + 1,
1412                });
1413            }
1414
1415            // We **cannot** append a zero byte, so instead we check whether we can treat the component as a fixed-width integer and increment it. The only failure case is if that component consists of 255-bytes only.
1416            let can_increment = !component.iter().all(|byte| *byte == 255);
1417
1418            // If we cannot increment, we go to the next iteration of the loop. But if we can, we can create a copy of the
1419            // prefix on the first `i + 1` components, and mutate its backing memory in-place.
1420            if can_increment {
1421                let mut buf = clone_prefix_and_lengthen_final_component(&self.data, i, 0);
1422
1423                let start_component_offset =
1424                    Representation::start_offset_of_component(buf.as_ref(), i);
1425                let end_component_offset = Representation::end_offset_of_component(buf.as_ref(), i);
1426
1427                let overflows = fixed_width_increment_reporting_overflows(
1428                    &mut buf.as_mut()[start_component_offset..end_component_offset],
1429                );
1430                let new_sum_of_lengths =
1431                    Representation::sum_of_lengths_for_component(buf.as_ref(), i) - overflows;
1432                buf_set_final_component_length(buf.as_mut(), i, new_sum_of_lengths);
1433
1434                return Some(Path {
1435                    data: buf.freeze(),
1436                    component_count: i + 1,
1437                });
1438            }
1439        }
1440
1441        // Failed to increment any component, so `self` is the maximal path.
1442        None
1443    }
1444}
1445
1446impl<const MCL: usize, const MCC: usize, const MPL: usize> SuccessorExceptForGreatest
1447    for Path<MCL, MCC, MPL>
1448{
1449}
1450
1451impl<const MCL: usize, const MCC: usize, const MPL: usize> Debug for Path<MCL, MCC, MPL> {
1452    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1453        f.debug_tuple("Path").field(&FmtHelper(self)).finish()
1454    }
1455}
1456
1457struct FmtHelper<'a, const MCL: usize, const MCC: usize, const MPL: usize>(&'a Path<MCL, MCC, MPL>);
1458
1459impl<'a, const MCL: usize, const MCC: usize, const MPL: usize> fmt::Debug
1460    for FmtHelper<'a, MCL, MCC, MPL>
1461{
1462    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1463        if self.0.is_empty() {
1464            write!(f, "<empty>")
1465        } else {
1466            for comp in self.0.components() {
1467                write!(f, "/")?;
1468                write!(f, "{:?}", ComponentFmtHelper::new(&comp, false))?;
1469            }
1470
1471            Ok(())
1472        }
1473    }
1474}
1475
1476impl<const MCL: usize, const MCC: usize, const MPL: usize> fmt::Display for Path<MCL, MCC, MPL> {
1477    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1478        write!(f, "{:?}", FmtHelper(self))
1479    }
1480}
1481
1482#[cfg(feature = "dev")]
1483impl<'a, const MCL: usize, const MCC: usize, const MPL: usize> Arbitrary<'a>
1484    for Path<MCL, MCC, MPL>
1485{
1486    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self, ArbitraryError> {
1487        let mut total_length_in_bytes: usize = Arbitrary::arbitrary(u)?;
1488        total_length_in_bytes %= MPL + 1;
1489
1490        let data: Box<[u8]> = Arbitrary::arbitrary(u)?;
1491        total_length_in_bytes = core::cmp::min(total_length_in_bytes, data.len());
1492
1493        let mut num_components: usize = Arbitrary::arbitrary(u)?;
1494        num_components %= MCC + 1;
1495
1496        if num_components == 0 {
1497            total_length_in_bytes = 0;
1498        }
1499
1500        let mut builder = PathBuilder::new(total_length_in_bytes, num_components).unwrap();
1501
1502        let mut length_total_so_far = 0;
1503        for i in 0..num_components {
1504            // Determine the length of the i-th component: randomly within some constraints for all but the final one. The final length is chosen to match the total_length_in_bytes.
1505            let length_of_ith_component = if i + 1 == num_components {
1506                if total_length_in_bytes - length_total_so_far > MCL {
1507                    return Err(ArbitraryError::IncorrectFormat);
1508                } else {
1509                    total_length_in_bytes - length_total_so_far
1510                }
1511            } else {
1512                // Any non-final component can take on a random length, ...
1513                let mut component_length: usize = Arbitrary::arbitrary(u)?;
1514                // ... except it must be at most the MCL, and...
1515                component_length %= MCL + 1;
1516                // ... the total length of all components must not exceed the total path length.
1517                component_length = core::cmp::min(
1518                    component_length,
1519                    total_length_in_bytes - length_total_so_far,
1520                );
1521                component_length
1522            };
1523
1524            builder.append_component(
1525                Component::new(
1526                    &data[length_total_so_far..length_total_so_far + length_of_ith_component],
1527                )
1528                .unwrap(),
1529            );
1530            length_total_so_far += length_of_ith_component;
1531        }
1532
1533        Ok(builder.build())
1534    }
1535
1536    #[inline]
1537    fn size_hint(depth: usize) -> (usize, Option<usize>) {
1538        (
1539            and_all(&[
1540                usize::size_hint(depth),
1541                usize::size_hint(depth),
1542                Box::<[u8]>::size_hint(depth),
1543            ])
1544            .0,
1545            None,
1546        )
1547    }
1548}
1549
1550/////////////////////////////////////////////////////////////////////
1551// Helpers for efficiently creating successors.                    //
1552// Efficiency warrants some low-level fiddling around here, sorry. //
1553/////////////////////////////////////////////////////////////////////
1554
1555/// Creates a new BufMut that stores the heap encoding of the first i components of `original`, but increasing the length of the final component by `extra_capacity`. No data to fill that extra capacity is written into the buffer.
1556fn clone_prefix_and_lengthen_final_component(
1557    representation: &[u8],
1558    i: usize,
1559    extra_capacity: usize,
1560) -> BytesMut {
1561    let successor_path_length =
1562        Representation::sum_of_lengths_for_component(representation, i) + extra_capacity;
1563    let buf_capacity = size_of::<usize>() * (i + 2) + successor_path_length;
1564    let mut buf = BytesMut::with_capacity(buf_capacity);
1565
1566    // Write the length of the successor path as the first usize.
1567    buf.extend_from_slice(&(i + 1).to_ne_bytes());
1568
1569    // Next, copy the total path lengths for the first i prefixes.
1570    buf.extend_from_slice(&representation[size_of::<usize>()..size_of::<usize>() * (i + 2)]);
1571
1572    // Now, write the length of the final component, which is one greater than before.
1573    buf_set_final_component_length(buf.as_mut(), i, successor_path_length);
1574
1575    // Finally, copy the raw bytes of the first i+1 components.
1576    buf.extend_from_slice(
1577        &representation[Representation::start_offset_of_component(representation, 0)
1578            ..Representation::start_offset_of_component(representation, i + 1)],
1579    );
1580
1581    buf
1582}
1583
1584// In a buffer that stores a path on the heap, set the sum of all component lengths for the i-th component, which must be the final component.
1585fn buf_set_final_component_length(buf: &mut [u8], i: usize, new_sum_of_lengths: usize) {
1586    let comp_len_start = Representation::start_offset_of_sum_of_lengths_for_component(i);
1587    let comp_len_end = comp_len_start + size_of::<usize>();
1588    buf[comp_len_start..comp_len_end].copy_from_slice(&new_sum_of_lengths.to_ne_bytes()[..]);
1589}
1590
1591// Overflows to all zeroes if all bytes are 255. Returns the number of overflowing bytes.
1592fn fixed_width_increment_reporting_overflows(buf: &mut [u8]) -> usize {
1593    let mut overflows = 0;
1594    for byte_ref in buf.iter_mut().rev() {
1595        if *byte_ref == 255 {
1596            *byte_ref = 0;
1597            overflows += 1;
1598        } else {
1599            *byte_ref += 1;
1600            return overflows;
1601        }
1602    }
1603
1604    overflows
1605}
1606
1607#[test]
1608fn greatest() {
1609    let path1 = Path::<3, 3, 6>::greatest();
1610
1611    assert!(path1.try_successor().is_none());
1612
1613    let path2 = Path::<4, 4, 16>::greatest();
1614    assert!(path2.try_successor().is_none());
1615
1616    let path3 = Path::<0, 4, 0>::greatest();
1617    assert!(path3.try_successor().is_none());
1618
1619    let path4 = Path::<4, 2, 6>::greatest();
1620    assert!(path4.try_successor().is_none())
1621}