1use super::super::branch_meta::BranchMeta;
8
9#[derive(#[automatically_derived]
impl<'a, T: ::core::fmt::Debug> ::core::fmt::Debug for ConstSlice<'a, T> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f, "ConstSlice",
"full_slice", &self.full_slice, "start", &self.start, "limit",
&&self.limit)
}
}Debug, #[automatically_derived]
impl<'a, T: ::core::marker::Copy> ::core::marker::Copy for ConstSlice<'a, T> {
}Copy, #[automatically_derived]
impl<'a, T: ::core::clone::Clone> ::core::clone::Clone for ConstSlice<'a, T> {
#[inline]
fn clone(&self) -> ConstSlice<'a, T> {
ConstSlice {
full_slice: ::core::clone::Clone::clone(&self.full_slice),
start: ::core::clone::Clone::clone(&self.start),
limit: ::core::clone::Clone::clone(&self.limit),
}
}
}Clone)]
13pub(crate) struct ConstSlice<'a, T> {
14 full_slice: &'a [T],
16 start: usize,
18 limit: usize,
20}
21
22impl<'a, T> ConstSlice<'a, T> {
23 pub const fn from_slice(other: &'a [T]) -> Self {
25 ConstSlice {
26 full_slice: other,
27 start: 0,
28 limit: other.len(),
29 }
30 }
31
32 pub const fn from_manual_slice(full_slice: &'a [T], start: usize, limit: usize) -> Self {
34 ConstSlice {
35 full_slice,
36 start,
37 limit,
38 }
39 }
40
41 pub const fn len(&self) -> usize {
43 self.limit - self.start
44 }
45
46 pub const fn get_or_panic(&self, index: usize) -> &T {
48 #[allow(clippy::indexing_slicing)] &self.full_slice[index + self.start]
50 }
51
52 #[cfg(test)]
54 pub const fn first(&self) -> Option<&T> {
55 if self.len() == 0 {
56 None
57 } else {
58 Some(self.get_or_panic(0))
60 }
61 }
62
63 pub const fn last(&self) -> Option<&T> {
65 if self.len() == 0 {
66 None
67 } else {
68 Some(self.get_or_panic(self.len() - 1))
70 }
71 }
72
73 #[cfg(test)]
75 pub const fn get_subslice_or_panic(
76 &self,
77 new_start: usize,
78 new_limit: usize,
79 ) -> ConstSlice<'a, T> {
80 assert!(new_start <= new_limit);
81 assert!(new_limit <= self.len());
82 ConstSlice {
83 full_slice: self.full_slice,
84 start: self.start + new_start,
85 limit: self.start + new_limit,
86 }
87 }
88
89 #[cfg(any(test, feature = "alloc"))]
91 #[allow(clippy::indexing_slicing)] pub fn as_slice(&self) -> &'a [T] {
93 &self.full_slice[self.start..self.limit]
94 }
95}
96
97impl<'a, T> From<&'a [T]> for ConstSlice<'a, T> {
98 fn from(other: &'a [T]) -> Self {
99 Self::from_slice(other)
100 }
101}
102
103#[derive(#[automatically_derived]
impl<const N : usize, T: ::core::fmt::Debug> ::core::fmt::Debug for
ConstArrayBuilder<N, T> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f,
"ConstArrayBuilder", "full_array", &self.full_array, "start",
&self.start, "limit", &&self.limit)
}
}Debug, #[automatically_derived]
impl<const N : usize, T: ::core::marker::Copy> ::core::marker::Copy for
ConstArrayBuilder<N, T> {
}Copy, #[automatically_derived]
impl<const N : usize, T: ::core::clone::Clone> ::core::clone::Clone for
ConstArrayBuilder<N, T> {
#[inline]
fn clone(&self) -> ConstArrayBuilder<N, T> {
ConstArrayBuilder {
full_array: ::core::clone::Clone::clone(&self.full_array),
start: ::core::clone::Clone::clone(&self.start),
limit: ::core::clone::Clone::clone(&self.limit),
}
}
}Clone)]
105pub(crate) struct ConstArrayBuilder<const N: usize, T> {
106 full_array: [T; N],
107 start: usize,
108 limit: usize,
109}
110
111impl<const N: usize, T: Default> Default for ConstArrayBuilder<N, T> {
112 fn default() -> Self {
113 Self::new_empty([(); N].map(|_| Default::default()), 0)
114 }
115}
116
117impl<const N: usize, T> ConstArrayBuilder<N, T> {
118 pub const fn new_empty(full_array: [T; N], cursor: usize) -> Self {
122 if !(cursor <= N) {
::core::panicking::panic("assertion failed: cursor <= N")
};assert!(cursor <= N);
123 Self {
124 full_array,
125 start: cursor,
126 limit: cursor,
127 }
128 }
129
130 pub const fn from_manual_slice(full_array: [T; N], start: usize, limit: usize) -> Self {
132 if !(start <= limit) {
::core::panicking::panic("assertion failed: start <= limit")
};assert!(start <= limit);
133 if !(limit <= N) { ::core::panicking::panic("assertion failed: limit <= N") };assert!(limit <= N);
134 Self {
135 full_array,
136 start,
137 limit,
138 }
139 }
140
141 pub const fn len(&self) -> usize {
143 self.limit - self.start
144 }
145
146 #[allow(dead_code)]
148 pub const fn is_empty(&self) -> bool {
149 self.len() == 0
150 }
151
152 pub const fn as_const_slice(&self) -> ConstSlice<'_, T> {
154 ConstSlice::from_manual_slice(&self.full_array, self.start, self.limit)
155 }
156
157 #[cfg(any(test, feature = "alloc"))]
159 pub fn as_slice(&self) -> &[T] {
160 &self.full_array[self.start..self.limit]
161 }
162}
163
164impl<const N: usize, T: Copy> ConstArrayBuilder<N, T> {
166 pub const fn const_build_or_panic(self) -> [T; N] {
169 if self.start != 0 || self.limit != N {
170 let actual_len = self.limit - self.start;
171 const PREFIX: &[u8; 31] = b"Buffer too large. Size needed: ";
172 let len_bytes: [u8; PREFIX.len() + crate::helpers::MAX_USIZE_LEN_AS_DIGITS] =
173 crate::helpers::const_fmt_int(*PREFIX, actual_len);
174 let Ok(len_str) = core::str::from_utf8(&len_bytes) else {
175 ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
176 };
177 { ::core::panicking::panic_display(&len_str); };panic!("{}", len_str);
178 }
179 self.full_array
180 }
181
182 #[allow(clippy::indexing_slicing)] pub const fn const_push_front_or_panic(mut self, value: T) -> Self {
185 if self.start == 0 {
186 { ::core::panicking::panic_fmt(format_args!("Buffer too small")); };panic!("Buffer too small");
187 }
188 self.start -= 1;
189 self.full_array[self.start] = value;
190 self
191 }
192
193 #[allow(clippy::indexing_slicing)] pub const fn const_extend_front_or_panic(mut self, other: ConstSlice<T>) -> Self {
196 if self.start < other.len() {
197 { ::core::panicking::panic_fmt(format_args!("Buffer too small")); };panic!("Buffer too small");
198 }
199 self.start -= other.len();
200 let mut i = self.start;
201 {
let mut i = 0;
while i < other.len() {
let byte = other.get_or_panic(i);
{ self.full_array[i] = *byte; i += 1; };
i += 1;
}
};const_for_each!(other, byte, {
202 self.full_array[i] = *byte;
203 i += 1;
204 });
205 self
206 }
207}
208
209impl<const N: usize> ConstArrayBuilder<N, u8> {
210 #[allow(clippy::indexing_slicing)] pub(crate) const fn const_bitor_assign_or_panic(mut self, index: usize, bits: u8) -> Self {
213 self.full_array[self.start + index] |= bits;
214 self
215 }
216}
217
218impl<const N: usize, T: Copy> ConstArrayBuilder<N, T> {
219 #[cfg(feature = "alloc")]
221 pub fn swap_or_panic(mut self, i: usize, j: usize) -> Self {
222 self.full_array.swap(self.start + i, self.start + j);
223 self
224 }
225}
226
227macro_rules! const_for_each {
233 ($safe_const_slice:expr, $item:tt, $inner:expr) => {{
234 let mut i = 0;
235 while i < $safe_const_slice.len() {
236 let $item = $safe_const_slice.get_or_panic(i);
238 $inner;
239 i += 1;
240 }
241 }};
242}
243
244pub(crate) use const_for_each;
245
246pub(crate) struct ConstLengthsStack<const K: usize> {
251 data: [Option<BranchMeta>; K],
252 idx: usize,
253}
254
255impl<const K: usize> core::fmt::Debug for ConstLengthsStack<K> {
256 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
257 self.as_slice().fmt(f)
258 }
259}
260
261impl<const K: usize> ConstLengthsStack<K> {
262 pub const fn new() -> Self {
264 Self {
265 data: [None; K],
266 idx: 0,
267 }
268 }
269
270 pub const fn is_empty(&self) -> bool {
272 self.idx == 0
273 }
274
275 #[must_use]
277 #[allow(clippy::indexing_slicing)] pub const fn push_or_panic(mut self, meta: BranchMeta) -> Self {
279 if self.idx >= K {
280 {
::core::panicking::panic_fmt(format_args!("AsciiTrie Builder: Need more stack (max K)"));
};panic!(concat!(
281 "AsciiTrie Builder: Need more stack (max ",
282 stringify!(K),
283 ")"
284 ));
285 }
286 self.data[self.idx] = Some(meta);
287 self.idx += 1;
288 self
289 }
290
291 pub const fn peek_or_panic(&self) -> BranchMeta {
294 if self.idx == 0 {
295 {
::core::panicking::panic_fmt(format_args!("AsciiTrie Builder: Attempted to peek from an empty stack"));
};panic!("AsciiTrie Builder: Attempted to peek from an empty stack");
296 }
297 self.get_or_panic(0)
298 }
299
300 #[allow(clippy::indexing_slicing)] const fn get_or_panic(&self, index: usize) -> BranchMeta {
303 if self.idx <= index {
304 {
::core::panicking::panic_fmt(format_args!("AsciiTrie Builder: Attempted to get too deep in a stack"));
};panic!("AsciiTrie Builder: Attempted to get too deep in a stack");
305 }
306 match self.data[self.idx - index - 1] {
307 Some(x) => x,
308 None => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
309 }
310 }
311
312 #[allow(clippy::indexing_slicing)] pub const fn pop_many_or_panic(
315 mut self,
316 len: usize,
317 ) -> (Self, ConstArrayBuilder<256, BranchMeta>) {
318 if true {
if !(len <= 256) {
::core::panicking::panic("assertion failed: len <= 256")
};
};debug_assert!(len <= 256);
319 let mut result = ConstArrayBuilder::new_empty([BranchMeta::default(); 256], 256);
320 let mut ix = 0;
321 loop {
322 if ix == len {
323 break;
324 }
325 let i = self.idx - ix - 1;
326 result = result.const_push_front_or_panic(match self.data[i] {
327 Some(x) => x,
328 None => {
::core::panicking::panic_fmt(format_args!("Not enough items in the ConstLengthsStack"));
}panic!("Not enough items in the ConstLengthsStack"),
329 });
330 ix += 1;
331 }
332 self.idx -= len;
333 (self, result)
334 }
335
336 fn as_slice(&self) -> &[Option<BranchMeta>] {
338 &self.data[0..self.idx]
339 }
340}
341
342impl<const K: usize> ConstArrayBuilder<K, BranchMeta> {
343 pub const fn map_to_ascii_bytes(&self) -> ConstArrayBuilder<K, u8> {
345 let mut result = ConstArrayBuilder::new_empty([0; K], K);
346 let self_as_slice = self.as_const_slice();
347 {
let mut i = 0;
while i < self_as_slice.len() {
let value = self_as_slice.get_or_panic(i);
{ result = result.const_push_front_or_panic(value.ascii); };
i += 1;
}
};const_for_each!(self_as_slice, value, {
348 result = result.const_push_front_or_panic(value.ascii);
349 });
350 result
351 }
352}