arctic/raw/key/
unsized.rs1use core::fmt;
4use core::fmt::Debug;
5use core::fmt::Display;
6use core::hash::Hash;
7
8pub(crate) mod boxed_slice;
9pub(crate) mod slice;
10
11pub unsafe trait Invariant:
19 Debug + Default + Hash + Eq + Ord + Send + Sync + 'static
20{
21 type Error: core::error::Error;
23
24 #[expect(private_bounds)]
27 type Terminate: Terminate;
28
29 fn validate(key: &[u8]) -> Result<(), Self::Error>;
31}
32
33#[derive(Copy, Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
39pub struct NonNull;
40
41#[derive(Clone, Debug)]
43pub struct NonNullError(usize);
44
45impl core::error::Error for NonNullError {}
46
47impl Display for NonNullError {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 write!(f, "Null byte at index ")?;
50 Display::fmt(&self.0, f)
51 }
52}
53
54unsafe impl Invariant for NonNull {
57 type Error = NonNullError;
58 type Terminate = bool;
59
60 fn validate(key: &[u8]) -> Result<(), Self::Error> {
61 if let Some(index) = key.iter().position(|byte| *byte == 0) {
62 return Err(NonNullError(index));
63 }
64
65 Ok(())
66 }
67}
68
69#[derive(Copy, Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
74pub struct Terminated<const TERMINATOR: u8>;
75
76#[derive(Clone, Debug)]
78pub enum TerminatedError {
79 Missing,
81 Internal(usize),
83}
84
85impl core::error::Error for TerminatedError {}
86
87impl Display for TerminatedError {
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89 match self {
90 Self::Missing => write!(f, "Missing terminator byte"),
91 Self::Internal(index) => {
92 write!(f, "Internal terminator byte at index {index}")
93 }
94 }
95 }
96}
97
98unsafe impl<const TERMINATOR: u8> Invariant for Terminated<TERMINATOR> {
100 type Error = TerminatedError;
101 type Terminate = ();
102
103 fn validate(key: &[u8]) -> Result<(), Self::Error> {
104 match key.iter().position(|byte| *byte == TERMINATOR) {
105 None => Err(TerminatedError::Missing),
106 Some(index) if index < key.len() - 1 => Err(TerminatedError::Internal(index)),
107 Some(_) => Ok(()),
108 }
109 }
110}
111
112#[inline]
114fn common_prefix(left: &[u8], right: &[u8]) -> usize {
115 core::iter::zip(left, right)
116 .position(|(l, r)| l != r)
117 .unwrap_or_else(|| left.len().min(right.len()))
118}
119
120#[inline]
122fn read_u64(slice: &[u8]) -> u64 {
123 if slice.len() >= 8 {
124 return unsafe { slice.as_ptr().cast::<u64>().read_unaligned() };
125 }
126
127 let mut buffer = [0u8; 8];
132 buffer[..slice.len()].copy_from_slice(slice);
133
134 u64::from_le_bytes(buffer)
135}
136
137mod seal {
138 pub trait Seal {}
139}
140
141pub(crate) trait Terminate:
142 Debug + Default + Eq + ribbit::Pack<Packed = Self> + Send + Sync + 'static + seal::Seal
143{
144 const FALSE: Self;
145 const TRUE: Self;
146
147 fn new(terminate: bool) -> Self;
148 fn get(self) -> bool;
149
150 fn try_compress(byte: u8) -> usize;
151
152 fn trim(slice: &[u8]) -> &[u8];
153}
154
155impl seal::Seal for () {}
156impl Terminate for () {
157 const FALSE: Self = ();
158 const TRUE: Self = ();
159
160 #[inline]
161 fn new(_: bool) -> Self {}
162
163 #[inline]
164 fn get(self) -> bool {
165 false
166 }
167
168 #[inline]
169 fn try_compress(_: u8) -> usize {
170 1
171 }
172
173 #[inline]
174 fn trim(slice: &[u8]) -> &[u8] {
175 slice
176 }
177}
178
179impl seal::Seal for bool {}
180impl Terminate for bool {
181 const FALSE: Self = false;
182 const TRUE: Self = true;
183
184 #[inline]
185 fn new(terminate: bool) -> Self {
186 terminate
187 }
188
189 #[inline]
190 fn get(self) -> bool {
191 self
192 }
193
194 #[inline]
195 fn try_compress(byte: u8) -> usize {
196 (byte > 0) as usize
197 }
198
199 #[inline]
200 fn trim(slice: &[u8]) -> &[u8] {
201 let (last, slice) = slice.split_last().expect("Non-empty");
202 validate_eq!(*last, 0);
203 slice
204 }
205}