querystring_tiny/
querystring.rs1use crate::error::Error;
4use std::{collections::BTreeMap, iter::FromIterator, ops::Deref};
5
6#[derive(Debug, Clone, Default)]
21pub struct QueryString {
22 fields: BTreeMap<Vec<u8>, Vec<u8>>,
24}
25impl QueryString {
26 pub fn new() -> Self {
28 Self { fields: BTreeMap::new() }
29 }
30 pub fn decode(source: &[u8]) -> Result<Self, Error> {
32 let (mut source, mut fields) = (source.iter().copied(), BTreeMap::new());
34 while source.len() > 0 {
35 let mut pair = (&mut source).take_while(|&b| b != b'&');
37 let key: Vec<_> = (&mut pair).take_while(|&b| b != b'=').collect();
38 let value: Vec<_> = (&mut pair).collect();
39
40 if !key.is_empty() {
42 fields.insert(key, value);
43 }
44 }
45 Ok(Self { fields })
46 }
47
48 pub fn get<T>(&self, name: T) -> Option<&[u8]>
50 where
51 T: AsRef<[u8]>,
52 {
53 self.fields.get(name.as_ref()).map(|s| s.as_ref())
54 }
55 pub fn set<A, B>(&mut self, name: A, value: B)
57 where
58 A: Into<Vec<u8>>,
59 B: Into<Vec<u8>>,
60 {
61 self.fields.insert(name.into(), value.into());
62 }
63
64 pub fn encode(&self) -> Vec<u8> {
66 let mut serialized = Vec::new();
68 for (key, value) in self.fields.iter() {
69 if !serialized.is_empty() {
71 serialized.extend(b"&");
72 }
73
74 serialized.extend(key);
76 if !value.is_empty() {
77 serialized.extend(b"=");
78 serialized.extend(value);
79 }
80 }
81 serialized
82 }
83}
84impl Deref for QueryString {
85 type Target = BTreeMap<Vec<u8>, Vec<u8>>;
86
87 fn deref(&self) -> &Self::Target {
88 &self.fields
89 }
90}
91impl<K, V> FromIterator<(K, V)> for QueryString
92where
93 K: Into<Vec<u8>>,
94 V: Into<Vec<u8>>,
95{
96 fn from_iter<T: IntoIterator<Item = (K, V)>>(pairs: T) -> Self {
97 let fields = pairs.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
98 Self { fields }
99 }
100}
101impl IntoIterator for QueryString {
102 type Item = <BTreeMap<Vec<u8>, Vec<u8>> as IntoIterator>::Item;
103 type IntoIter = <BTreeMap<Vec<u8>, Vec<u8>> as IntoIterator>::IntoIter;
104
105 fn into_iter(self) -> Self::IntoIter {
106 self.fields.into_iter()
107 }
108}