zerotrie/builder/
slice_indices.rs1#[cfg(feature = "alloc")]
6use alloc::vec::Vec;
7
8const fn is_less_than(a: &[u8], b: &[u8]) -> bool {
10 let mut i = 0;
11 #[allow(clippy::indexing_slicing, reason = "bounds checked in while loop")]
12 while i < a.len() && i < b.len() {
13 if a[i] < b[i] {
14 return true;
15 }
16 if a[i] > b[i] {
17 return false;
18 }
19 i += 1;
20 }
21 a.len() < b.len()
22}
23
24pub(crate) const fn prefix_eq_or_panic(a: &[u8], b: &[u8], prefix_len: usize) -> bool {
30 let mut i = 0;
31 #[allow(clippy::indexing_slicing, reason = "documented panic")]
32 while i < prefix_len {
33 if a[i] != b[i] {
34 return false;
35 }
36 i += 1;
37 }
38 true
39}
40
41#[derive(#[automatically_derived]
impl<'a> ::core::marker::Copy for ByteSliceWithIndices<'a> { }Copy, #[automatically_derived]
impl<'a> ::core::clone::Clone for ByteSliceWithIndices<'a> {
#[inline]
fn clone(&self) -> ByteSliceWithIndices<'a> {
let _: ::core::clone::AssertParamIsClone<&'a [(&'a [u8], usize)]>;
let _: ::core::clone::AssertParamIsClone<&'a [(&'a str, usize)]>;
*self
}
}Clone)]
44pub(crate) enum ByteSliceWithIndices<'a> {
45 Bytes(&'a [(&'a [u8], usize)]),
46 Str(&'a [(&'a str, usize)]),
47}
48
49impl<'a> ByteSliceWithIndices<'a> {
50 pub const fn from_byte_slice(s: &'a [(&'a [u8], usize)]) -> Self {
51 Self::Bytes(s)
52 }
53
54 pub const fn from_str_slice(s: &'a [(&'a str, usize)]) -> Self {
55 Self::Str(s)
56 }
57
58 pub const fn len(&self) -> usize {
59 match self {
60 Self::Bytes(s) => s.len(),
61 Self::Str(s) => s.len(),
62 }
63 }
64
65 #[allow(clippy::indexing_slicing, reason = "documented")]
71 pub const fn get_or_panic(&self, index: usize) -> (&'a [u8], usize) {
72 match self {
73 Self::Bytes(s) => s[index],
74 Self::Str(s) => {
75 let (key, value) = s[index];
76 (key.as_bytes(), value)
77 }
78 }
79 }
80
81 pub const fn last(&self) -> Option<(&'a [u8], usize)> {
82 if self.len() == 0 {
83 None
84 } else {
85 Some(self.get_or_panic(self.len() - 1))
86 }
87 }
88
89 #[cfg(feature = "alloc")]
90 pub fn to_vec_u8(self) -> Vec<(&'a [u8], usize)> {
91 match self {
92 Self::Bytes(s) => s.to_vec(),
93 Self::Str(s) => s.iter().map(|(k, v)| (k.as_bytes(), *v)).collect(),
94 }
95 }
96
97 pub const fn is_sorted(self) -> bool {
98 let mut i = 0;
99 let mut prev: Option<&'a [u8]> = None;
100
101 while i < self.len() {
102 let (ascii_str, _) = self.get_or_panic(i);
103 match prev {
104 None => (),
105 Some(prev) => {
106 if !is_less_than(prev, ascii_str) {
107 return false;
108 }
109 }
110 };
111 prev = Some(ascii_str);
112 i += 1;
113 }
114 true
115 }
116
117 #[cfg(feature = "alloc")]
118 pub fn is_all_ascii(&self) -> bool {
119 match self {
120 Self::Bytes(s) => s
121 .iter()
122 .all(|(slice, _)| slice.iter().all(|c| c.is_ascii())),
123 Self::Str(s) => s
124 .iter()
125 .all(|(slice, _)| slice.as_bytes().iter().all(|c| c.is_ascii())),
126 }
127 }
128}