credibil_vc/core/urlencode/
ser.rs

1use percent_encoding::{utf8_percent_encode, AsciiSet, NON_ALPHANUMERIC};
2use serde::{ser, Serialize};
3
4use super::error::{Error, Result};
5
6const TOP_LEVEL: usize = 1;
7const UNRESERVED: &AsciiSet =
8    &NON_ALPHANUMERIC.remove(b'&').remove(b'=').remove(b'.').remove(b'_').remove(b'-').remove(b'~');
9
10/// Serializes a value to a url-encoded string.
11///
12/// ```rust,ignore
13/// use serde::{Deserialize, Serialize};
14///
15/// #[derive(Serialize, Deserialize)]
16/// struct TopLevel {
17///     field_1: String,
18///     field_2: Nested,
19/// }
20///
21/// #[derive(Serialize, Deserialize)]
22/// struct Nested {
23///     field_3: String,
24///     field_4: String,
25/// }
26///
27/// let data = TopLevel {
28///     field_1: "value1".to_owned(),
29///     field_2: "value2".to_owned(),
30///     nested: Nested {
31///         field_3: "value3".to_owned(),
32///         field_4: "value4".to_owned(),
33///     },
34/// };
35///
36/// let serialized = urlencode::to_string(&data).expect("should serialize");
37/// let expected =
38///     r#"field_1=value1&field_2=value2&nested=%7B%22field_3%22%3A%22value3%22%2C%22field_4%22%3A%22value4%22%7D"#;
39/// assert_eq!(serialized, expected);
40/// ```
41///
42/// # Errors
43/// TODO: Add error handling
44pub fn to_string<T>(value: &T) -> Result<String>
45where
46    T: Serialize,
47{
48    let mut serializer = Serializer {
49        output: String::new(),
50        level: 0,
51    };
52    value.serialize(&mut serializer)?;
53
54    let encoded = utf8_percent_encode(&serializer.output, UNRESERVED).to_string();
55    Ok(encoded)
56}
57
58/// A serializer for url encoding.
59///
60/// * Supported top-level inputs are structs, maps and sequences of pairs, with
61///   or without a given length.
62///
63/// * Supported keys and values are integers, bytes (if convertible to strings),
64///   unit structs and unit variants.
65///
66/// * Newtype structs defer to their inner values.
67pub struct Serializer {
68    output: String,
69    level: usize,
70}
71
72impl ser::Serializer for &mut Serializer {
73    type Error = Error;
74    type Ok = ();
75    type SerializeMap = Self;
76    type SerializeSeq = Self;
77    type SerializeStruct = Self;
78    type SerializeStructVariant = Self;
79    type SerializeTuple = Self;
80    type SerializeTupleStruct = Self;
81    type SerializeTupleVariant = Self;
82
83    fn serialize_bool(self, v: bool) -> Result<()> {
84        self.output += if v { "true" } else { "false" };
85        Ok(())
86    }
87
88    // JSON does not distinguish between different sizes of integers.
89    fn serialize_i8(self, v: i8) -> Result<()> {
90        self.serialize_i64(i64::from(v))
91    }
92
93    fn serialize_i16(self, v: i16) -> Result<()> {
94        self.serialize_i64(i64::from(v))
95    }
96
97    fn serialize_i32(self, v: i32) -> Result<()> {
98        self.serialize_i64(i64::from(v))
99    }
100
101    // Not particularly efficient but this is example code anyway. A more
102    // performant approach would be to use the `itoa` crate.
103    fn serialize_i64(self, v: i64) -> Result<()> {
104        self.output += &v.to_string();
105        Ok(())
106    }
107
108    fn serialize_u8(self, v: u8) -> Result<()> {
109        self.serialize_u64(u64::from(v))
110    }
111
112    fn serialize_u16(self, v: u16) -> Result<()> {
113        self.serialize_u64(u64::from(v))
114    }
115
116    fn serialize_u32(self, v: u32) -> Result<()> {
117        self.serialize_u64(u64::from(v))
118    }
119
120    fn serialize_u64(self, v: u64) -> Result<()> {
121        self.output += &v.to_string();
122        Ok(())
123    }
124
125    fn serialize_f32(self, v: f32) -> Result<()> {
126        self.serialize_f64(f64::from(v))
127    }
128
129    fn serialize_f64(self, v: f64) -> Result<()> {
130        self.output += &v.to_string();
131        Ok(())
132    }
133
134    fn serialize_char(self, v: char) -> Result<()> {
135        self.serialize_str(&v.to_string())
136    }
137
138    fn serialize_str(self, v: &str) -> Result<()> {
139        if self.level > TOP_LEVEL {
140            self.output += "\"";
141            self.output += v;
142            self.output += "\"";
143        } else {
144            self.output += v;
145        }
146        Ok(())
147    }
148
149    // Serialize a byte array as an array of bytes.
150    fn serialize_bytes(self, v: &[u8]) -> Result<()> {
151        use serde::ser::SerializeSeq;
152        let mut seq = self.serialize_seq(Some(v.len()))?;
153        for byte in v {
154            seq.serialize_element(byte)?;
155        }
156        seq.end()
157    }
158
159    // An absent optional is represented as the JSON `null`.
160    fn serialize_none(self) -> Result<()> {
161        self.serialize_unit()
162    }
163
164    // A present optional is represented as just the contained value. Note that
165    // this is a lossy representation. For example the values `Some(())` and
166    // `None` both serialize as just `null`.
167    fn serialize_some<T>(self, value: &T) -> Result<()>
168    where
169        T: ?Sized + Serialize,
170    {
171        value.serialize(self)
172    }
173
174    // In Serde, unit means an anonymous value containing no data. Map this to
175    // JSON as `null`.
176    fn serialize_unit(self) -> Result<()> {
177        self.output += "null";
178        Ok(())
179    }
180
181    // Unit struct means a named value containing no data. Again, since there is
182    // no data, map this to JSON as `null`.
183    fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
184        self.serialize_unit()
185    }
186
187    // When serializing a unit variant (or any other kind of variant), formats
188    // can choose whether to keep track of it by index or by name.
189    fn serialize_unit_variant(
190        self, _name: &'static str, _variant_index: u32, variant: &'static str,
191    ) -> Result<()> {
192        self.serialize_str(variant)
193    }
194
195    // Treat newtype structs as insignificant wrappers around the data they contain.
196    fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
197    where
198        T: ?Sized + Serialize,
199    {
200        value.serialize(self)
201    }
202
203    // Note that newtype variant (and all of the other variant serialization
204    // methods) refer exclusively to the "externally tagged" enum
205    // representation.
206    //
207    // Serialize this to JSON in externally tagged form as `{ NAME: VALUE }`.
208    fn serialize_newtype_variant<T>(
209        self, _name: &'static str, _variant_index: u32, variant: &'static str, value: &T,
210    ) -> Result<()>
211    where
212        T: ?Sized + Serialize,
213    {
214        self.level += 1;
215
216        if self.level > TOP_LEVEL {
217            self.output += "{";
218            variant.serialize(&mut *self)?;
219            self.output += ":";
220            value.serialize(&mut *self)?;
221            self.output += "}";
222        } else {
223            variant.serialize(&mut *self)?;
224            self.output += "=";
225            value.serialize(&mut *self)?;
226        }
227
228        self.level -= 1;
229        Ok(())
230    }
231
232    // Serialization of compound types.
233    //
234    // The start of the sequence, each value, and the end are three separate
235    // method calls. This one is responsible only for serializing the start,
236    // which in JSON is `[`.
237    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
238        self.level += 1;
239        self.output += "[";
240        Ok(self)
241    }
242
243    // Tuples look just like sequences in JSON.
244    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
245        self.level += 1;
246        self.serialize_seq(Some(len))
247    }
248
249    // Tuple structs look just like sequences in JSON.
250    fn serialize_tuple_struct(
251        self, _name: &'static str, len: usize,
252    ) -> Result<Self::SerializeTupleStruct> {
253        self.serialize_seq(Some(len))
254    }
255
256    // Tuple variants are represented in JSON as `{ NAME: [DATA...] }`. This
257    // method is only responsible for the externally tagged representation.
258    fn serialize_tuple_variant(
259        self, _name: &'static str, _variant_index: u32, variant: &'static str, _len: usize,
260    ) -> Result<Self::SerializeTupleVariant> {
261        self.level += 1;
262
263        if self.level > TOP_LEVEL {
264            self.output += "{";
265            variant.serialize(&mut *self)?;
266            self.output += ":[";
267        } else {
268            variant.serialize(&mut *self)?;
269            self.output += "=[";
270        }
271
272        Ok(self)
273    }
274
275    // Maps are represented in JSON as `{ K: V, K: V, ... }`.
276    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
277        self.level += 1;
278
279        if self.level > TOP_LEVEL {
280            self.output += "{";
281        }
282
283        Ok(self)
284    }
285
286    // Structs look just like maps in JSON.
287    fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
288        self.serialize_map(Some(len))
289    }
290
291    // Struct variants are represented in JSON as `{ NAME: { K: V, ... } }`.
292    // This is the externally tagged representation.
293    fn serialize_struct_variant(
294        self, _name: &'static str, _variant_index: u32, variant: &'static str, _len: usize,
295    ) -> Result<Self::SerializeStructVariant> {
296        self.level += 1;
297
298        if self.level > TOP_LEVEL {
299            self.output += "{";
300            variant.serialize(&mut *self)?;
301            self.output += ":{";
302        } else {
303            variant.serialize(&mut *self)?;
304            self.output += "={";
305        }
306        Ok(self)
307    }
308}
309
310// The following 7 impls deal with the serialization of compound types like
311// sequences and maps. Serialization of such types is begun by a Serializer
312// method and followed by zero or more calls to serialize individual elements of
313// the compound type and one call to end the compound type.
314//
315// `SerializeSeq` methods are called after the `serialize_seq` function.
316// is called on the Serializer.
317impl ser::SerializeSeq for &mut Serializer {
318    type Error = Error;
319    type Ok = ();
320
321    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
322    where
323        T: ?Sized + Serialize,
324    {
325        if !self.output.ends_with('[') {
326            self.output += ",";
327        }
328        value.serialize(&mut **self)
329    }
330
331    fn end(self) -> Result<()> {
332        self.output += "]";
333        self.level -= 1;
334        Ok(())
335    }
336}
337
338impl ser::SerializeTuple for &mut Serializer {
339    type Error = Error;
340    type Ok = ();
341
342    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
343    where
344        T: ?Sized + Serialize,
345    {
346        if !self.output.ends_with('[') {
347            self.output += ",";
348        }
349        value.serialize(&mut **self)
350    }
351
352    fn end(self) -> Result<()> {
353        self.output += "]";
354        self.level -= 1;
355        Ok(())
356    }
357}
358
359impl ser::SerializeTupleStruct for &mut Serializer {
360    type Error = Error;
361    type Ok = ();
362
363    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
364    where
365        T: ?Sized + Serialize,
366    {
367        if !self.output.ends_with('[') {
368            self.output += ",";
369        }
370        value.serialize(&mut **self)
371    }
372
373    fn end(self) -> Result<()> {
374        self.output += "]";
375        self.level -= 1;
376        Ok(())
377    }
378}
379
380// Tuple variants are a little different as the `end` method in this impl is
381// responsible for closing both the `]` and the `}`.
382//
383// See the `serialize_tuple_variant` method above:
384//
385//    self.output += "{";
386//    variant.serialize(&mut *self)?;
387//    self.output += ":[";
388//
389impl ser::SerializeTupleVariant for &mut Serializer {
390    type Error = Error;
391    type Ok = ();
392
393    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
394    where
395        T: ?Sized + Serialize,
396    {
397        if !self.output.ends_with('[') {
398            self.output += ",";
399        }
400        value.serialize(&mut **self)
401    }
402
403    fn end(self) -> Result<()> {
404        if self.level > TOP_LEVEL {
405            self.output += "]}";
406        } else {
407            self.output += "]";
408        }
409        self.level -= 1;
410        Ok(())
411    }
412}
413
414// Some `Serialize` types are not able to hold a key and value in memory at the
415// same time so `SerializeMap` implementations are required to support
416// `serialize_key` and `serialize_value` individually.
417//
418// There is a third optional method on the `SerializeMap` trait. The
419// `serialize_entry` method allows serializers to optimize for the case where
420// key and value are both available simultaneously. In JSON it doesn't make a
421// difference so the default behavior for `serialize_entry` is fine.
422impl ser::SerializeMap for &mut Serializer {
423    type Error = Error;
424    type Ok = ();
425
426    // The Serde data model allows map keys to be any serializable type. JSON
427    // only allows string keys so the implementation below will produce invalid
428    // JSON if the key serializes as something other than a string.
429    //
430    // A real JSON serializer would need to validate that map keys are strings.
431    // This can be done by using a different Serializer to serialize the key
432    // (instead of `&mut **self`) and having that other serializer only
433    // implement `serialize_str` and return an error on any other data type.
434    fn serialize_key<T>(&mut self, key: &T) -> Result<()>
435    where
436        T: ?Sized + Serialize,
437    {
438        if !self.output.ends_with('{') {
439            self.output += ",";
440        }
441        key.serialize(&mut **self)
442    }
443
444    fn serialize_value<T>(&mut self, value: &T) -> Result<()>
445    where
446        T: ?Sized + Serialize,
447    {
448        self.output += ":";
449        value.serialize(&mut **self)
450    }
451
452    fn end(self) -> Result<()> {
453        self.output += "}";
454        self.level -= 1;
455        Ok(())
456    }
457}
458
459impl ser::SerializeStruct for &mut Serializer {
460    type Error = Error;
461    type Ok = ();
462
463    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
464    where
465        T: ?Sized + Serialize,
466    {
467        if self.level > TOP_LEVEL {
468            if !self.output.ends_with('{') {
469                self.output += ",";
470            }
471        } else if !self.output.is_empty() {
472            self.output += "&";
473        }
474
475        key.serialize(&mut **self)?;
476        if self.level > TOP_LEVEL {
477            self.output += ":";
478        } else {
479            self.output += "=";
480        }
481        value.serialize(&mut **self)
482    }
483
484    fn end(self) -> Result<()> {
485        if self.level > TOP_LEVEL {
486            self.output += "}";
487            self.level -= 1;
488        }
489        Ok(())
490    }
491}
492
493// Similar to `SerializeTupleVariant`, here the `end` method is responsible for
494// closing both of the curly braces opened by `serialize_struct_variant`.
495impl ser::SerializeStructVariant for &mut Serializer {
496    type Error = Error;
497    type Ok = ();
498
499    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
500    where
501        T: ?Sized + Serialize,
502    {
503        if !self.output.ends_with('{') {
504            self.output += ",";
505        }
506        key.serialize(&mut **self)?;
507        self.output += ":";
508        value.serialize(&mut **self)
509    }
510
511    fn end(self) -> Result<()> {
512        if self.level > TOP_LEVEL {
513            self.output += "}}";
514        } else {
515            self.output += "}";
516        }
517        self.level -= 1;
518        Ok(())
519    }
520}