1use std::fmt;
2use std::str::FromStr;
3use std::error::Error;
4use std::ops::Deref;
5use std::collections::HashMap;
6
7use crate::ValidationError;
8
9#[derive(Debug, PartialEq)]
11pub struct UrlDecodingError<'a> {
12 message: &'a str,
13}
14
15impl <'a> UrlDecodingError<'a> {
16 pub fn new(message: &'a str) -> UrlDecodingError {
17 UrlDecodingError {
18 message,
19 }
20 }
21}
22
23impl <'a> fmt::Display for UrlDecodingError<'a> {
24 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25 write!(f, "{}", self.message)
26 }
27}
28
29impl <'a> Error for UrlDecodingError<'a> {
30 fn description(&self) -> &str {
31 &self.message
32 }
33}
34
35impl <'a> From<std::str::Utf8Error> for UrlDecodingError<'a> {
36 fn from(_e: std::str::Utf8Error) -> UrlDecodingError<'a> {
37 UrlDecodingError {
38 message: "invalid encoding error sequence",
39 }
40 }
41}
42
43impl <'a> From<hex::FromHexError> for UrlDecodingError<'a> {
44 fn from(_e: hex::FromHexError) -> UrlDecodingError<'a> {
45 UrlDecodingError {
46 message: "invalid encoding sequence",
47 }
48 }
49}
50
51impl <'a> From<std::num::ParseIntError> for UrlDecodingError<'a> {
52 fn from(_e: std::num::ParseIntError) -> UrlDecodingError<'a> {
53 UrlDecodingError {
54 message: "invalid encoding character",
55 }
56 }
57}
58
59pub fn urldecode(input: &[u8]) -> Result<String, UrlDecodingError<'static>> {
61 let plus: u8 = 43;
62 let percent: u8 = 37;
63 let mut out: Vec<u8> = Vec::new();
64 let mut i = 0;
65 while i < input.len() {
66 let chr: u8 = input[i];
67 let charcode: u8;
68 i += 1;
69 if chr == percent {
70 if input.len() < i + 2 {
71 return Err(
72 UrlDecodingError::new("unexpected end of input"));
73 }
74 charcode = hex::decode(
83 &format!(
84 "{}{}", input[i] as char, input[i + 1] as char))?[0];
85 i += 2;
86 } else if chr == plus {
87 charcode = 32 } else {
90 charcode = chr;
91 }
92 out.push(charcode);
93 }
94 Ok(std::str::from_utf8(&out)?.to_string())
95}
96
97#[derive(Debug, PartialEq, Clone)]
102pub struct ValueMap {
103 values: HashMap<String, Vec<Value>>,
104}
105
106impl ValueMap {
107 pub fn new(values: HashMap<String, Vec<Value>>) -> ValueMap {
108 ValueMap {
109 values,
110 }
111 }
112
113 pub fn from_vec(vec: Vec<(&str, Vec<&str>)>) -> ValueMap {
114 let mut values: HashMap<String, Vec<Value>> = HashMap::new();
115 for (name, strvalues) in vec {
116 values.insert(
117 String::from(name),
118 strvalues.iter().map(|v| Value::new(v)).collect());
119 }
120 ValueMap {
121 values,
122 }
123 }
124
125 pub fn values(&self, name: &str) -> Option<&Vec<Value>> {
126 self.values.get(name)
127 }
128
129 pub fn from_urlencoded(input: &[u8]) ->
130 Result<ValueMap, UrlDecodingError> {
131 let mut values: HashMap<String, Vec<Value>> = HashMap::new();
132 let eq: u8 = 61;
133 let amp: u8 = 38;
134 let mut bkey = vec![];
135 let mut bvalue = vec![];
136 let mut in_value = false;
137 for chr in input {
138 let chr = chr.clone();
139 if chr == eq {
140 if !in_value {
141 in_value = true;
142 } else {
143 return Err(
144 UrlDecodingError::new("unexpected = character"));
145 }
146 } else if chr == amp {
147 let key = urldecode(&bkey)?;
148 let value = urldecode(&bvalue)?;
149 if !bvalue.is_empty() {
150 if values.contains_key(&key) {
151 let keyvalues = values.get_mut(&key).unwrap();
152 keyvalues.push(Value::new(&value));
153 } else {
154 values.insert(key, vec![Value::new(&value)]);
155 }
156 } else {
157 values.insert(key, vec![]);
158 }
159 bkey.truncate(0);
160 bvalue.truncate(0);
161 in_value = false;
162 } else if in_value {
163 bvalue.push(chr);
164 } else {
165 bkey.push(chr);
166 }
167 }
168 if !bkey.is_empty() {
170 let key = urldecode(&bkey)?;
171 let value = urldecode(&bvalue)?;
172 if !bvalue.is_empty() {
173 if values.contains_key(&key) {
174 let keyvalues = values.get_mut(&key).unwrap();
175 keyvalues.push(Value::new(&value));
176 } else {
177 values.insert(key, vec![Value::new(&value)]);
178 }
179 } else {
180 values.insert(key, vec![]);
181 }
182 }
183 let map = ValueMap {
184 values,
185 };
186 Ok(map)
187 }
188}
189
190impl Deref for ValueMap {
191 type Target = HashMap<String, Vec<Value>>;
192
193 fn deref(&self) -> &Self::Target {
194 &self.values
195 }
196}
197
198#[derive(Debug, PartialEq, Clone)]
201pub struct Value(String);
202
203impl Value {
204 pub fn new(value: &str) -> Value {
205 Value(value.to_string())
206 }
207
208 pub fn as_string(&self) -> String {
209 self.0.clone()
210 }
211
212 pub fn parse<T>(&self) -> Result<T, ValidationError>
213 where T: FromStr {
214 match self.0.parse() {
215 Ok(value) => Ok(value),
216 Err(_) => Err(ValidationError::new(
217 &format!("cannot convert {:?}", self.0))),
218 }
219 }
220}
221
222impl Deref for Value {
224 type Target = String;
225
226 fn deref(&self) -> &Self::Target {
227 &self.0
228 }
229}