precomputed_map/
store.rs

1use core::borrow::Borrow;
2use core::marker::PhantomData;
3use crate::seq::List;
4
5
6pub trait AsData {
7    type Data;
8    
9    fn as_data(&self) -> Self::Data;
10}
11
12pub trait MapStore<'data> {
13    type Key: 'data;
14    type Value: 'data;
15
16    const LEN: usize;
17    
18    fn get_key(&self, index: usize) -> Self::Key;
19    fn get_value(&self, index: usize) -> Self::Value;
20}
21
22pub trait AccessSeq<'data> {
23    type Item: 'data;
24    const LEN: usize;
25
26    fn index(&self, index: usize) -> Self::Item;
27}
28
29pub trait Searchable<'data>: MapStore<'data> {
30    fn search<Q>(&self, key: &Q) -> Option<Self::Value>
31    where
32        Self::Key: Borrow<Q>,
33        Q: Ord + ?Sized
34    ;
35}
36
37pub struct ConstSlice<'data, const O: usize, const L: usize, B: ?Sized> {
38    data: &'data B,
39    _phantom: PhantomData<([u8; O], [u8; L])>
40}
41
42pub struct Ordered<D>(pub D);
43
44impl<'data, const O: usize, const L: usize, B: ?Sized> ConstSlice<'data, O, L, B> {
45    pub const fn new(data: &'data B) -> Self {
46        ConstSlice { data, _phantom: PhantomData }
47    }
48}
49
50impl<
51    'data,
52    const B: usize,
53    const O: usize,
54    const N: usize,
55> AsData for ConstSlice<'data, O, N, [u8; B]> {
56    type Data = &'data [u8; N];
57    
58    #[inline]
59    fn as_data(&self) -> &'data [u8; N] {
60        self.data[O..][..N].try_into().unwrap()
61    }
62}
63
64impl<
65    'data,
66    const O: usize,
67    const N: usize,
68> AsData for ConstSlice<'data, O, N, str> {
69    type Data = &'data str;
70    
71    #[inline]
72    fn as_data(&self) -> &'data str {
73        self.data[O..][..N].try_into().unwrap()
74    }
75}
76
77impl<
78    'data,
79    const B: usize,
80    const O: usize,
81    const L: usize,
82> AccessSeq<'data> for ConstSlice<'data, O, L, [u8; B]> {
83    type Item = u8;
84    const LEN: usize = L;
85
86    #[inline]
87    fn index(&self, index: usize) -> Self::Item {
88        self.as_data()[index]
89    }
90}
91
92impl<'data, K> MapStore<'data> for K
93where
94    K: AccessSeq<'data>
95{
96    type Key = K::Item;
97    type Value = usize;
98
99    const LEN: usize = K::LEN;
100
101    #[inline]
102    fn get_key(&self, index: usize) -> Self::Key {
103        self.index(index)
104    }
105
106    #[inline]
107    fn get_value(&self, index: usize) -> Self::Value {
108        index
109    }
110}
111
112impl<'data, K, V> MapStore<'data> for (K, V)
113where
114    K: AccessSeq<'data>,
115    V: AccessSeq<'data>
116{
117    type Key = K::Item;
118    type Value = V::Item;
119
120    const LEN: usize = {
121        if K::LEN != V::LEN {
122            panic!();
123        }
124
125        K::LEN
126    };
127
128    #[inline]
129    fn get_key(&self, index: usize) -> Self::Key {
130        self.0.index(index)
131    }
132
133    #[inline]
134    fn get_value(&self, index: usize) -> Self::Value {
135        self.1.index(index)
136    }
137}
138
139impl<'data, M> MapStore<'data> for Ordered<M>
140where
141    M: MapStore<'data>
142{
143    type Key = M::Key;
144    type Value = M::Value;
145
146    const LEN: usize = M::LEN;
147
148    #[inline]
149    fn get_key(&self, index: usize) -> Self::Key {
150        self.0.get_key(index)
151    }
152
153    #[inline]
154    fn get_value(&self, index: usize) -> Self::Value {
155        self.0.get_value(index)
156    }
157}
158
159impl<'data, const N: usize, T> Searchable<'data> for Ordered<List<'data, N, T>>
160where
161    T: Copy
162{
163    fn search<Q>(&self, key: &Q) -> Option<Self::Value>
164    where
165        Self::Key: Borrow<Q>,
166        Q: Ord + ?Sized
167    {
168        self.0.0.binary_search_by(|t| Ord::cmp(t.borrow(), key)).ok()
169    }
170}
171
172impl<'data, const N: usize, K, V> Searchable<'data> for Ordered<(List<'data, N, K>, V)>
173where
174    K: Copy,
175    V: AccessSeq<'data>
176{
177    fn search<Q>(&self, key: &Q) -> Option<Self::Value>
178    where
179        Self::Key: Borrow<Q>,
180        Q: Ord + ?Sized
181    {
182        let index = self.0.0.0.binary_search_by(|t| Ord::cmp(t.borrow(), key)).ok()?;
183        Some(self.0.1.index(index))
184    }
185}
186
187pub struct MapIter<'iter, 'data, D> {
188    store: &'iter D,
189    next: usize,
190    _phantom: PhantomData<&'data D>
191}
192
193impl<'iter, 'data, D> MapIter<'iter, 'data, D> {
194    pub(super) const fn new(store: &'iter D) -> Self {
195        MapIter { store, next: 0, _phantom: PhantomData }
196    }
197}
198
199impl<'iter, 'data, D> Iterator for MapIter<'iter, 'data, D>
200where
201    D: MapStore<'data>
202{
203    type Item = (D::Key, D::Value);
204
205    fn next(&mut self) -> Option<Self::Item> {
206        if self.next < D::LEN {
207            let k = self.store.get_key(self.next);
208            let v = self.store.get_value(self.next);
209            self.next += 1;
210            Some((k, v))
211        } else {
212            None
213        }
214    }
215}
216
217impl<'iter, 'data, D> ExactSizeIterator for MapIter<'iter, 'data, D>
218where
219    D: MapStore<'data>
220{
221    fn len(&self) -> usize {
222        D::LEN
223    }
224}
225
226impl<'iter, 'data, D> Clone for MapIter<'iter, 'data, D> {
227    #[inline]
228    fn clone(&self) -> Self {
229        MapIter {
230            store: self.store,
231            next: self.next,
232            _phantom: PhantomData
233        }
234    }
235}