granular_id/
lib.rs

1//! This crate contains the type `GranularId`, which is a data type which can provide ID numbers in
2//! a sequential order, where between any two ID:s, there are infinitely many *more granular* ID:s.
3//! You can think of this as version numbers with an infinite granularity, so if there are versions
4//! 1 and 2, there are ID:s 1.1, 1.2, 1.3 etc in-between them. Additionally, in-between ID 1.1 and
5//! 1.2, there are infinitely many ID:s 1.1.1, 1.1.2 and so on.
6//!
7//! `GranularId`s is best used with any unsized integer type, where each component of the ID:s may
8//! range from the minimum bound to the maximum bound of that integer type. The `GranularId` that
9//! starts with the upper bound of the integer type is the very maximum `GranularId`. This means
10//! that, using `u8`, all these `GranularId<u8>`s exist, in increasing order:
11//! * `254`
12//! * `254.0`
13//! * `254.1`
14//! * `254.1.0`
15//! * `254.1.1`
16//! * `254.1.*`
17//! * ...
18//! * `254.2`
19//! * `254.3`
20//! * `255`
21//! `255` is the highest ID available of this type (i.e. there is no `255.0`, `255.1` etc), and is
22//! the upper bound for this type. This constraint is added so that there is an upper bound to the
23//! `GranularId<T>` type if `T` has an upper bound.
24//!
25//! Even though it is recommended to use unsized integers for ID components, any types conforming
26//! to the appropriate [`num_traits`](https://docs.rs/num-traits/latest/num_traits/index.html) may
27//! be used.
28//!
29//! You may also think of the ID:s as a tree structure, where `3` has the children `3.0`, `3.1` etc
30//! up to `3.T::max`, and `5.3` having the siblings `5.4`, `5.5`, `5.6` etc following it. For this
31//! reason, [`GranularId<T>::children`], [`GranularId<T>::next_siblings`],
32//! [`GranularId<T>::previous_siblings`] and [`GranularId<T>::all_siblings`], as well as
33//! [`GranularId<T>::parent`] exist. If you were to build a tree structure, you may have a
34//! [`root`](GranularId<T>::root) ID from which you assign all nodes living in the root ID:s from
35//! the children of that root, and in turn assign each child of each children an ID derived from its
36//! own ID. In that way, you are maintaining a total ordering of the children (assuming the
37//! component type is totally ordered) while being able to easily find the parent ID of any node.
38//! The [`root`](GranularId<T>::root) ID is a special ID since it doesn't have any components, and
39//! is always the lowest ID.
40
41use std::{cmp, fmt, iter::Iterator};
42
43pub use num_traits::bounds::{LowerBounded, UpperBounded};
44use num_traits::{Bounded, CheckedAdd, CheckedSub, One};
45
46/// The data type `GranularId` represents any ID which can have an arbitrary granularity,
47/// meaning that there is indefinitely many `GranularId`s in-between any two `GranularId`s. It is
48/// best used with unsized integer types such as `u8`, `u16`, `u32`, `u64` and `usize`, but may be
49/// used with other data types implementing the required
50/// [`num_traits`](https://docs.rs/num-traits/latest/num_traits/index.html) bounds.
51///
52/// An ID basically consists of multiple *components*
53#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
54pub struct GranularId<T> {
55    id: Vec<T>,
56}
57
58impl<T: fmt::Display> fmt::Display for GranularId<T> {
59    /// A `GranularId` is displayed similarly to a version string, where the `GranularId` created
60    /// from the vector `[1, 2, 3]` is displayed as `1.2.3`. If the `GranularId` is the root ID
61    /// (doesn't have any components), it is displayed as `<root>`.
62    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63        let mut iter = self.id.iter();
64        if let Some(x) = iter.next() {
65            write!(f, "{x}")?;
66            for x in iter {
67                write!(f, ".{x}")?;
68            }
69        } else {
70            write!(f, "<root>")?;
71        }
72        Ok(())
73    }
74}
75
76impl<T> PartialOrd for GranularId<T>
77where
78    T: Ord,
79{
80    /// Since `GranularId`s does have a total ordering if and only if its type has a total ordering,
81    /// this function never returns `None` and just returns the value [`GranularId<T>::cmp`] would
82    /// return
83    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
84        Some(self.cmp(other))
85    }
86}
87
88impl<T> Ord for GranularId<T>
89where
90    T: Ord,
91{
92    /// When comparing two [`GranularId`]s, their relative positioning is determined by its first
93    /// non-matching component. All ID:s starting with `1` is less than all ID:s starting with a `2`
94    /// and `1.2` is ordered before `1.2.0`. Here is an example of some ordered `GranularId`s:
95    ///
96    /// ```rust
97    /// use num_traits::bounds::LowerBounded;
98    /// use granular_id::GranularId;
99    /// let vec: Vec<GranularId<u8>> = vec![
100    ///     vec![1].into(),         // id 1
101    ///     vec![1, 0].into(),      // id 1.0
102    ///     vec![1, 1].into(),      // id 1.1
103    ///     vec![1, 1, 0].into(),   // id 1.1.0
104    ///     vec![1, 1, 1].into(),   // id 1.1.1
105    ///     vec![1, 1, 2].into(),   // id 1.1.2
106    ///     vec![1, 2].into(),      // id 1.2
107    ///     vec![2].into(),         // id 2
108    /// ];
109    /// let mut min = GranularId::min_value();
110    /// for id in vec {
111    ///     assert!(id > min);
112    ///     min = id;
113    /// }
114    /// ```
115    ///
116    /// For a [`GranularId`] to have a total ordering, the component type must also have a total
117    /// ordering.
118    fn cmp(&self, other: &Self) -> cmp::Ordering {
119        Iterator::zip(self.id.iter(), &other.id)
120            .map(|(a, b)| a.cmp(b))
121            .find(|x| *x != cmp::Ordering::Equal)
122            .unwrap_or_else(|| self.id.len().cmp(&other.id.len()))
123    }
124}
125
126impl<T> LowerBounded for GranularId<T> {
127    /// The lower bound for any [`GranularId`] (the smallest ID) is the empty ID which contains no
128    /// components.
129    fn min_value() -> Self {
130        Self { id: vec![] }
131    }
132}
133
134impl<T> UpperBounded for GranularId<T>
135where
136    T: UpperBounded,
137{
138    /// The upper bound for any [`GranularId`] (the largest ID) is the empty ID which contains one
139    /// component, containing the upper bound of the component type.
140    fn max_value() -> Self {
141        Self {
142            id: vec![T::max_value()],
143        }
144    }
145}
146
147impl<T> From<Vec<T>> for GranularId<T>
148where
149    T: PartialEq + UpperBounded,
150{
151    /// A vector of components may be turned into a `GranularId`. Keep in mind that the maximum
152    /// `GranularId` of any type `T` is the one containing just the component `T::max`, attempting
153    /// to convert any vector starting with `T::max` will result in the
154    /// [`upper bound`](GranularId<T>::max_value) `GranularId` for that type.
155    fn from(other: Vec<T>) -> Self {
156        if other.first().map_or(false, |x| x == &T::max_value()) {
157            Self {
158                id: vec![T::max_value()],
159            }
160        } else {
161            Self { id: other }
162        }
163    }
164}
165
166impl<T> From<&[T]> for GranularId<T>
167where
168    T: PartialEq + UpperBounded + Clone,
169{
170    /// A slice of components may be turned into a `GranularId`. Keep in mind that the maximum
171    /// `GranularId` of any type `T` is the one containing just the component `T::max`, attempting
172    /// to convert any vector starting with `T::max` will result in the
173    /// [`upper bound`](GranularId<T>::max_value) `GranularId` for that type.
174    fn from(other: &[T]) -> Self {
175        if other.first().map_or(false, |x| x == &T::max_value()) {
176            Self {
177                id: vec![T::max_value()],
178            }
179        } else {
180            Self { id: other.to_vec() }
181        }
182    }
183}
184
185impl<T> From<GranularId<T>> for Vec<T> {
186    /// Turns a `GranularId` into a vector of its components.
187    fn from(other: GranularId<T>) -> Vec<T> {
188        other.id
189    }
190}
191
192impl<T> GranularId<T>
193where
194    T: SequentialId,
195{
196    /// Gets all the siblings of this `GranularId`, ordered from the smallest sibling to the largest
197    /// sibling. This is all the `GranularId`s which starts the same as this `GranularId` but has
198    /// its last component changed.
199    ///
200    /// ```rust
201    /// use granular_id::GranularId;
202    /// let id = GranularId::from(vec![1u8, 2, 2]); // id 1.2.2
203    /// let mut all_siblings = id.all_siblings();
204    /// assert_eq!(all_siblings.next().unwrap(), vec![1, 2, 0].into()); // id 1.2.0
205    /// assert_eq!(all_siblings.next().unwrap(), vec![1, 2, 1].into()); // id 1.2.1
206    /// assert_eq!(all_siblings.next().unwrap(), vec![1, 2, 2].into()); // id 1.2.2
207    /// assert_eq!(all_siblings.next().unwrap(), vec![1, 2, 3].into()); // id 1.2.3
208    /// ```
209    #[must_use]
210    pub fn all_siblings(&self) -> SequentialIds<T>
211    where
212        T: LowerBounded,
213    {
214        let mut id = self.id.clone();
215        id.pop();
216        SequentialIds {
217            current: Some(T::min_value()),
218            base: id,
219        }
220    }
221
222    /// Gets all the next siblings of this `GranularId`, ordered from the smallest sibling larger
223    /// than this ID to the largest sibling. This is all the `GranularId`s which starts the same as
224    /// this `GranularId` but has its last component changed to any larger value.
225    ///
226    /// ```rust
227    /// use granular_id::GranularId;
228    /// let id = GranularId::from(vec![1u8, 2, 2]); // id 1.2.2
229    /// let mut next_siblings = id.next_siblings();
230    /// assert_eq!(next_siblings.next().unwrap(), vec![1, 2, 3].into()); // id 1.2.3
231    /// assert_eq!(next_siblings.next().unwrap(), vec![1, 2, 4].into()); // id 1.2.4
232    /// assert_eq!(next_siblings.next().unwrap(), vec![1, 2, 5].into()); // id 1.2.5
233    /// assert_eq!(next_siblings.next().unwrap(), vec![1, 2, 6].into()); // id 1.2.6
234    /// ```
235    #[must_use]
236    pub fn next_siblings(&self) -> SequentialIds<T>
237    where
238        T: CheckedAdd,
239    {
240        let mut id = self.id.clone();
241        let current = id.pop().and_then(|x| x.checked_add(&T::one()));
242        SequentialIds { current, base: id }
243    }
244
245    /// Gets all direct children of this `GranularId`, ordered from the smallest child (which is
246    /// larger than this ID, but smallest out of all children) to the largest child. This is all
247    /// the `GranularId`s which starts with this `GranularId` but has one additional component.
248    ///
249    /// ```rust
250    /// use granular_id::GranularId;
251    /// let id = GranularId::from(vec![1u8, 2]); // id 1.2
252    /// let mut children = id.children();
253    /// assert_eq!(children.next().unwrap(), vec![1, 2, 0].into()); // id 1.2.0
254    /// assert_eq!(children.next().unwrap(), vec![1, 2, 1].into()); // id 1.2.1
255    /// assert_eq!(children.next().unwrap(), vec![1, 2, 2].into()); // id 1.2.2
256    /// assert_eq!(children.next().unwrap(), vec![1, 2, 3].into()); // id 1.2.3
257    /// ```
258    #[must_use]
259    pub fn children(&self) -> SequentialIds<T>
260    where
261        T: LowerBounded,
262    {
263        SequentialIds {
264            current: Some(T::min_value()),
265            base: self.id.clone(),
266        }
267    }
268}
269
270impl<T> GranularId<T>
271where
272    T: BackSequentialId,
273{
274    /// Gets all the previous siblings of this `GranularId`, ordered from the largest sibling
275    /// smaller than this ID to the smallest sibling. This is all the `GranularId`s which starts the
276    /// same as this `GranularId` but has its last component changed to any smaller value.
277    ///
278    /// ```rust
279    /// use granular_id::GranularId;
280    /// let id = GranularId::from(vec![1u8, 2, 3]); // id 1.2.3
281    /// let mut previous_siblings = id.previous_siblings();
282    /// assert_eq!(previous_siblings.next().unwrap(), vec![1, 2, 2].into()); // id 1.2.2
283    /// assert_eq!(previous_siblings.next().unwrap(), vec![1, 2, 1].into()); // id 1.2.1
284    /// assert_eq!(previous_siblings.next().unwrap(), vec![1, 2, 0].into()); // id 1.2.0
285    /// assert_eq!(previous_siblings.next(), None); // No more smaller siblings
286    /// ```
287    #[must_use]
288    pub fn previous_siblings(&self) -> BackSequentialIds<T>
289    where
290        T: Bounded + One + Clone + CheckedSub,
291    {
292        let mut id = self.id.clone();
293        let current = id.pop().and_then(|x| x.checked_sub(&T::one()));
294        BackSequentialIds { current, base: id }
295    }
296}
297
298impl<T> GranularId<T> {
299    /// Checks whether this `GranularId` is the maximum value of this type. If it is, no
300    /// other larger `GranularId`s exist of the same type.
301    ///
302    /// ```rust
303    /// use granular_id::GranularId;
304    /// let not_max: GranularId<u8> = vec![254].into();
305    /// let max: GranularId<u8> = vec![255].into();
306    /// assert!(!not_max.is_max_value());
307    /// assert!(max.is_max_value());
308    /// ```
309    #[must_use]
310    pub fn is_max_value(&self) -> bool
311    where
312        T: UpperBounded + PartialEq,
313    {
314        self == &Self::max_value()
315    }
316
317    /// Gets the granularity of this `GranularId`, which is the number of components it contains,
318    /// or the "precision" it has
319    ///
320    /// ```rust
321    ///
322    /// use granular_id::GranularId;
323    /// let id: GranularId<u8> = vec![1, 2, 3, 4].into(); // id 1.2.3.4, granularity 4
324    /// assert_eq!(id.granularity(), 4);
325    /// // Its children should have granularity 5:
326    /// assert_eq!(id.children().next().unwrap().granularity(), 5);
327    /// ```
328    #[must_use]
329    pub fn granularity(&self) -> usize {
330        self.id.len()
331    }
332
333    /// Checks whether this `GranularId` is the root, which means not having any components.
334    ///
335    /// ```rust
336    /// use granular_id::GranularId;
337    /// let not_root: GranularId<u8> = vec![254].into();
338    /// let root: GranularId<u8> = vec![].into();
339    /// assert!(!not_root.is_root());
340    /// assert!(root.is_root());
341    /// ```
342    #[must_use]
343    pub fn is_root(&self) -> bool {
344        self.id.is_empty()
345    }
346
347    /// Turns this `GranularId` into its parent, that is, the same `GranularId` with the last
348    /// component removed. If this `GranularId` is the root (has no components), this function
349    /// returns the root. For a mutating version, see [`GranularId::pop`], and for a copying
350    /// version, see [`GranularId::parent`]. If this `GranularId` doesn't have any components (is
351    /// the root ID), this function returns `None` since the root ID doesn't have a parent.
352    ///
353    /// ```rust
354    /// use granular_id::GranularId;
355    /// let id: GranularId<u8> = vec![1, 2, 3].into(); // id 1.2.3
356    /// assert_eq!(id.into_parent(), Some(vec![1, 2].into())); // id 1.2
357    /// ```
358    #[must_use]
359    pub fn into_parent(mut self) -> Option<Self> {
360        if self.id.is_empty() {
361            return None;
362        }
363        self.id.pop();
364        Some(self)
365    }
366
367    /// Gets the parent of this `GranularId`, that is, the same `GranularId` with the last component
368    /// removed. If this `GranularId` doesn't have any components (is the root ID), this function
369    /// returns `None` since the root ID doesn't have a parent.
370    ///
371    /// ```rust
372    /// use granular_id::GranularId;
373    /// let id: GranularId<u8> = vec![1, 2, 3].into(); // id 1.2.3
374    /// assert_eq!(id.parent(), Some(vec![1, 2].into())); // id 1.2
375    /// ```
376    #[must_use]
377    pub fn parent(&self) -> Option<Self>
378    where
379        T: Clone,
380    {
381        if self.id.is_empty() {
382            return None;
383        }
384        let mut id = self.id.clone();
385        id.pop();
386        Some(Self { id })
387    }
388
389    /// Returns an iterator over the ancestors of this `GranularId`. The iterator will yield all the
390    /// ancestors, in order from the next-most parent until the root `GranularId`. This will give the
391    /// same results as iteratively calling [`GranularId::parent`]. This function consumes the
392    /// `GranularId`.
393    ///
394    ///```rust
395    /// use granular_id::GranularId;
396    /// let id: GranularId<u8> = vec![1, 2, 3].into(); // id 1.2.3
397    /// let mut ancestors = id.into_ancestors();
398    /// assert_eq!(ancestors.next(), Some(vec![1, 2].into())); // id 1.2
399    /// assert_eq!(ancestors.next(), Some(vec![1].into())); // id 1
400    /// assert_eq!(ancestors.next(), Some(vec![].into())); // root id
401    /// assert_eq!(ancestors.next(), None); // There are no more ancestors at this point
402    ///```
403    #[must_use]
404    pub fn into_ancestors(self) -> Ancestors<T> {
405        Ancestors {
406            current: Some(self),
407        }
408    }
409
410    /// Returns an iterator over the ancestors of this `GranularId`. The iterator will yield all the
411    /// ancestors, in order from the next-most parent until the root `GranularId`. This will give the
412    /// same results as iteratively calling [`GranularId::parent`].
413    ///
414    ///```rust
415    /// use granular_id::GranularId;
416    /// let id: GranularId<u8> = vec![1, 2, 3].into(); // id 1.2.3
417    /// let mut ancestors = id.ancestors();
418    /// assert_eq!(ancestors.next(), Some(vec![1, 2].into())); // id 1.2
419    /// assert_eq!(ancestors.next(), Some(vec![1].into())); // id 1
420    /// assert_eq!(ancestors.next(), Some(vec![].into())); // root id
421    /// assert_eq!(ancestors.next(), None); // There are no more parents at this point
422    ///```
423    #[must_use]
424    pub fn ancestors(&self) -> Ancestors<T>
425    where
426        T: Clone,
427    {
428        Ancestors {
429            current: Some(self.clone()),
430        }
431    }
432
433    /// Removes the last component of this `GranularId`. To get the parent of any `GranularId`
434    /// without mutating it, see [`GranularId::parent`]. The function returns the component popped,
435    /// akin to [`Vec::pop`], which is `None` if this `GranularId` doesn't have a parent. In that
436    /// case, this `GranularId` will remain unchanged as the root.
437    ///
438    /// ```rust
439    /// use granular_id::GranularId;
440    /// let mut id: GranularId<u8> = vec![1, 2, 3].into(); // id 1.2.3
441    /// assert_eq!(id.pop(), Some(3)); // popping the last component '3'
442    /// assert_eq!(id, vec![1, 2].into()); // id 1.2
443    /// ```
444    pub fn pop(&mut self) -> Option<T> {
445        self.id.pop()
446    }
447
448    /// Pushes a new component to the `GranularId`, adding it as a new last component. Since the
449    /// maximum bound for a `GranularId` of type `T` is `[T::max]`, if any component is pushed to
450    /// such an ID, the call doesn't do anything.
451    ///
452    /// ```rust
453    /// use granular_id::GranularId;
454    /// let mut id: GranularId<u8> = vec![1, 2, 3].into(); // id 1.2.3
455    /// id.push(4);
456    /// assert_eq!(id, vec![1, 2, 3, 4].into()); // id 1.2.3.4
457    /// ```
458    pub fn push(&mut self, component: T)
459    where
460        T: UpperBounded + PartialEq,
461    {
462        if self != &Self::max_value() {
463            self.id.push(component);
464        }
465    }
466
467    /// Makes a new `GranularId`, adding the given component as its new last component. Since the
468    /// maximum bound for a `GranularId` of type `T` is `[T::max]`, if any component is pushed to
469    /// such an ID, the call returns a plain copy of the original `GranularId`.
470    ///
471    /// ```rust
472    /// use granular_id::GranularId;
473    /// let mut id: GranularId<u8> = vec![1, 2, 3].into(); // id 1.2.3
474    /// assert_eq!(id.pushing(4), vec![1, 2, 3, 4].into()); // id 1.2.3.4
475    /// ```
476    #[must_use]
477    pub fn pushing(&self, component: T) -> Self
478    where
479        T: UpperBounded + PartialEq + Clone,
480    {
481        if self == &Self::max_value() {
482            self.clone()
483        } else {
484            let mut id = self.id.clone();
485            id.push(component);
486            Self { id }
487        }
488    }
489
490    /// Appends all components from another `GranularId` to this `GranularId`, adding them as a new
491    /// last components. Since the maximum bound for a `GranularId` of type `T` is `[T::max]`, if
492    /// any components is appended to such an ID, the call doesn't do anything.
493    ///
494    /// ```rust
495    /// use granular_id::GranularId;
496    /// let mut id: GranularId<u8> = vec![1, 2, 3].into(); // id 1.2.3
497    /// let id_2 = vec![4, 5, 6].into(); // id 4.5.6
498    /// id.append(id_2);
499    /// assert_eq!(id, vec![1, 2, 3, 4, 5, 6].into()); // id 1.2.3.4.5.6
500    /// ```
501    pub fn append(&mut self, mut other: GranularId<T>)
502    where
503        T: UpperBounded + PartialEq,
504    {
505        if self != &Self::max_value() {
506            self.id.append(&mut other.id);
507        }
508    }
509
510    /// Makes a new `GranularId`, appending all components from another `GranularId` to that
511    /// `GranularId`, adding them as a new last components. Since the maximum bound for a
512    /// `GranularId` of type `T` is `[T::max]`, if any components is appended to such an ID, the
513    /// call returns a copy of the original `GranularId`.
514    ///
515    /// ```rust
516    /// use granular_id::GranularId;
517    /// let mut id: GranularId<u8> = vec![1, 2, 3].into(); // id 1.2.3
518    /// let id_2 = vec![4, 5, 6].into(); // id 4.5.6
519    /// assert_eq!(id.appending(id_2), vec![1, 2, 3, 4, 5, 6].into()); // id 1.2.3.4.5.6
520    /// ```
521    #[must_use]
522    pub fn appending(&self, mut other: GranularId<T>) -> GranularId<T>
523    where
524        T: UpperBounded + PartialEq + Clone,
525    {
526        if self == &Self::max_value() {
527            self.clone()
528        } else {
529            let mut id = self.id.clone();
530            id.append(&mut other.id);
531            Self { id }
532        }
533    }
534
535    /// Appends all components from a `Vec` to this `GranularId`, adding them as a new
536    /// last components. Since the maximum bound for a `GranularId` of type `T` is `[T::max]`, if
537    /// any components is appended to such an ID, the call doesn't do anything.
538    ///
539    /// ```rust
540    /// use granular_id::GranularId;
541    /// let mut id: GranularId<u8> = vec![1, 2, 3].into(); // id 1.2.3
542    /// id.append_vec(vec![4, 5, 6]);
543    /// assert_eq!(id, vec![1, 2, 3, 4, 5, 6].into()); // id 1.2.3.4.5.6
544    /// ```
545    pub fn append_vec(&mut self, mut other: Vec<T>)
546    where
547        T: UpperBounded + PartialEq,
548    {
549        if self.id.is_empty() {
550            // If this is empty, replace the internal vec, making sure to use into() to not
551            // exceed max
552            let other_id: GranularId<T> = other.into();
553            self.id = other_id.id;
554        } else if self != &Self::max_value() {
555            self.id.append(&mut other);
556        }
557    }
558
559    /// Makes a new `GranularId`, appending all components from a `Vec` to that
560    /// `GranularId`, adding them as a new last components. Since the maximum bound for a
561    /// `GranularId` of type `T` is `[T::max]`, if any components is appended to such an ID, the
562    /// call returns a copy of the original `GranularId`.
563    ///
564    /// ```rust
565    /// use granular_id::GranularId;
566    /// let mut id: GranularId<u8> = vec![1, 2, 3].into(); // id 1.2.3
567    /// assert_eq!(id.appending_vec(vec![4, 5, 6]), vec![1, 2, 3, 4, 5, 6].into()); // id 1.2.3.4.5.6
568    /// ```
569    #[must_use]
570    pub fn appending_vec(&self, mut other: Vec<T>) -> GranularId<T>
571    where
572        T: UpperBounded + PartialEq + Clone,
573    {
574        if self.id.is_empty() {
575            other.into()
576        } else if self != &Self::max_value() {
577            let mut id = self.id.clone();
578            id.append(&mut other);
579            Self { id }
580        } else {
581            self.clone()
582        }
583    }
584
585    /// Gets the root `GranularId` of any type, that is, a `GranularId` without any components.
586    /// That `GranularId` is the smallest one of that type.
587    ///
588    /// ```rust
589    /// use granular_id::GranularId;
590    /// let id: GranularId<u8> = GranularId::root(); // id <root>
591    /// assert_eq!(Into::<Vec<u8>>::into(id), vec![]);
592    /// ```
593    #[must_use]
594    pub fn root() -> Self {
595        Self { id: vec![] }
596    }
597}
598
599impl<T> IntoIterator for GranularId<T> {
600    type Item = T;
601    type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
602
603    /// Turns this `GranularId` into an iterator over its components, consuming them.
604    fn into_iter(self) -> Self::IntoIter {
605        self.id.into_iter()
606    }
607}
608
609pub struct SequentialIds<T> {
610    current: Option<T>,
611    base: Vec<T>,
612}
613
614pub trait SequentialId: UpperBounded + One + Clone + PartialEq + Ord + CheckedAdd {}
615
616impl<T: UpperBounded + One + Clone + PartialEq + Ord + CheckedAdd> SequentialId for T {}
617
618impl<T> Iterator for SequentialIds<T>
619where
620    T: SequentialId,
621{
622    type Item = GranularId<T>;
623
624    fn next(&mut self) -> Option<Self::Item> {
625        if self.base.first().map_or(false, |x| x >= &T::max_value()) {
626            return None;
627        }
628
629        let x = self.current.as_ref()?;
630        let mut id = self.base.clone();
631        id.push(x.clone());
632        self.current = x.checked_add(&T::one());
633        Some(GranularId { id })
634    }
635}
636
637pub trait BackSequentialId: Bounded + One + Clone + CheckedSub {}
638
639impl<T: Bounded + One + Clone + CheckedSub> BackSequentialId for T {}
640
641pub struct BackSequentialIds<T> {
642    current: Option<T>,
643    base: Vec<T>,
644}
645
646impl<T> Iterator for BackSequentialIds<T>
647where
648    T: BackSequentialId,
649{
650    type Item = GranularId<T>;
651
652    fn next(&mut self) -> Option<Self::Item> {
653        let x = self.current.as_ref()?;
654        let mut id = self.base.clone();
655        id.push(x.clone());
656        self.current = x.checked_sub(&T::one());
657        Some(GranularId { id })
658    }
659}
660
661pub struct Ancestors<T> {
662    current: Option<GranularId<T>>,
663}
664
665impl<T> Iterator for Ancestors<T>
666where
667    T: Clone,
668{
669    type Item = GranularId<T>;
670
671    fn next(&mut self) -> Option<Self::Item> {
672        self.current = self.current.as_ref().and_then(GranularId::parent);
673        self.current.clone()
674    }
675}
676
677#[cfg(test)]
678mod tests {
679    use std::collections::HashMap;
680
681    use super::*;
682
683    #[test]
684    fn keys_in_hm() {
685        // Create a HM
686        let mut hm: HashMap<GranularId<u8>, &'static str> = HashMap::new();
687
688        // Create three sample keys
689        let id_1: GranularId<u8> = vec![1].into();
690        let id_1_1: GranularId<u8> = vec![1, 1].into();
691        let id_2: GranularId<u8> = vec![2].into();
692
693        // Inserting sample values
694        hm.insert(id_1.clone(), "abc");
695        hm.insert(id_1_1.clone(), "def");
696        hm.insert(id_2.clone(), "ghi");
697
698        // Checking that they work as expected
699        assert_eq!(hm.get(&id_1).unwrap(), &"abc");
700        assert_eq!(hm.get(&id_1_1).unwrap(), &"def");
701        assert_eq!(hm.get(&id_2).unwrap(), &"ghi");
702    }
703
704    #[test]
705    fn readme_example() {
706        // Create a new GranularId from a vec of u8 (id: 1.2.3)
707        let id: GranularId<u8> = vec![1, 2, 3].into();
708
709        // Get the parent ID (id: 1.2)
710        let parent = id.parent().unwrap();
711        assert_eq!(parent, vec![1, 2].into());
712
713        // Iterate over the following siblings of 1.2.3
714        let mut next_siblings = id.next_siblings();
715        // First one is 1.2.4
716        assert_eq!(next_siblings.next().unwrap(), vec![1, 2, 4].into());
717        // Then, 1.2.5, etc
718        assert_eq!(next_siblings.next().unwrap(), vec![1, 2, 5].into());
719        assert_eq!(next_siblings.next().unwrap(), vec![1, 2, 6].into());
720
721        // Get an iterator over childrens of 1.2.3
722        let mut children = id.children();
723        // First one is 1.2.3.0
724        assert_eq!(children.next().unwrap(), vec![1, 2, 3, 0].into());
725        // Then, 1.2.3.1, etc
726        assert_eq!(children.next().unwrap(), vec![1, 2, 3, 1].into());
727        assert_eq!(children.next().unwrap(), vec![1, 2, 3, 2].into());
728
729        // Each parent is always smaller than all of its children
730        assert!(parent < id);
731    }
732}