1use core::ffi::CStr;
4use core::fmt::Debug;
5use core::marker::PhantomData;
6
7use ribbit::u13;
8
9use crate::key::Terminated;
10use crate::raw::edge;
11use crate::raw::edge::Len as _;
12use crate::raw::key;
13use crate::raw::key::Byte;
14use crate::raw::key::Len as _;
15use crate::raw::key::Read as _;
16use crate::raw::key::r#unsized;
17use crate::raw::key::r#unsized::Terminate;
18use crate::raw::key::r#unsized::boxed_slice::BoxedSlice;
19
20pub unsafe trait Raw: 'static + AsRef<[u8]> + Debug {
25 #[expect(clippy::wrong_self_convention)]
26 fn into_boxed(&self) -> Box<Self>;
27}
28unsafe impl Raw for [u8] {
29 #[inline]
30 fn into_boxed(&self) -> Box<Self> {
31 Box::from(self)
32 }
33}
34unsafe impl Raw for str {
35 #[inline]
36 fn into_boxed(&self) -> Box<Self> {
37 Box::from(self)
38 }
39}
40
41#[repr(transparent)]
43#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
44pub struct Slice<I, R: ?Sized = [u8]> {
45 invariant: PhantomData<I>,
46 raw: R,
47}
48
49impl<I, R> Slice<I, R>
50where
51 I: r#unsized::Invariant,
52 R: ?Sized + Raw,
53{
54 pub fn new(key: &R) -> Result<&Self, I::Error> {
58 I::validate(key.as_ref())?;
59 Ok(unsafe { Self::new_unchecked(key) })
61 }
62}
63
64impl<I, R: ?Sized> Slice<I, R> {
65 #[inline]
69 pub const unsafe fn new_unchecked(key: &R) -> &Self {
70 unsafe { core::mem::transmute::<&R, &Self>(key) }
71 }
72
73 #[doc(hidden)]
75 #[inline]
76 pub const fn as_raw(&self) -> &R {
77 &self.raw
78 }
79}
80
81impl<I> Slice<I, str> {
82 #[inline]
84 pub const fn as_str(&self) -> &str {
85 self.as_raw()
86 }
87}
88
89impl<I> Slice<I, [u8]> {
90 #[inline]
92 pub const fn as_bytes(&self) -> &[u8] {
93 self.as_raw()
94 }
95}
96
97impl<I, R: ?Sized> AsRef<R> for Slice<I, R> {
98 #[inline]
99 fn as_ref(&self) -> &R {
100 self.as_raw()
101 }
102}
103
104impl<I, R> ToOwned for Slice<I, R>
105where
106 R: ?Sized + Raw,
107{
108 type Owned = BoxedSlice<I, R>;
109 fn to_owned(&self) -> Self::Owned {
110 unsafe { BoxedSlice::new_unchecked(self.as_raw().into_boxed()) }
111 }
112}
113
114impl<'a> From<&'a CStr> for &'a Slice<Terminated<0>, [u8]> {
115 fn from(str: &'a CStr) -> Self {
116 unsafe { Slice::new_unchecked(str.to_bytes_with_nul()) }
118 }
119}
120
121impl<'a, I, R> crate::Key for &'a Slice<I, R>
122where
123 I: r#unsized::Invariant,
124 R: ?Sized + Raw,
125{
126 type Borrowed = Slice<I, R>;
127
128 type Insert<'k>
129 = &'a Slice<I, R>
130 where
131 Self: 'k;
132
133 type Read<'k> = Reader<'k, I::Terminate>;
134 type Write = Writer<I>;
135 type Edge = edge::Slice<I::Terminate>;
136 type Len = Byte;
137
138 fn as_insert(&self) -> Self::Insert<'_> {
139 self
140 }
141
142 fn insert_as_read<'k>(insert: Self::Insert<'k>) -> Self::Read<'k>
143 where
144 Self: 'k,
145 {
146 Self::Read::from(insert)
147 }
148
149 fn insert_to_key<'k>(insert: Self::Insert<'k>) -> Self
150 where
151 Self: 'k,
152 {
153 insert
154 }
155
156 unsafe fn write_as_insert<'k>(writer: &'k Self::Write) -> Self::Insert<'k>
157 where
158 Self: 'k,
159 {
160 unsafe { writer.as_slice_unchecked() }
161 }
162}
163
164#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
165pub struct Reader<'k, T>(pub(crate) r#unsized::boxed_slice::Reader<'k, T>);
166
167impl<'k, I, R> From<&'k Slice<I, R>> for Reader<'k, I::Terminate>
168where
169 I: r#unsized::Invariant,
170 R: ?Sized + Raw,
171{
172 #[inline]
173 fn from(key: &'k Slice<I, R>) -> Self {
174 Self(r#unsized::boxed_slice::Reader::from(key))
175 }
176}
177
178impl<'k, T: Terminate> From<&'k [u8]> for Reader<'k, T> {
179 #[inline]
180 fn from(prefix: &'k [u8]) -> Self {
181 Self(r#unsized::boxed_slice::Reader::from(prefix))
182 }
183}
184
185impl<'k, T: Terminate> From<&'k str> for Reader<'k, T> {
186 #[inline]
187 fn from(prefix: &'k str) -> Self {
188 Self::from(prefix.as_bytes())
189 }
190}
191
192impl<'k, const N: usize, T: Terminate> From<&'k [u8; N]> for Reader<'k, T> {
193 #[inline]
194 fn from(prefix: &'k [u8; N]) -> Self {
195 Self::from(prefix.as_slice())
196 }
197}
198
199impl<T: Terminate> key::Read for Reader<'_, T> {
200 const LEN: Option<Byte> = None;
201
202 type Edge = edge::Slice<T>;
203 type Len = Byte;
204
205 fn len(&self) -> Self::Len {
206 self.0.len()
207 }
208
209 fn get_edge(
210 &self,
211 len: <ribbit::Packed<Self::Edge> as edge::Meta>::Len,
212 ) -> ribbit::Packed<Self::Edge> {
213 let min = len.bytes().min(self.0.len);
214 edge::Slice::new(self.0.as_non_null(), min)
215 .with_terminate(T::new(self.0.terminate.get() && len.bytes() > self.0.len))
216 }
217
218 fn get_byte(&self, index: u13) -> Option<u8> {
219 self.0.get_byte(index.bytes())
220 }
221
222 fn match_prefix(&self, meta: ribbit::Packed<edge::Slice<T>>) -> Self::Len {
223 let other = unsafe { meta.as_slice() };
224
225 let index = r#unsized::common_prefix(self.0.as_slice(), other);
226 let terminate = self.0.terminate.get()
227 && index == self.0.len
228 && index == other.len()
229 && meta.terminate().get();
230
231 Byte(index + terminate as usize)
232 }
233
234 #[inline]
235 fn prefix(self, end: Byte) -> Self {
236 Self(self.0.prefix(end))
237 }
238
239 #[inline]
240 fn suffix(self, start: Byte) -> Self {
241 Self(self.0.suffix(start))
242 }
243
244 #[inline]
245 fn common_prefix(self, other: Self) -> Self {
246 Self(self.0.common_prefix(other.0))
247 }
248}
249
250#[doc(hidden)]
251#[derive(Clone, Default, Debug)]
252pub struct Writer<I: r#unsized::Invariant> {
253 last: ribbit::Packed<edge::Slice<I::Terminate>>,
254 len: Byte,
255}
256
257impl<I: r#unsized::Invariant> Writer<I> {
258 unsafe fn as_slice_unchecked<'a, R: ?Sized>(&self) -> &'a Slice<I, R> {
259 let len_total = self.len.bytes();
260 let len_suffix = self.last.len().bytes();
262
263 validate!(len_total >= len_suffix);
264
265 let raw = I::Terminate::trim(unsafe {
266 core::slice::from_raw_parts(
267 self.last.as_ptr().byte_sub(len_total - len_suffix),
269 len_total,
270 )
271 });
272 unsafe { Slice::<I, R>::new_unchecked(core::mem::transmute_copy::<&[u8], &R>(&raw)) }
273 }
274}
275
276impl<I: r#unsized::Invariant> key::Write<Reader<'_, I::Terminate>> for Writer<I> {
277 type Len = Byte;
278
279 fn new(
280 prefix: Reader<'_, I::Terminate>,
281 key: ribbit::Packed<edge::Slice<I::Terminate>>,
282 ) -> (Self, Self::Len) {
283 let len = prefix.len() + key.len().into();
284 (Writer { last: key, len }, len)
285 }
286
287 fn replace(
288 &mut self,
289 start: Self::Len,
290 _: u8,
291 edge: ribbit::Packed<edge::Slice<I::Terminate>>,
292 ) -> Self::Len {
293 validate!(start <= self.len);
294 self.len = start + Byte::BYTE + edge.len().into();
295 self.last = edge;
296 self.len
297 }
298}