serde_querystring/parsers/
delimiter.rs1use std::{borrow::Cow, collections::BTreeMap};
2
3use crate::decode::{parse_bytes, Reference};
4
5struct Key<'a>(&'a [u8]);
6
7impl<'a> Key<'a> {
8 fn parse(slice: &'a [u8]) -> Self {
9 let mut index = 0;
10 while index < slice.len() {
11 match slice[index] {
12 b'&' | b'=' => break,
13 _ => index += 1,
14 }
15 }
16
17 Self(&slice[..index])
18 }
19
20 fn len(&self) -> usize {
21 self.0.len()
22 }
23
24 fn decode<'s>(&self, scratch: &'s mut Vec<u8>) -> Reference<'a, 's, [u8]> {
25 parse_bytes(self.0, scratch)
26 }
27}
28
29struct Value<'a>(&'a [u8]);
30
31impl<'a> Value<'a> {
32 fn decode<'s>(&self, scratch: &'s mut Vec<u8>) -> Reference<'a, 's, [u8]> {
33 parse_bytes(self.0, scratch)
34 }
35}
36
37#[derive(Default)]
38struct Values<'a>(&'a [u8]);
39
40impl<'a> Values<'a> {
41 fn parse(slice: &'a [u8]) -> Option<Self> {
42 if *slice.first()? == b'&' {
43 return None;
44 }
45
46 let mut index = 1;
47 while index < slice.len() {
48 match slice[index] {
49 b'&' => break,
50 _ => index += 1,
51 }
52 }
53
54 Some(Self(&slice[1..index]))
55 }
56
57 fn len(&self) -> usize {
58 self.0.len()
59 }
60
61 fn values(&self, delimiter: u8) -> impl Iterator<Item = Value<'a>> {
62 self.0.split(move |c| *c == delimiter).map(Value)
63 }
64
65 fn decode_to<'s>(&self, scratch: &'s mut Vec<u8>) -> Reference<'a, 's, [u8]> {
66 parse_bytes(self.0, scratch)
67 }
68}
69
70struct Pair<'a>(Key<'a>, Option<Values<'a>>);
71
72impl<'a> Pair<'a> {
73 fn parse(slice: &'a [u8]) -> Self {
74 let key = Key::parse(slice);
75 let value = Values::parse(&slice[key.len()..]);
76
77 Self(key, value)
78 }
79
80 fn skip_len(&self) -> usize {
84 match &self.1 {
85 Some(v) => self.0.len() + v.len() + 2,
86 None => self.0.len() + 1,
87 }
88 }
89}
90
91pub struct DelimiterQS<'a> {
120 pairs: BTreeMap<Cow<'a, [u8]>, Pair<'a>>,
121 delimiter: u8,
122}
123
124impl<'a> DelimiterQS<'a> {
125 pub fn parse(slice: &'a [u8], delimiter: u8) -> Self {
127 let mut pairs: BTreeMap<Cow<'a, [u8]>, Pair<'a>> = BTreeMap::new();
128 let mut scratch = Vec::new();
129
130 let mut index = 0;
131
132 while index < slice.len() {
133 let pair = Pair::parse(&slice[index..]);
134 index += pair.skip_len();
135
136 let decoded_key = pair.0.decode(&mut scratch);
137
138 if let Some(old_pair) = pairs.get_mut(decoded_key.as_ref()) {
139 *old_pair = pair;
140 } else {
141 pairs.insert(decoded_key.into_cow(), pair);
142 }
143 }
144
145 Self { pairs, delimiter }
146 }
147
148 pub fn keys(&self) -> Vec<&Cow<'a, [u8]>> {
150 self.pairs.keys().collect()
151 }
152
153 pub fn values(&self, key: &'a [u8]) -> Option<Option<Vec<Cow<'a, [u8]>>>> {
161 let delimiter = self.delimiter;
162 let mut scratch = Vec::new();
163
164 Some(self.pairs.get(key)?.1.as_ref().map(|values| {
165 values
166 .values(delimiter)
167 .map(|v| v.decode(&mut scratch).into_cow())
168 .collect()
169 }))
170 }
171
172 pub fn value(&self, key: &'a [u8]) -> Option<Option<Cow<'a, [u8]>>> {
180 let mut scratch = Vec::new();
181
182 Some(
183 self.pairs
184 .get(key)?
185 .1
186 .as_ref()
187 .map(|values| values.decode_to(&mut scratch).into_cow()),
188 )
189 }
190}
191
192#[cfg(feature = "serde")]
193mod de {
194 use _serde::Deserialize;
195
196 use crate::de::{
197 Error, QSDeserializer,
198 __implementors::{DecodedSlice, IntoRawSlices, RawSlice},
199 };
200
201 use super::DelimiterQS;
202
203 impl<'a> DelimiterQS<'a> {
204 pub fn deserialize<T: Deserialize<'a>>(self) -> Result<T, Error> {
206 T::deserialize(QSDeserializer::new(self.into_iter()))
207 }
208
209 pub(crate) fn into_iter(
210 self,
211 ) -> impl Iterator<Item = (DecodedSlice<'a>, SeparatorValues<'a>)> {
212 let delimiter = self.delimiter;
213 self.pairs.into_iter().map(move |(key, pair)| {
214 (
215 DecodedSlice(key),
216 SeparatorValues::from_slice(pair.1.map(|v| v.0).unwrap_or_default(), delimiter),
217 )
218 })
219 }
220 }
221
222 pub(crate) struct SeparatorValues<'a> {
223 slice: &'a [u8],
224 delimiter: u8,
225 }
226
227 impl<'a> SeparatorValues<'a> {
228 fn from_slice(slice: &'a [u8], delimiter: u8) -> Self {
229 Self { slice, delimiter }
230 }
231 }
232
233 impl<'a> IntoRawSlices<'a> for SeparatorValues<'a> {
234 type SizedIterator = SizedValuesIterator<'a>;
235
236 type UnSizedIterator = SizedValuesIterator<'a>;
237
238 #[inline]
239 fn into_sized_iterator(self, size: usize) -> Result<Self::SizedIterator, crate::de::Error> {
240 Ok(SizedValuesIterator::new(
241 self.slice,
242 self.delimiter,
243 Some(size),
244 ))
245 }
246
247 #[inline]
248 fn into_unsized_iterator(self) -> Self::UnSizedIterator {
249 SizedValuesIterator::new(self.slice, self.delimiter, None)
250 }
251
252 #[inline]
253 fn into_single_slice(self) -> RawSlice<'a> {
254 RawSlice(self.slice)
255 }
256 }
257
258 pub struct SizedValuesIterator<'a> {
259 slice: &'a [u8],
260 delimiter: u8,
261 remaining: Option<usize>,
262 index: usize,
263 }
264
265 impl<'a> SizedValuesIterator<'a> {
266 fn new(slice: &'a [u8], delimiter: u8, size: Option<usize>) -> Self {
267 Self {
268 slice,
269 delimiter,
270 remaining: size,
271 index: 0,
272 }
273 }
274
275 #[inline]
276 fn decrease_remaining(&mut self) {
277 if let Some(remaining) = self.remaining {
278 self.remaining = Some(remaining - 1);
279 }
280 }
281 }
282
283 impl<'a> Iterator for SizedValuesIterator<'a> {
284 type Item = RawSlice<'a>;
285
286 fn next(&mut self) -> Option<Self::Item> {
287 if self.index >= self.slice.len() {
288 return None;
289 }
290
291 if let Some(remaining) = self.remaining {
292 match remaining {
293 0 => {
294 return None;
295 }
296 1 => {
297 self.remaining = Some(0);
298 return Some(RawSlice(&self.slice[self.index..]));
299 }
300 _ => {}
301 }
302 }
303
304 let start = self.index;
305 for c in &self.slice[self.index..] {
306 if *c == self.delimiter {
307 let end = self.index;
308 self.index += 1;
309
310 self.decrease_remaining();
311 return Some(RawSlice(&self.slice[start..end]));
312 }
313 self.index += 1;
314 }
315
316 self.decrease_remaining();
317 Some(RawSlice(&self.slice[start..]))
318 }
319 }
320}
321
322#[cfg(test)]
323mod tests {
324 use std::borrow::Cow;
325
326 use super::DelimiterQS;
327
328 #[test]
329 fn parse_pair() {
330 let slice = b"key=value";
331
332 let parser = DelimiterQS::parse(slice, b'|');
333
334 assert_eq!(parser.keys(), vec![&Cow::Borrowed(b"key")]);
335 assert_eq!(
336 parser.values(b"key"),
337 Some(Some(vec![Cow::Borrowed("value".as_bytes())]))
338 );
339 assert_eq!(
340 parser.value(b"key"),
341 Some(Some(Cow::Borrowed("value".as_bytes())))
342 );
343
344 assert_eq!(parser.values(b"test"), None);
345 }
346
347 #[test]
348 fn parse_multiple_pairs() {
349 let slice = b"foo=bar&foobar=baz&qux=box";
350
351 let parser = DelimiterQS::parse(slice, b'|');
352
353 assert_eq!(
354 parser.values(b"foo"),
355 Some(Some(vec!["bar".as_bytes().into()]))
356 );
357 assert_eq!(
358 parser.values(b"foobar"),
359 Some(Some(vec!["baz".as_bytes().into()]))
360 );
361 assert_eq!(
362 parser.values(b"qux"),
363 Some(Some(vec!["box".as_bytes().into()]))
364 );
365 }
366
367 #[test]
368 fn parse_no_value() {
369 let slice = b"foo&foobar=";
370
371 let parser = DelimiterQS::parse(slice, b'|');
372
373 assert_eq!(parser.values(b"foo"), Some(None));
375 assert_eq!(
376 parser.values(b"foobar"),
377 Some(Some(vec!["".as_bytes().into()]))
378 );
379
380 assert_eq!(parser.value(b"foo"), Some(None));
382 assert_eq!(parser.value(b"foobar"), Some(Some("".as_bytes().into())));
383 }
384
385 #[test]
386 fn parse_multiple_values() {
387 let slice = b"foo=bar|baz|foobar||";
388
389 let parser = DelimiterQS::parse(slice, b'|');
390
391 assert_eq!(
392 parser.values(b"foo"),
393 Some(Some(vec![
394 "bar".as_bytes().into(),
395 "baz".as_bytes().into(),
396 "foobar".as_bytes().into(),
397 "".as_bytes().into(),
398 "".as_bytes().into()
399 ]))
400 );
401
402 let slice = b"foo=bar,baz,foobar,,";
403
404 let parser = DelimiterQS::parse(slice, b',');
405
406 assert_eq!(
407 parser.values(b"foo"),
408 Some(Some(vec![
409 "bar".as_bytes().into(),
410 "baz".as_bytes().into(),
411 "foobar".as_bytes().into(),
412 "".as_bytes().into(),
413 "".as_bytes().into()
414 ]))
415 );
416 }
417}