Skip to main content

syntree/
flavor.rs

1//! Trait for defining the flavor of a syntree.
2
3use core::ops::DerefMut;
4
5use crate::index::{Index, Length, TreeIndex};
6use crate::pointer::{Pointer, Width};
7
8/// Storage being used in a tree.
9pub trait Storage<T>
10where
11    Self: Sized + DerefMut<Target = [T]>,
12{
13    /// A storage error.
14    type Error: 'static;
15
16    /// Empty storage.
17    const EMPTY: Self;
18
19    /// Construct storage with the given capacity.
20    fn with_capacity(capacity: usize) -> Result<Self, Self::Error>;
21
22    /// Get the capacity of the underlying storage.
23    fn capacity(&self) -> usize;
24
25    /// Push an item into storage.
26    fn push(&mut self, item: T) -> Result<(), Self::Error>;
27}
28
29#[cfg(feature = "alloc")]
30impl<T> Storage<T> for alloc::vec::Vec<T> {
31    type Error = core::convert::Infallible;
32
33    const EMPTY: Self = alloc::vec::Vec::new();
34
35    #[inline]
36    fn with_capacity(capacity: usize) -> Result<Self, Self::Error> {
37        Ok(alloc::vec::Vec::with_capacity(capacity))
38    }
39
40    #[inline]
41    fn capacity(&self) -> usize {
42        alloc::vec::Vec::capacity(self)
43    }
44
45    #[inline]
46    fn push(&mut self, item: T) -> Result<(), Self::Error> {
47        alloc::vec::Vec::push(self, item);
48        Ok(())
49    }
50}
51
52/// Declare a new flavor.
53///
54/// The associated types are declared in this order, and all but `Index` are
55/// optional:
56/// * `type Index = ..;` the [Index] used for spans.
57/// * `type Width = ..;` the [Width] which bounds pointers, defaults to `usize`.
58/// * `type Error = ..;` the error raised by storage, defaults to
59///   [`Infallible`].
60/// * `type Storage<T> = ..;` the [Storage] used for tree data, defaults to
61///   `Vec<T>` (or [`EmptyVec<T>`] without the `alloc` feature).
62/// * `type Indexes = ..;` the [Storage] of [`TreeIndex<Self>`], defaults to
63///   `Vec<TreeIndex<Self>>` (or [`EmptyVec`] without the `alloc` feature),
64///   regardless of `Storage`.
65///
66/// The `Error` of both `Storage` and `Indexes` must be the flavor's `Error`,
67/// so a flavor with a custom `Error` needs to declare both of them. Errors
68/// raised by storage are reported as [`Error::Flavor`].
69///
70/// [`Infallible`]: core::convert::Infallible
71/// [`EmptyVec<T>`]: crate::EmptyVec
72/// [`EmptyVec`]: crate::EmptyVec
73/// [`Error::Flavor`]: crate::Error::Flavor
74///
75/// # Examples
76///
77/// ```
78/// use syntree::{Empty, EmptyVec, TreeIndex};
79///
80/// syntree::flavor! {
81///     struct FlavorEmpty {
82///         type Index = Empty;
83///         type Indexes = EmptyVec<TreeIndex<Self>>;
84///     }
85/// }
86///
87/// syntree::flavor! {
88///     struct FlavorU32 {
89///         type Index = u32;
90///         type Width = u32;
91///     }
92/// }
93/// ```
94///
95/// A flavor with custom fallible storage:
96///
97/// ```
98/// use core::ops::{Deref, DerefMut};
99/// use syntree::{Builder, Error, Storage, TreeIndex};
100///
101/// #[derive(Debug, PartialEq)]
102/// struct Full;
103///
104/// /// Storage which holds at most one item.
105/// struct One<T>(Option<T>);
106///
107/// impl<T> Deref for One<T> {
108///     type Target = [T];
109///
110///     fn deref(&self) -> &[T] {
111///         self.0.as_slice()
112///     }
113/// }
114///
115/// impl<T> DerefMut for One<T> {
116///     fn deref_mut(&mut self) -> &mut [T] {
117///         self.0.as_mut_slice()
118///     }
119/// }
120///
121/// impl<T> Storage<T> for One<T> {
122///     type Error = Full;
123///
124///     const EMPTY: Self = One(None);
125///
126///     fn with_capacity(capacity: usize) -> Result<Self, Full> {
127///         if capacity > 1 {
128///             return Err(Full);
129///         }
130///
131///         Ok(One(None))
132///     }
133///
134///     fn capacity(&self) -> usize {
135///         1
136///     }
137///
138///     fn push(&mut self, item: T) -> Result<(), Full> {
139///         if self.0.is_some() {
140///             return Err(Full);
141///         }
142///
143///         self.0 = Some(item);
144///         Ok(())
145///     }
146/// }
147///
148/// syntree::flavor! {
149///     struct FlavorOne {
150///         type Index = u32;
151///         type Error = Full;
152///         type Storage<T> = One<T>;
153///         type Indexes = One<TreeIndex<Self>>;
154///     }
155/// }
156///
157/// let mut tree: Builder<_, FlavorOne> = Builder::new_with();
158/// tree.token("a", 1)?;
159/// assert_eq!(tree.token("b", 1), Err(Error::Flavor(Full)));
160/// # Ok::<_, Error<Full>>(())
161/// ```
162#[macro_export]
163macro_rules! flavor {
164    (
165        $(#[doc = $doc:literal])*
166        $vis:vis struct $ty:ident {
167            type Index = $index:ty;
168            $(type Width = $width:ty;)?
169            $(type Error = $error:ty;)?
170            $(type Storage<$t:ident> = $storage:ty;)?
171            $(type Indexes = $indexes:ty;)?
172        }
173    ) => {
174        $(#[doc = $doc])*
175        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
176        #[non_exhaustive]
177        $vis struct $ty;
178
179        impl $crate::Flavor for $ty {
180            type Error = $crate::flavor!(@error $($error)*);
181            type Index = $index;
182            type Length = <$index as $crate::Index>::Length;
183            type Width = $crate::flavor!(@width $($width)*);
184            type Pointer = $crate::flavor!(@pointer $($width)*);
185            $crate::flavor!(@storage $($t $storage)*);
186            type Indexes = $crate::flavor!(@indexes $($indexes)*);
187        }
188    };
189
190    (@error $ty:ty) => { $ty };
191    (@error) => { ::core::convert::Infallible };
192    (@width $ty:ty) => { $ty };
193    (@width) => { usize };
194    (@pointer $ty:ty) => { <$ty as $crate::pointer::Width>::Pointer };
195    (@pointer) => { <usize as $crate::pointer::Width>::Pointer };
196    (@storage $t:ident $ty:ty) => { type Storage<$t> = $ty; };
197    (@storage) => { type Storage<T> = $crate::macro_support::Vec<T>; };
198    (@indexes $ty:ty) => { $ty };
199    (@indexes) => { $crate::macro_support::DefaultIndexes<Self> };
200}
201
202flavor! {
203    /// The default flavor of a tree.
204    ///
205    /// This corresponds to a `u32` index with a `usize` width.
206    pub struct FlavorDefault {
207        type Index = u32;
208        type Width = usize;
209    }
210}
211
212/// The flavor of a tree.
213///
214/// This should not be implemented directly, instead see the [flavor!] macro.
215///
216/// The Index associated type is constrained by the [Index] trait, and
217/// determines the numerical bounds of [spans] the tree.
218///
219/// The `Width` associated type determines the bounds of pointers in the tree
220/// through the [Width] trait, this decides how many elements that can be stored
221/// in the tree.
222///
223/// [spans]: crate::Span
224pub trait Flavor {
225    /// The error raised by the type of the tree.
226    type Error;
227    /// The type of an index used by a tree.
228    type Index: Index<Length = Self::Length>;
229    /// The length used in the flavor.
230    type Length: Length;
231    /// The width used in the flavor.
232    type Width: Width<Pointer = Self::Pointer>;
233    /// The pointer in use.
234    type Pointer: Pointer;
235    /// The storage type used in the tree.
236    type Storage<T>: Storage<T, Error = Self::Error>;
237    /// How indexes are stored in the tree.
238    type Indexes: Storage<TreeIndex<Self>, Error = Self::Error>;
239}