1use core::marker::PhantomData;
2use crate::equivalent::Comparable;
3
4pub trait AsData {
5 type Data: ?Sized;
6
7 fn as_data() -> &'static Self::Data;
8}
9
10pub trait AccessSeq {
11 type Item;
12 const LEN: usize;
13
14 fn index(index: usize) -> Option<Self::Item>;
15}
16
17pub trait Searchable: MapStore {
18 fn search<Q>(query: &Q) -> Option<usize>
19 where
20 Q: Comparable<Self::Key> + ?Sized;
21}
22
23pub trait MapStore {
24 type Key;
25 type Value;
26
27 const LEN: usize;
28
29 fn get_key(index: usize) -> Option<Self::Key>;
30 fn get_value(index: usize) -> Option<Self::Value>;
31}
32
33pub struct SliceData<
34 const O: usize,
35 const L: usize,
36 D
37>(PhantomData<([u8; O], [u8; L], D)>);
38
39impl<
40 const B: usize,
41 const O: usize,
42 const L: usize,
43 D: AsData<Data = [u8; B]>
44> AsData for SliceData<O, L, D> {
45 type Data = [u8; L];
46
47 #[inline(always)]
48 fn as_data() -> &'static Self::Data {
49 D::as_data()[O..][..L].try_into().unwrap()
50 }
51}
52
53impl<const B: usize, D> AccessSeq for D
54where
55 D: AsData<Data = [u8; B]>
56{
57 type Item = u8;
58 const LEN: usize = B;
59
60 #[inline(always)]
61 fn index(index: usize) -> Option<Self::Item> {
62 D::as_data().get(index).copied()
63 }
64}
65
66impl<K> MapStore for K
67where
68 K: AccessSeq
69{
70 type Key = K::Item;
71 type Value = usize;
72
73 const LEN: usize = K::LEN;
74
75 #[inline(always)]
76 fn get_key(index: usize) -> Option<Self::Key> {
77 K::index(index)
78 }
79
80 #[inline(always)]
81 fn get_value(index: usize) -> Option<Self::Value> {
82 debug_assert!(index < Self::LEN);
83
84 Some(index)
85 }
86}
87
88impl<K, V> MapStore for (K, V)
89where
90 K: AccessSeq,
91 V: AccessSeq
92{
93 type Key = K::Item;
94 type Value = V::Item;
95
96 const LEN: usize = {
97 if K::LEN != V::LEN {
98 panic!();
99 }
100
101 K::LEN
102 };
103
104 #[inline(always)]
105 fn get_key(index: usize) -> Option<Self::Key> {
106 K::index(index)
107 }
108
109 #[inline(always)]
110 fn get_value(index: usize) -> Option<Self::Value> {
111 V::index(index)
112 }
113}
114
115impl<K, V> Searchable for (K, V)
116where
117 K: Searchable + AccessSeq,
118 K: MapStore<Key = K::Item>,
119 V: AccessSeq,
120{
121 fn search<Q>(query: &Q) -> Option<usize>
122 where
123 Q: Comparable<K::Item> + ?Sized
124 {
125 K::search(query)
126 }
127}
128
129pub struct MapIter<'iter, D> {
130 next: usize,
131 _phantom: PhantomData<&'iter D>
132}
133
134impl<'iter, D> MapIter<'iter, D> {
135 pub(super) const fn new() -> Self {
136 MapIter { next: 0, _phantom: PhantomData }
137 }
138}
139
140impl<'iter, D> Iterator for MapIter<'iter, D>
141where
142 D: MapStore
143{
144 type Item = (D::Key, D::Value);
145
146 fn next(&mut self) -> Option<Self::Item> {
147 if self.next < D::LEN {
148 let k = D::get_key(self.next)?;
149 let v = D::get_value(self.next)?;
150 self.next += 1;
151 Some((k, v))
152 } else {
153 None
154 }
155 }
156}
157
158impl<'iter, D> ExactSizeIterator for MapIter<'iter, D>
159where
160 D: MapStore
161{
162 fn len(&self) -> usize {
163 D::LEN
164 }
165}
166
167impl<'iter, D> Clone for MapIter<'iter, D> {
168 #[inline]
169 fn clone(&self) -> Self {
170 MapIter {
171 next: self.next,
172 _phantom: PhantomData
173 }
174 }
175}