miniconf/
key.rs

1use core::{convert::Infallible, iter::Fuse};
2
3use serde::Serialize;
4
5use crate::{DescendError, Internal, KeyError, Schema};
6
7/// Convert a key into a node index given an internal node schema
8pub trait Key {
9    /// Convert the key `self` to a `usize` index
10    fn find(&self, internal: &Internal) -> Option<usize>;
11}
12
13impl<T: Key + ?Sized> Key for &T {
14    fn find(&self, internal: &Internal) -> Option<usize> {
15        (**self).find(internal)
16    }
17}
18
19impl<T: Key + ?Sized> Key for &mut T {
20    fn find(&self, internal: &Internal) -> Option<usize> {
21        (**self).find(internal)
22    }
23}
24
25/// Capability to yield and look up [`Key`]s
26pub trait Keys {
27    /// Look up the next key in a [`Internal`] and convert to `usize` index.
28    ///
29    /// This must be fused (like [`core::iter::FusedIterator`]).
30    fn next(&mut self, internal: &Internal) -> Result<usize, KeyError>;
31
32    /// Finalize the keys, ensure there are no more.
33    ///
34    /// This must be fused.
35    fn finalize(&mut self) -> Result<(), KeyError>;
36
37    /// Chain another `Keys` to this one.
38    fn chain<U: IntoKeys>(self, other: U) -> Chain<Self, U::IntoKeys>
39    where
40        Self: Sized,
41    {
42        Chain(self, other.into_keys())
43    }
44
45    /// Track depth
46    fn track(self) -> Track<Self>
47    where
48        Self: Sized,
49    {
50        Track {
51            inner: self,
52            depth: 0,
53        }
54    }
55
56    /// Track whether a leaf node is reached
57    fn short(self) -> Short<Self>
58    where
59        Self: Sized,
60    {
61        Short {
62            inner: self,
63            leaf: false,
64        }
65    }
66}
67
68impl<T: Keys + ?Sized> Keys for &mut T {
69    fn next(&mut self, internal: &Internal) -> Result<usize, KeyError> {
70        (**self).next(internal)
71    }
72
73    fn finalize(&mut self) -> Result<(), KeyError> {
74        (**self).finalize()
75    }
76}
77
78/// Be converted into a `Keys`
79pub trait IntoKeys {
80    /// The specific `Keys` implementor.
81    type IntoKeys: Keys;
82
83    /// Convert `self` into a `Keys` implementor.
84    fn into_keys(self) -> Self::IntoKeys;
85}
86
87/// Look up an `IntoKeys` in a `Schema` and transcode it.
88pub trait Transcode {
89    /// The possible error when transcoding.
90    ///
91    /// Use this to indicate no space or unencodable/invalid values
92    type Error;
93
94    /// Perform a node lookup of a `K: IntoKeys` on a `Schema` and transcode it.
95    ///
96    /// This modifies `self` such that afterwards `Self: IntoKeys` can be used on `M` again.
97    /// It returns a `Node` with node type and depth information.
98    ///
99    /// Returning `Err(ValueError::Absent)` indicates that there was insufficient
100    /// capacity and a key could not be encoded at the given depth.
101    fn transcode(
102        &mut self,
103        schema: &Schema,
104        keys: impl IntoKeys,
105    ) -> Result<(), DescendError<Self::Error>>;
106}
107
108/// Construct a fresh transcoding target from compact seed/config state.
109pub trait Seeded: Sized {
110    /// The configuration required to construct `Self`.
111    type Seed: Copy;
112
113    /// Default configuration for `Self`.
114    const DEFAULT_SEED: Self::Seed;
115
116    /// Construct a fresh transcoding target from the provided seed.
117    fn from_seed(seed: &Self::Seed) -> Self;
118}
119
120impl<T: Transcode + ?Sized> Transcode for &mut T {
121    type Error = T::Error;
122    fn transcode(
123        &mut self,
124        schema: &Schema,
125        keys: impl IntoKeys,
126    ) -> Result<(), DescendError<Self::Error>> {
127        (**self).transcode(schema, keys)
128    }
129}
130
131/// Track leaf node encounter
132///
133/// This records whether a leaf node has been reached during [`Keys`] and [`Transcode`].
134#[derive(Clone, Debug, Default, PartialEq, PartialOrd, Hash, Serialize)]
135pub struct Short<K> {
136    /// The inner Keys
137    inner: K,
138    /// The inner keys terminates at a leaf node
139    leaf: bool,
140}
141
142impl<K> Short<K> {
143    /// Create a new `Short`
144    pub fn new(inner: K) -> Self {
145        Self { inner, leaf: false }
146    }
147
148    /// Whether a leaf node as been encountered
149    pub fn leaf(&self) -> bool {
150        self.leaf
151    }
152
153    /// Borrow the inner `Keys`
154    pub fn inner(&self) -> &K {
155        &self.inner
156    }
157
158    /// Split into inner `Keys` and leaf node flag
159    pub fn into_inner(self) -> (K, bool) {
160        (self.inner, self.leaf)
161    }
162}
163
164impl<K: Keys> IntoKeys for &mut Short<K> {
165    type IntoKeys = Self;
166
167    fn into_keys(self) -> Self::IntoKeys {
168        self.leaf = false;
169        self
170    }
171}
172
173impl<K: Keys> Keys for Short<K> {
174    fn next(&mut self, internal: &Internal) -> Result<usize, KeyError> {
175        self.inner.next(internal)
176    }
177
178    fn finalize(&mut self) -> Result<(), KeyError> {
179        self.inner.finalize()?;
180        self.leaf = true;
181        Ok(())
182    }
183}
184
185impl<T: Transcode> Transcode for Short<T> {
186    type Error = T::Error;
187
188    fn transcode(
189        &mut self,
190        schema: &Schema,
191        keys: impl IntoKeys,
192    ) -> Result<(), DescendError<Self::Error>> {
193        self.leaf = false;
194        match self.inner.transcode(schema, keys) {
195            Err(DescendError::Key(KeyError::TooShort)) => Ok(()),
196            Ok(()) | Err(DescendError::Key(KeyError::TooLong)) => {
197                self.leaf = true;
198                Ok(())
199            }
200            ret => ret,
201        }
202    }
203}
204
205impl<T: Seeded> Seeded for Short<T> {
206    type Seed = T::Seed;
207    const DEFAULT_SEED: Self::Seed = T::DEFAULT_SEED;
208
209    fn from_seed(seed: &Self::Seed) -> Self {
210        Self::new(T::from_seed(seed))
211    }
212}
213
214/// Track key depth
215///
216/// This tracks the depth during [`Keys`] and [`Transcode`].
217#[derive(Clone, Debug, Default, PartialEq, PartialOrd, Hash, Serialize)]
218pub struct Track<K> {
219    /// The inner keys
220    inner: K,
221    /// The keys terminate at the given depth
222    depth: usize,
223}
224
225impl<K> Track<K> {
226    /// Create a new `Track`
227    pub fn new(inner: K) -> Self {
228        Self { inner, depth: 0 }
229    }
230
231    /// Whether a leaf node as been encountered
232    pub fn depth(&self) -> usize {
233        self.depth
234    }
235
236    /// Borrow the inner `Keys`
237    pub fn inner(&self) -> &K {
238        &self.inner
239    }
240
241    /// Split into inner `Keys` and leaf node flag
242    pub fn into_inner(self) -> (K, usize) {
243        (self.inner, self.depth)
244    }
245}
246
247impl<K: Keys> IntoKeys for &mut Track<K> {
248    type IntoKeys = Self;
249
250    fn into_keys(self) -> Self::IntoKeys {
251        self.depth = 0;
252        self
253    }
254}
255
256impl<K: Keys> Keys for Track<K> {
257    fn next(&mut self, internal: &Internal) -> Result<usize, KeyError> {
258        let k = self.inner.next(internal);
259        if k.is_ok() {
260            self.depth += 1;
261        }
262        k
263    }
264
265    fn finalize(&mut self) -> Result<(), KeyError> {
266        self.inner.finalize()
267    }
268}
269
270impl<T: Transcode> Transcode for Track<T> {
271    type Error = T::Error;
272
273    fn transcode(
274        &mut self,
275        schema: &Schema,
276        keys: impl IntoKeys,
277    ) -> Result<(), DescendError<Self::Error>> {
278        self.depth = 0;
279        let mut tracked = keys.into_keys().track();
280        let ret = self.inner.transcode(schema, &mut tracked);
281        self.depth = tracked.depth;
282        ret
283    }
284}
285
286impl<T: Seeded> Seeded for Track<T> {
287    type Seed = T::Seed;
288    const DEFAULT_SEED: Self::Seed = T::DEFAULT_SEED;
289
290    fn from_seed(seed: &Self::Seed) -> Self {
291        Self::new(T::from_seed(seed))
292    }
293}
294
295/// Shim to provide the bare lookup/Track/Short without transcoding target
296impl Transcode for () {
297    type Error = Infallible;
298    fn transcode(
299        &mut self,
300        schema: &Schema,
301        keys: impl IntoKeys,
302    ) -> Result<(), DescendError<Self::Error>> {
303        schema.descend(keys.into_keys(), |_, _| Ok(()))
304    }
305}
306
307impl Seeded for () {
308    type Seed = ();
309    const DEFAULT_SEED: Self::Seed = ();
310
311    fn from_seed(_: &Self::Seed) -> Self {}
312}
313
314/// [`Keys`]/[`IntoKeys`] for Iterators of [`Key`]
315#[derive(Debug, Clone)]
316#[repr(transparent)]
317pub struct KeysIter<T>(Fuse<T>);
318
319impl<T: Iterator> KeysIter<T> {
320    fn new(inner: T) -> Self {
321        Self(inner.fuse())
322    }
323}
324
325impl<T> Keys for KeysIter<T>
326where
327    T: Iterator,
328    T::Item: Key,
329{
330    fn next(&mut self, internal: &Internal) -> Result<usize, KeyError> {
331        let n = self.0.next().ok_or(KeyError::TooShort)?;
332        n.find(internal).ok_or(KeyError::NotFound)
333    }
334
335    fn finalize(&mut self) -> Result<(), KeyError> {
336        match self.0.next() {
337            Some(_) => Err(KeyError::TooLong),
338            None => Ok(()),
339        }
340    }
341}
342
343impl<T> IntoKeys for T
344where
345    T: IntoIterator,
346    <T::IntoIter as Iterator>::Item: Key,
347{
348    type IntoKeys = KeysIter<T::IntoIter>;
349
350    fn into_keys(self) -> Self::IntoKeys {
351        KeysIter::new(self.into_iter())
352    }
353}
354
355impl<T> IntoKeys for KeysIter<T>
356where
357    T: Iterator,
358    T::Item: Key,
359{
360    type IntoKeys = KeysIter<T>;
361
362    fn into_keys(self) -> Self::IntoKeys {
363        self
364    }
365}
366
367/// Concatenate two `Keys` of different types
368pub struct Chain<T, U>(T, U);
369
370impl<T: Keys, U: Keys> Keys for Chain<T, U> {
371    fn next(&mut self, internal: &Internal) -> Result<usize, KeyError> {
372        match self.0.next(internal) {
373            Err(KeyError::TooShort) => self.1.next(internal),
374            ret => ret,
375        }
376    }
377
378    fn finalize(&mut self) -> Result<(), KeyError> {
379        self.0.finalize().and_then(|_| self.1.finalize())
380    }
381}
382
383impl<T: Keys, U: Keys> IntoKeys for Chain<T, U> {
384    type IntoKeys = Self;
385
386    fn into_keys(self) -> Self::IntoKeys {
387        self
388    }
389}