1use std::iter;
2use std::mem;
3use std::slice;
4
5#[derive(Debug, PartialEq, Eq, Ord, PartialOrd, Default, Copy, Clone)]
7struct Param<'k, 'v> {
8 key: &'k [u8],
9 value: &'v [u8],
10}
11
12impl<'k, 'v> Param<'k, 'v> {
13 fn key_str(&self) -> &'k str {
15 std::str::from_utf8(self.key).unwrap()
16 }
17
18 fn value_str(&self) -> &'v str {
19 std::str::from_utf8(self.value).unwrap()
20 }
21}
22
23#[derive(Debug, PartialEq, Eq, Ord, PartialOrd, Clone)]
43pub struct Params<'k, 'v> {
44 kind: ParamsKind<'k, 'v>,
45}
46
47const SMALL: usize = 3;
49
50#[derive(Debug, PartialEq, Eq, Ord, PartialOrd, Clone)]
51enum ParamsKind<'k, 'v> {
52 None,
53 Small([Param<'k, 'v>; SMALL], usize),
54 Large(Vec<Param<'k, 'v>>),
55}
56
57impl<'k, 'v> Params<'k, 'v> {
58 pub(crate) fn new() -> Self {
59 let kind = ParamsKind::None;
60 Self { kind }
61 }
62
63 pub fn len(&self) -> usize {
65 match &self.kind {
66 ParamsKind::None => 0,
67 ParamsKind::Small(_, len) => *len,
68 ParamsKind::Large(vec) => vec.len(),
69 }
70 }
71
72 pub(crate) fn truncate(&mut self, n: usize) {
73 match &mut self.kind {
74 ParamsKind::None => {}
75 ParamsKind::Small(_, len) => {
76 *len = n;
77 }
78 ParamsKind::Large(vec) => {
79 vec.truncate(n);
80 }
81 }
82 }
83
84 pub fn get(&self, key: impl AsRef<str>) -> Option<&'v str> {
86 let key = key.as_ref().as_bytes();
87
88 match &self.kind {
89 ParamsKind::None => None,
90 ParamsKind::Small(arr, len) => arr
91 .iter()
92 .take(*len)
93 .find(|param| param.key == key)
94 .map(Param::value_str),
95 ParamsKind::Large(vec) => vec
96 .iter()
97 .find(|param| param.key == key)
98 .map(Param::value_str),
99 }
100 }
101
102 pub fn iter(&self) -> ParamsIter<'_, 'k, 'v> {
104 ParamsIter::new(self)
105 }
106
107 pub fn is_empty(&self) -> bool {
109 match &self.kind {
110 ParamsKind::None => true,
111 ParamsKind::Small(_, len) => *len == 0,
112 ParamsKind::Large(vec) => vec.is_empty(),
113 }
114 }
115
116 pub(crate) fn push(&mut self, key: &'k [u8], value: &'v [u8]) {
118 #[cold]
119 fn drain_to_vec<T: Default>(len: usize, elem: T, arr: &mut [T; SMALL]) -> Vec<T> {
120 let mut vec = Vec::with_capacity(len + 1);
121 vec.extend(arr.iter_mut().map(mem::take));
122 vec.push(elem);
123 vec
124 }
125
126 let param = Param { key, value };
127 match &mut self.kind {
128 ParamsKind::None => {
129 self.kind = ParamsKind::Small([param, Param::default(), Param::default()], 1);
130 }
131 ParamsKind::Small(arr, len) => {
132 if *len == SMALL {
133 self.kind = ParamsKind::Large(drain_to_vec(*len, param, arr));
134 return;
135 }
136 arr[*len] = param;
137 *len += 1;
138 }
139 ParamsKind::Large(vec) => vec.push(param),
140 }
141 }
142
143 pub(crate) fn for_each_key_mut(&mut self, f: impl Fn((usize, &mut &'k [u8]))) {
145 match &mut self.kind {
146 ParamsKind::None => {}
147 ParamsKind::Small(arr, len) => arr
148 .iter_mut()
149 .take(*len)
150 .map(|param| &mut param.key)
151 .enumerate()
152 .for_each(f),
153 ParamsKind::Large(vec) => vec
154 .iter_mut()
155 .map(|param| &mut param.key)
156 .enumerate()
157 .for_each(f),
158 }
159 }
160}
161
162pub struct ParamsIter<'ps, 'k, 'v> {
164 kind: ParamsIterKind<'ps, 'k, 'v>,
165}
166
167impl<'ps, 'k, 'v> ParamsIter<'ps, 'k, 'v> {
168 fn new(params: &'ps Params<'k, 'v>) -> Self {
169 let kind = match ¶ms.kind {
170 ParamsKind::None => ParamsIterKind::None,
171 ParamsKind::Small(arr, len) => ParamsIterKind::Small(arr.iter().take(*len)),
172 ParamsKind::Large(vec) => ParamsIterKind::Large(vec.iter()),
173 };
174 Self { kind }
175 }
176}
177
178enum ParamsIterKind<'ps, 'k, 'v> {
179 None,
180 Small(iter::Take<slice::Iter<'ps, Param<'k, 'v>>>),
181 Large(slice::Iter<'ps, Param<'k, 'v>>),
182}
183
184impl<'ps, 'k, 'v> Iterator for ParamsIter<'ps, 'k, 'v> {
185 type Item = (&'k str, &'v str);
186
187 fn next(&mut self) -> Option<Self::Item> {
188 match self.kind {
189 ParamsIterKind::None => None,
190 ParamsIterKind::Small(ref mut iter) => {
191 iter.next().map(|p| (p.key_str(), p.value_str()))
192 }
193 ParamsIterKind::Large(ref mut iter) => {
194 iter.next().map(|p| (p.key_str(), p.value_str()))
195 }
196 }
197 }
198}
199
200#[cfg(test)]
201mod tests {
202 use super::*;
203
204 #[test]
205 fn no_alloc() {
206 assert_eq!(Params::new().kind, ParamsKind::None);
207 }
208
209 #[test]
210 fn heap_alloc() {
211 let vec = vec![
212 ("hello", "hello"),
213 ("world", "world"),
214 ("foo", "foo"),
215 ("bar", "bar"),
216 ("baz", "baz"),
217 ];
218
219 let mut params = Params::new();
220 for (key, value) in vec.clone() {
221 params.push(key.as_bytes(), value.as_bytes());
222 assert_eq!(params.get(key), Some(value));
223 }
224
225 match params.kind {
226 ParamsKind::Large(..) => {}
227 _ => panic!(),
228 }
229
230 assert!(params.iter().eq(vec.clone()));
231 }
232
233 #[test]
234 fn stack_alloc() {
235 let vec = vec![("hello", "hello"), ("world", "world"), ("baz", "baz")];
236
237 let mut params = Params::new();
238 for (key, value) in vec.clone() {
239 params.push(key.as_bytes(), value.as_bytes());
240 assert_eq!(params.get(key), Some(value));
241 }
242
243 match params.kind {
244 ParamsKind::Small(..) => {}
245 _ => panic!(),
246 }
247
248 assert!(params.iter().eq(vec.clone()));
249 }
250
251 #[test]
252 fn ignore_array_default() {
253 let params = Params::new();
254 assert!(params.get("").is_none());
255 }
256}