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}