Skip to main content

arctic/raw/key/sized/
array.rs

1//! Support for byte array keys (`[u8; N]`).
2
3use crate::raw::Key;
4use crate::raw::edge;
5use crate::raw::edge::Len as _;
6use crate::raw::edge::Meta as _;
7use crate::raw::key;
8use crate::raw::key::Byte;
9use crate::raw::key::Len as _;
10use crate::raw::key::Read as _;
11use crate::raw::key::boxed_slice;
12
13impl<const N: usize> Key for [u8; N] {
14    type Read<'k> = Reader<'k, N>;
15    type Write = Writer<N>;
16    type Borrowed = [u8; N];
17    type Insert<'k> = &'k Self;
18    type Edge = edge::Le;
19    type Len = Byte;
20
21    #[inline]
22    fn as_insert(&self) -> Self::Insert<'_> {
23        self
24    }
25
26    #[inline]
27    fn insert_as_read<'k>(insert: Self::Insert<'k>) -> Self::Read<'k>
28    where
29        Self: 'k,
30    {
31        Reader::from(insert)
32    }
33
34    #[inline]
35    fn insert_to_key<'k>(insert: Self::Insert<'k>) -> Self
36    where
37        Self: 'k,
38    {
39        *insert
40    }
41
42    #[inline]
43    unsafe fn write_as_insert<'k>(writer: &'k Self::Write) -> &'k Self::Borrowed
44    where
45        Self: 'k,
46    {
47        &writer.0
48    }
49}
50
51impl<const N: usize> key::Split for [u8; N] {
52    // NOTE: should split into ([u8; N - 1], u8) ideally, but can't
53    // use const generic expressions yet
54    fn split_last<'k>(key: &'k Self::Borrowed) -> (Self::Read<'k>, u8) {
55        const {
56            assert!(N > 0);
57        }
58
59        let (last, slice) = key.split_last().expect("Non-empty");
60        (Reader(boxed_slice::Reader::new_prefix(slice)), *last)
61    }
62}
63
64impl<'k, const N: usize> From<&'k [u8]> for Reader<'k, N> {
65    #[inline]
66    fn from(prefix: &'k [u8]) -> Self {
67        Reader(boxed_slice::Reader::from(prefix))
68    }
69}
70
71impl<'k, const N: usize> From<&'k str> for Reader<'k, N> {
72    #[inline]
73    fn from(prefix: &'k str) -> Self {
74        Self::from(prefix.as_bytes())
75    }
76}
77
78impl<'k, const N: usize, const M: usize> From<&'k [u8; N]> for Reader<'k, M> {
79    #[inline]
80    fn from(prefix: &'k [u8; N]) -> Self {
81        Self::from(prefix.as_slice())
82    }
83}
84
85#[doc(hidden)]
86#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
87pub struct Reader<'k, const N: usize>(pub(crate) boxed_slice::Reader<'k, ()>);
88
89impl<'k, const N: usize> key::Read for Reader<'k, N> {
90    const LEN: Option<Self::Len> = Some(Byte(N));
91    type Edge = edge::Le;
92    type Len = Byte;
93
94    fn len(&self) -> Self::Len {
95        self.0.len()
96    }
97
98    fn get_edge(
99        &self,
100        len: <ribbit::Packed<Self::Edge> as edge::Meta>::Len,
101    ) -> ribbit::Packed<Self::Edge> {
102        self.0.get_edge(len)
103    }
104
105    fn get_byte(&self, index: <ribbit::Packed<Self::Edge> as edge::Meta>::Len) -> Option<u8> {
106        self.0.get_byte(index.bytes())
107    }
108
109    fn match_prefix(&self, meta: <Self::Edge as ribbit::Pack>::Packed) -> Self::Len {
110        self.0.match_prefix(meta)
111    }
112
113    fn prefix(self, end: Self::Len) -> Self {
114        Self(self.0.prefix(end))
115    }
116
117    fn suffix(self, start: Self::Len) -> Self {
118        Self(self.0.suffix(start))
119    }
120
121    fn common_prefix(self, other: Self) -> Self {
122        Self(self.0.common_prefix(other.0))
123    }
124}
125
126#[doc(hidden)]
127#[repr(transparent)]
128#[derive(Debug)]
129pub struct Writer<const N: usize>(pub(super) [u8; N]);
130
131impl<const N: usize> Default for Writer<N> {
132    #[inline]
133    fn default() -> Self {
134        Self([0; N])
135    }
136}
137
138impl<'k, const N: usize> key::Write<Reader<'k, N>> for Writer<N> {
139    type Len = Byte;
140
141    #[inline]
142    fn new(prefix: Reader<'k, N>, key: ribbit::Packed<edge::Le>) -> (Self, Self::Len) {
143        let len = prefix.len() + key.len().into();
144        let mut buffer = [0u8; N];
145        buffer[..prefix.0.len().bytes()].copy_from_slice(prefix.0.as_slice());
146        buffer[prefix.0.len().bytes()..]
147            .iter_mut()
148            .zip(key)
149            .for_each(|(out, r#in)| {
150                *out = r#in;
151            });
152        (Writer(buffer), len)
153    }
154
155    #[inline]
156    fn replace(&mut self, start: Self::Len, node: u8, edge: ribbit::Packed<edge::Le>) -> Self::Len {
157        self.0[start.bytes()] = node;
158        self.0[start.bytes() + 1..]
159            .iter_mut()
160            .zip(edge)
161            .for_each(|(out, r#in)| {
162                *out = r#in;
163            });
164        start + Byte::BYTE + edge.len().into()
165    }
166}