serde_querystring/parsers/
duplicate.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 parse(slice: &'a [u8]) -> Option<Self> {
33 if *slice.first()? == b'&' {
34 return None;
35 }
36
37 let mut index = 1;
38 while index < slice.len() {
39 match slice[index] {
40 b'&' => break,
41 _ => index += 1,
42 }
43 }
44
45 Some(Self(&slice[1..index]))
46 }
47
48 fn len(&self) -> usize {
49 self.0.len()
50 }
51
52 fn decode<'s>(&self, scratch: &'s mut Vec<u8>) -> Reference<'a, 's, [u8]> {
53 parse_bytes(self.0, scratch)
54 }
55
56 fn slice(&self) -> &'a [u8] {
57 self.0
58 }
59}
60
61struct Pair<'a>(Key<'a>, Option<Value<'a>>);
62
63impl<'a> Pair<'a> {
64 fn parse(slice: &'a [u8]) -> Self {
65 let key = Key::parse(slice);
66 let value = Value::parse(&slice[key.len()..]);
67
68 Self(key, value)
69 }
70
71 fn skip_len(&self) -> usize {
75 match &self.1 {
76 Some(v) => self.0.len() + v.len() + 2,
77 None => self.0.len() + 1,
78 }
79 }
80}
81
82pub struct DuplicateQS<'a> {
112 pairs: BTreeMap<Cow<'a, [u8]>, Vec<Pair<'a>>>,
113}
114
115impl<'a> DuplicateQS<'a> {
116 pub fn parse(slice: &'a [u8]) -> Self {
118 let mut pairs: BTreeMap<Cow<'a, [u8]>, Vec<Pair<'a>>> = BTreeMap::new();
119 let mut scratch = Vec::new();
120
121 let mut index = 0;
122
123 while index < slice.len() {
124 let pair = Pair::parse(&slice[index..]);
125 index += pair.skip_len();
126
127 let decoded_key = pair.0.decode(&mut scratch);
128
129 if let Some(values) = pairs.get_mut(decoded_key.as_ref()) {
130 values.push(pair);
131 } else {
132 pairs.insert(decoded_key.into_cow(), vec![pair]);
133 }
134 }
135
136 Self { pairs }
137 }
138
139 pub fn keys(&self) -> Vec<&Cow<'a, [u8]>> {
141 self.pairs.keys().collect()
142 }
143
144 pub fn values(&self, key: &'a [u8]) -> Option<Vec<Option<Cow<'a, [u8]>>>> {
152 let mut scratch = Vec::new();
153
154 Some(
155 self.pairs
156 .get(key)?
157 .iter()
158 .map(|p| p.1.as_ref().map(|v| v.decode(&mut scratch).into_cow()))
159 .collect(),
160 )
161 }
162
163 pub fn value(&self, key: &'a [u8]) -> Option<Option<Cow<'a, [u8]>>> {
171 let mut scratch = Vec::new();
172
173 self.pairs
174 .get(key)?
175 .iter()
176 .last()
177 .map(|p| p.1.as_ref().map(|v| v.decode(&mut scratch).into_cow()))
178 }
179}
180
181#[cfg(feature = "serde")]
182mod de {
183 use _serde::Deserialize;
184
185 use crate::de::{
186 Error, ErrorKind, QSDeserializer,
187 __implementors::{DecodedSlice, IntoRawSlices, RawSlice},
188 };
189
190 use super::DuplicateQS;
191
192 impl<'a> DuplicateQS<'a> {
193 pub fn deserialize<T: Deserialize<'a>>(self) -> Result<T, Error> {
195 T::deserialize(QSDeserializer::new(self.into_iter()))
196 }
197
198 pub(crate) fn into_iter(
199 self,
200 ) -> impl Iterator<
201 Item = (
202 DecodedSlice<'a>,
203 DuplicateValueIter<impl Iterator<Item = RawSlice<'a>>>,
204 ),
205 > {
206 self.pairs.into_iter().map(|(key, pairs)| {
207 (
208 DecodedSlice(key),
209 DuplicateValueIter(
210 pairs
211 .into_iter()
212 .map(|v| RawSlice(v.1.map(|v| v.slice()).unwrap_or_default())),
213 ),
214 )
215 })
216 }
217 }
218
219 pub(crate) struct DuplicateValueIter<I>(I);
220
221 impl<'a, I> IntoRawSlices<'a> for DuplicateValueIter<I>
222 where
223 I: Iterator<Item = RawSlice<'a>>,
224 {
225 type SizedIterator = I;
226 type UnSizedIterator = I;
227
228 #[inline]
229 fn into_sized_iterator(self, size: usize) -> Result<I, Error> {
230 if self.0.size_hint().0 == size {
231 Ok(self.0)
232 } else {
233 Err(Error::new(ErrorKind::InvalidLength))
234 }
235 }
236
237 #[inline]
238 fn into_unsized_iterator(self) -> I {
239 self.0
240 }
241
242 #[inline]
243 fn into_single_slice(self) -> RawSlice<'a> {
244 self.0
245 .last()
246 .expect("Iterator has at least one value in it")
247 }
248 }
249}
250
251#[cfg(test)]
252mod tests {
253 use std::borrow::Cow;
254
255 use super::DuplicateQS;
256
257 #[test]
258 fn parse_pair() {
259 let slice = b"key=value";
260
261 let parser = DuplicateQS::parse(slice);
262
263 assert_eq!(parser.keys(), vec![&Cow::Borrowed(b"key")]);
264 assert_eq!(
265 parser.values(b"key"),
266 Some(vec![Some(Cow::Borrowed("value".as_bytes()))])
267 );
268 assert_eq!(
269 parser.value(b"key"),
270 Some(Some(Cow::Borrowed("value".as_bytes())))
271 );
272 }
273
274 #[test]
275 fn parse_multiple_pairs() {
276 let slice = b"foo=bar&foobar=baz&qux=box";
277
278 let parser = DuplicateQS::parse(slice);
279
280 assert_eq!(
281 parser.values(b"foo"),
282 Some(vec![Some("bar".as_bytes().into())])
283 );
284 assert_eq!(
285 parser.values(b"foobar"),
286 Some(vec![Some("baz".as_bytes().into())])
287 );
288 assert_eq!(
289 parser.values(b"qux"),
290 Some(vec![Some("box".as_bytes().into())])
291 );
292 }
293
294 #[test]
295 fn parse_no_value() {
296 let slice = b"foo&foobar=";
297
298 let parser = DuplicateQS::parse(slice);
299
300 assert_eq!(parser.value(b"key"), None);
301 assert_eq!(parser.values(b"key"), None);
302 assert_eq!(parser.value(b"foo"), Some(None));
303 assert_eq!(parser.values(b"foo"), Some(vec![None]));
304 assert_eq!(
305 parser.values(b"foobar"),
306 Some(vec![Some("".as_bytes().into())])
307 );
308 assert_eq!(parser.value(b"foobar"), Some(Some("".as_bytes().into())));
309 }
310
311 #[test]
312 fn parse_multiple_values() {
313 let slice = b"foo=bar&foo=baz&foo=foobar&foo&foo=";
314
315 let parser = DuplicateQS::parse(slice);
316
317 assert_eq!(
318 parser.values(b"foo"),
319 Some(vec![
320 Some("bar".as_bytes().into()),
321 Some("baz".as_bytes().into()),
322 Some("foobar".as_bytes().into()),
323 None,
324 Some("".as_bytes().into())
325 ])
326 );
327
328 assert_eq!(parser.value(b"foo"), Some(Some("".as_bytes().into())));
329 }
330}