1use percent_encoding::{percent_encode, AsciiSet, NON_ALPHANUMERIC};
4use serde::ser;
5
6use crate::error::*;
7
8use std::borrow::Cow;
9use std::fmt::Display;
10use std::io::Write;
11use std::str;
12
13const QS_ENCODE_SET: &AsciiSet = &NON_ALPHANUMERIC
14 .remove(b' ')
15 .remove(b'*')
16 .remove(b'-')
17 .remove(b'.')
18 .remove(b'_');
19
20pub fn to_string<T: ser::Serialize>(input: &T) -> Result<String> {
47 let mut buffer = Vec::new();
48 let mut first = true;
49 input.serialize(&mut QsSerializer {
50 writer: &mut buffer,
51 key: None,
52 first: &mut first,
53 })?;
54 String::from_utf8(buffer).map_err(Error::from)
55}
56
57pub fn to_writer<T: ser::Serialize, W: Write>(input: &T, writer: &mut W) -> Result<()> {
85 let mut first = true;
86 input.serialize(&mut QsSerializer {
87 writer,
88 key: None,
89 first: &mut first,
90 })
91}
92
93pub struct QsSerializer<'a, W: 'a + Write> {
102 key: Option<Cow<'static, str>>,
103 writer: &'a mut W,
104 first: &'a mut bool,
105}
106
107fn replace_space(input: &str) -> Cow<str> {
108 match input.as_bytes().iter().position(|&b| b == b' ') {
109 None => Cow::Borrowed(input),
110 Some(first_position) => {
111 let mut replaced = input.as_bytes().to_owned();
112 replaced[first_position] = b'+';
113 for byte in &mut replaced[first_position + 1..] {
114 if *byte == b' ' {
115 *byte = b'+';
116 }
117 }
118 Cow::Owned(String::from_utf8(replaced).expect("replacing ' ' with '+' cannot panic"))
119 }
120 }
121}
122
123impl<'a, W: 'a + Write> QsSerializer<'a, W> {
124 fn extend_key(&mut self, newkey: &str) {
125 let newkey = percent_encode(newkey.as_bytes(), QS_ENCODE_SET)
126 .map(replace_space)
127 .collect::<String>();
128 let key = if let Some(ref key) = self.key {
129 format!("{}[{}]", key, newkey)
130 } else {
131 newkey
132 };
133 self.key = Some(Cow::Owned(key))
134 }
135
136 fn write_value(&mut self, value: &[u8]) -> Result<()> {
137 if let Some(ref key) = self.key {
138 write!(
139 self.writer,
140 "{}{}={}",
141 if *self.first {
142 *self.first = false;
143 ""
144 } else {
145 "&"
146 },
147 key,
148 percent_encode(value, QS_ENCODE_SET)
149 .map(replace_space)
150 .collect::<String>()
151 )
152 .map_err(Error::from)
153 } else {
154 Err(Error::no_key())
155 }
156 }
157
158 fn new_from_ref<'b: 'a>(other: &'a mut QsSerializer<'b, W>) -> QsSerializer<'a, W> {
161 Self {
162 key: other.key.clone(),
163 writer: other.writer,
164 first: other.first,
165 }
166 }
167}
168
169impl Error {
170 fn no_key() -> Self {
171 let msg = "tried to serialize a value before serializing key";
172 Error::Custom(msg.into())
173 }
174}
175
176macro_rules! serialize_as_string {
177 (Qs $($ty:ty => $meth:ident,)*) => {
178 $(
179 fn $meth(self, v: $ty) -> Result<Self::Ok> {
180 self.write_value(&v.to_string().as_bytes())
181 }
182 )*
183 };
184 ($($ty:ty => $meth:ident,)*) => {
185 $(
186 fn $meth(self, v: $ty) -> Result<Self::Ok> {
187 Ok(v.to_string())
188 }
189 )*
190 };
191}
192
193impl<'a, W: Write> ser::Serializer for &'a mut QsSerializer<'a, W> {
194 type Ok = ();
195 type Error = Error;
196 type SerializeSeq = QsSeq<'a, W>;
197 type SerializeTuple = QsSeq<'a, W>;
198 type SerializeTupleStruct = QsSeq<'a, W>;
199 type SerializeTupleVariant = QsSeq<'a, W>;
200 type SerializeMap = QsMap<'a, W>;
201 type SerializeStruct = Self;
202 type SerializeStructVariant = Self;
203
204 serialize_as_string! {
205 Qs
206 bool => serialize_bool,
207 u8 => serialize_u8,
208 u16 => serialize_u16,
209 u32 => serialize_u32,
210 u64 => serialize_u64,
211 i8 => serialize_i8,
212 i16 => serialize_i16,
213 i32 => serialize_i32,
214 i64 => serialize_i64,
215 f32 => serialize_f32,
216 f64 => serialize_f64,
217 char => serialize_char,
218 &str => serialize_str,
219 }
220
221 fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok> {
222 self.write_value(value)
223 }
224
225 fn serialize_unit(self) -> Result<Self::Ok> {
226 self.write_value(&[])
227 }
228
229 fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> {
231 self.write_value(name.as_bytes())
232 }
233
234 fn serialize_unit_variant(
236 self,
237 _name: &'static str,
238 _variant_index: u32,
239 variant: &'static str,
240 ) -> Result<Self::Ok> {
241 self.write_value(variant.as_bytes())
242 }
243
244 fn serialize_newtype_struct<T: ?Sized + ser::Serialize>(
246 self,
247 _name: &'static str,
248 value: &T,
249 ) -> Result<Self::Ok> {
250 value.serialize(self)
251 }
252
253 fn serialize_newtype_variant<T: ?Sized + ser::Serialize>(
255 self,
256 _name: &'static str,
257 _variant_index: u32,
258 variant: &'static str,
259 value: &T,
260 ) -> Result<Self::Ok> {
261 self.extend_key(variant);
262 value.serialize(self)
263 }
264
265 fn serialize_none(self) -> Result<Self::Ok> {
266 Ok(())
267 }
268
269 fn serialize_some<T: ?Sized + ser::Serialize>(self, value: &T) -> Result<Self::Ok> {
270 value.serialize(self)
272 }
273
274 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
276 Ok(QsSeq(self, 0))
277 }
278
279 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
280 Ok(QsSeq(self, 0))
281 }
282
283 fn serialize_tuple_struct(
285 self,
286 _name: &'static str,
287 _len: usize,
288 ) -> Result<Self::SerializeTupleStruct> {
289 Ok(QsSeq(self, 0))
290 }
291
292 fn serialize_tuple_variant(
293 self,
294 _name: &'static str,
295 _variant_index: u32,
296 variant: &'static str,
297 _len: usize,
298 ) -> Result<Self::SerializeTupleVariant> {
299 self.extend_key(variant);
301 Ok(QsSeq(self, 0))
302 }
303
304 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
305 Ok(QsMap(self, None))
306 }
307
308 fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
309 Ok(self)
310 }
311
312 fn serialize_struct_variant(
313 self,
314 _name: &'static str,
315 _variant_index: u32,
316 variant: &'static str,
317 _len: usize,
318 ) -> Result<Self::SerializeStructVariant> {
319 self.extend_key(variant);
320 Ok(self)
321 }
322}
323
324impl ser::Error for Error {
325 fn custom<T>(msg: T) -> Self
326 where
327 T: Display,
328 {
329 Error::Custom(msg.to_string())
330 }
331}
332
333pub struct QsSeq<'a, W: 'a + Write>(&'a mut QsSerializer<'a, W>, usize);
334pub struct QsMap<'a, W: 'a + Write>(&'a mut QsSerializer<'a, W>, Option<Cow<'a, str>>);
335
336impl<'a, W: Write> ser::SerializeTuple for QsSeq<'a, W> {
337 type Ok = ();
338 type Error = Error;
339 fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
340 where
341 T: ser::Serialize,
342 {
343 let mut serializer = QsSerializer::new_from_ref(self.0);
344 serializer.extend_key(&self.1.to_string());
345 self.1 += 1;
346 value.serialize(&mut serializer)
347 }
348
349 fn end(self) -> Result<Self::Ok> {
350 Ok(())
351 }
352}
353
354impl<'a, W: Write> ser::SerializeSeq for QsSeq<'a, W> {
355 type Ok = ();
356 type Error = Error;
357 fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
358 where
359 T: ser::Serialize,
360 {
361 let mut serializer = QsSerializer::new_from_ref(self.0);
362 serializer.extend_key(&self.1.to_string());
363 self.1 += 1;
364 value.serialize(&mut serializer)
365 }
366 fn end(self) -> Result<Self::Ok> {
367 Ok(())
368 }
369}
370
371impl<'a, W: Write> ser::SerializeStruct for &'a mut QsSerializer<'a, W> {
372 type Ok = ();
373 type Error = Error;
374 fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<()>
375 where
376 T: ser::Serialize,
377 {
378 let mut serializer = QsSerializer::new_from_ref(self);
379 serializer.extend_key(key);
380 value.serialize(&mut serializer)
381 }
382 fn end(self) -> Result<Self::Ok> {
383 Ok(())
384 }
385}
386
387impl<'a, W: Write> ser::SerializeStructVariant for &'a mut QsSerializer<'a, W> {
388 type Ok = ();
389 type Error = Error;
390
391 fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<()>
392 where
393 T: ser::Serialize,
394 {
395 let mut serializer = QsSerializer::new_from_ref(self);
396 serializer.extend_key(key);
397 value.serialize(&mut serializer)
398 }
399
400 fn end(self) -> Result<Self::Ok> {
401 Ok(())
402 }
403}
404
405impl<'a, W: Write> ser::SerializeTupleVariant for QsSeq<'a, W> {
406 type Ok = ();
407 type Error = Error;
408
409 fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
410 where
411 T: ser::Serialize,
412 {
413 let mut serializer = QsSerializer::new_from_ref(self.0);
414 serializer.extend_key(&self.1.to_string());
415 self.1 += 1;
416 value.serialize(&mut serializer)
417 }
418
419 fn end(self) -> Result<Self::Ok> {
420 Ok(())
421 }
422}
423
424impl<'a, W: Write> ser::SerializeTupleStruct for QsSeq<'a, W> {
425 type Ok = ();
426 type Error = Error;
427
428 fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
429 where
430 T: ser::Serialize,
431 {
432 let mut serializer = QsSerializer::new_from_ref(self.0);
433 serializer.extend_key(&self.1.to_string());
434 self.1 += 1;
435 value.serialize(&mut serializer)
436 }
437
438 fn end(self) -> Result<Self::Ok> {
439 Ok(())
440 }
441}
442
443impl<'a, W: Write> ser::SerializeMap for QsMap<'a, W> {
444 type Ok = ();
445 type Error = Error;
446
447 fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()>
448 where
449 T: ser::Serialize,
450 {
451 self.1 = Some(Cow::from(key.serialize(StringSerializer)?));
452 Ok(())
453 }
454
455 fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()>
456 where
457 T: ser::Serialize,
458 {
459 let mut serializer = QsSerializer::new_from_ref(self.0);
460 if let Some(ref key) = self.1 {
461 serializer.extend_key(key);
462 } else {
463 return Err(Error::no_key());
464 }
465 self.1 = None;
466 value.serialize(&mut serializer)
467 }
468
469 fn end(self) -> Result<Self::Ok> {
470 Ok(())
471 }
472
473 fn serialize_entry<K: ?Sized, V: ?Sized>(&mut self, key: &K, value: &V) -> Result<()>
474 where
475 K: ser::Serialize,
476 V: ser::Serialize,
477 {
478 let mut serializer = QsSerializer::new_from_ref(self.0);
479 serializer.extend_key(&key.serialize(StringSerializer)?);
480 value.serialize(&mut serializer)
481 }
482}
483
484struct StringSerializer;
485
486impl ser::Serializer for StringSerializer {
487 type Ok = String;
488 type Error = Error;
489 type SerializeSeq = ser::Impossible<String, Error>;
490 type SerializeTuple = ser::Impossible<String, Error>;
491 type SerializeTupleStruct = ser::Impossible<String, Error>;
492 type SerializeTupleVariant = ser::Impossible<String, Error>;
493 type SerializeMap = ser::Impossible<String, Error>;
494 type SerializeStruct = ser::Impossible<String, Error>;
495 type SerializeStructVariant = ser::Impossible<String, Error>;
496
497 serialize_as_string! {
498 bool => serialize_bool,
499 u8 => serialize_u8,
500 u16 => serialize_u16,
501 u32 => serialize_u32,
502 u64 => serialize_u64,
503 i8 => serialize_i8,
504 i16 => serialize_i16,
505 i32 => serialize_i32,
506 i64 => serialize_i64,
507 f32 => serialize_f32,
508 f64 => serialize_f64,
509 char => serialize_char,
510 &str => serialize_str,
511 }
512
513 fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok> {
514 Ok(String::from_utf8_lossy(value).to_string())
515 }
516
517 fn serialize_unit(self) -> Result<Self::Ok> {
519 Err(Error::Unsupported)
520 }
521
522 fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
524 Err(Error::Unsupported)
525 }
526
527 fn serialize_unit_variant(
528 self,
529 _name: &'static str,
530 _variant_index: u32,
531 variant: &'static str,
532 ) -> Result<Self::Ok> {
533 Ok(variant.to_string())
534 }
535
536 fn serialize_newtype_struct<T: ?Sized + ser::Serialize>(
538 self,
539 _name: &'static str,
540 _value: &T,
541 ) -> Result<Self::Ok> {
542 Err(Error::Unsupported)
543 }
544
545 fn serialize_newtype_variant<T: ?Sized + ser::Serialize>(
547 self,
548 _name: &'static str,
549 _variant_index: u32,
550 _variant: &'static str,
551 _value: &T,
552 ) -> Result<Self::Ok> {
553 Err(Error::Unsupported)
554 }
555
556 fn serialize_none(self) -> Result<Self::Ok> {
558 Err(Error::Unsupported)
559 }
560
561 fn serialize_some<T: ?Sized + ser::Serialize>(self, _value: &T) -> Result<Self::Ok> {
563 Err(Error::Unsupported)
564 }
565
566 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
568 Err(Error::Unsupported)
569 }
570
571 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
572 Err(Error::Unsupported)
573 }
574
575 fn serialize_tuple_struct(
577 self,
578 _name: &'static str,
579 _len: usize,
580 ) -> Result<Self::SerializeTupleStruct> {
581 Err(Error::Unsupported)
582 }
583
584 fn serialize_tuple_variant(
585 self,
586 _name: &'static str,
587 _variant_index: u32,
588 _variant: &'static str,
589 _len: usize,
590 ) -> Result<Self::SerializeTupleVariant> {
591 Err(Error::Unsupported)
592 }
593
594 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
595 Err(Error::Unsupported)
596 }
597
598 fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
599 Err(Error::Unsupported)
600 }
601
602 fn serialize_struct_variant(
603 self,
604 _name: &'static str,
605 _variant_index: u32,
606 _variant: &'static str,
607 _len: usize,
608 ) -> Result<Self::SerializeStructVariant> {
609 Err(Error::Unsupported)
610 }
611}