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}