kserd/encode/
encoder.rs

1use super::*;
2use serde::{ser, Serialize};
3use std::{error, fmt};
4
5type Res = Result<Kserd<'static>, Error>;
6
7/// Encoder to pass to [`Serialize::serialize`] to encode a type into a [`Kserd`].
8///
9/// There is no data associated with the `Encoder`, instead it is used to implement `serde`'s
10/// `Serializer` trait. It can be used to encode a data type that implements [`Serialize`] like
11/// so:
12/// ```rust
13/// # use kserd::*;
14/// use kserd::encode::Encoder;
15/// use kserd::encode::Serialize;
16///
17/// let data = ("Hello!", 3.14);
18/// let expected = Kserd::new(
19///     Value::Tuple(vec![
20///         Kserd::new_str("Hello!"),
21///         Kserd::new_num(3.14),
22///     ])
23/// );
24///
25/// let kserd = data.serialize(Encoder);
26/// assert_eq!(kserd, Ok(expected));
27/// ```
28///
29/// It is important to note that the signature of the [`Serialize`] trait does not allow
30/// propogation of borrowed data. Specifically, when implementing a `Serializer` the values
31/// are either passed through copied, or as ephemeral borrows as in the case of strings and byte
32/// arrays. This limits the [`Kserd`] to be an _owned_ copy, with a `'static` lifetime parameter.
33/// This has implications when decoding as described in the [`Decoder`] documentation.
34/// An alternate trait [`ToKserd`] is defined that _consumes_ the data structure and allows
35/// borrowed data to be propogated to the [`Kserd`].
36///
37/// There is also a helper function [`Kserd::enc`] that can encode without importing the `Encoder`.
38/// ```rust
39/// # use kserd::*;
40/// let expected = Kserd::new(
41///     Value::Tuple(vec![
42///         Kserd::new_str("Hello!"),
43///         Kserd::new_num(3.14),
44///     ])
45/// );
46///
47/// let kserd = Kserd::enc(&("Hello!", 3.14));
48/// assert_eq!(kserd, Ok(expected));
49/// ```
50///
51/// [`Decoder`]: crate::encode::Decoder
52/// [`Kserd`]: crate::Kserd
53/// [`Kserd::enc`]: crate::Kserd::enc
54/// [`Serialize`]: crate::encode::Serialize
55/// [`Serialize::serialize`]: crate::encode::Serialize::serialize
56/// [`ToKserd`]: crate::ToKserd
57pub struct Encoder;
58
59impl ser::Serializer for Encoder {
60    type Ok = Kserd<'static>;
61    type Error = Error;
62    type SerializeSeq = SeqLike;
63    type SerializeTuple = TupleLike;
64    type SerializeTupleStruct = TupleLike;
65    type SerializeTupleVariant = TupleLike;
66    type SerializeMap = MapLike;
67    type SerializeStruct = CntrLike;
68    type SerializeStructVariant = CntrLike;
69
70    fn serialize_bool(self, v: bool) -> Res {
71        Ok(Kserd::new_bool(v))
72    }
73
74    fn serialize_i8(self, v: i8) -> Res {
75        Ok(Kserd::new_num(v))
76    }
77
78    fn serialize_i16(self, v: i16) -> Res {
79        Ok(Kserd::new_num(v))
80    }
81
82    fn serialize_i32(self, v: i32) -> Res {
83        Ok(Kserd::new_num(v))
84    }
85
86    fn serialize_i64(self, v: i64) -> Res {
87        Ok(Kserd::new_num(v))
88    }
89
90    fn serialize_i128(self, v: i128) -> Res {
91        Ok(Kserd::new_num(v))
92    }
93
94    fn serialize_u8(self, v: u8) -> Res {
95        Ok(Kserd::new_num(v))
96    }
97
98    fn serialize_u16(self, v: u16) -> Res {
99        Ok(Kserd::new_num(v))
100    }
101
102    fn serialize_u32(self, v: u32) -> Res {
103        Ok(Kserd::new_num(v))
104    }
105
106    fn serialize_u64(self, v: u64) -> Res {
107        Ok(Kserd::new_num(v))
108    }
109
110    fn serialize_u128(self, v: u128) -> Res {
111        Ok(Kserd::new_num(v))
112    }
113
114    fn serialize_f32(self, v: f32) -> Res {
115        Ok(Kserd::new_num(v))
116    }
117
118    fn serialize_f64(self, v: f64) -> Res {
119        Ok(Kserd::new_num(v))
120    }
121
122    fn serialize_char(self, v: char) -> Res {
123        Ok(Kserd::with_id_unchk(
124            "char",
125            Value::Str(Kstr::owned(v.to_string())),
126        ))
127    }
128
129    fn serialize_str(self, v: &str) -> Res {
130        Ok(Kserd::new_str(v).into_owned())
131    }
132
133    fn serialize_bytes(self, v: &[u8]) -> Res {
134        Ok(Kserd::new_barr(v).into_owned())
135    }
136
137    fn serialize_none(self) -> Res {
138        Ok(Kserd::with_id_unchk("None", Value::Tuple(vec![])))
139    }
140
141    fn serialize_some<T: ?Sized + Serialize>(self, v: &T) -> Res {
142        Ok(Kserd::with_id_unchk(
143            "Some",
144            Value::Tuple(vec![v.serialize(self)?]),
145        ))
146    }
147
148    fn serialize_unit(self) -> Res {
149        Ok(Kserd::new_unit())
150    }
151
152    fn serialize_unit_struct(self, name: &'static str) -> Res {
153        Kserd::with_id(name, Value::Tuple(vec![])).map_err(Error::InvalidId)
154    }
155
156    fn serialize_unit_variant(self, _: &'static str, _: u32, variant: &'static str) -> Res {
157        Kserd::with_id(variant, Value::Tuple(vec![])).map_err(Error::InvalidId)
158    }
159
160    fn serialize_newtype_struct<T: ?Sized + Serialize>(self, name: &'static str, value: &T) -> Res {
161        Kserd::with_id(name, Value::Tuple(vec![value.serialize(self)?])).map_err(Error::InvalidId)
162    }
163
164    fn serialize_newtype_variant<T: ?Sized + Serialize>(
165        self,
166        _: &'static str,
167        _: u32,
168        variant: &'static str,
169        value: &T,
170    ) -> Res {
171        Kserd::with_id(variant, Value::Tuple(vec![value.serialize(self)?]))
172            .map_err(Error::InvalidId)
173    }
174
175    fn serialize_seq(self, len: Option<usize>) -> Result<SeqLike, Error> {
176        Ok(SeqLike {
177            kserd: Kserd::new(Value::Seq(Vec::with_capacity(len.unwrap_or_default()))),
178        })
179    }
180
181    fn serialize_tuple(self, len: usize) -> Result<TupleLike, Error> {
182        Ok(TupleLike {
183            kserd: Kserd::new(Value::Tuple(Vec::with_capacity(len))),
184        })
185    }
186
187    fn serialize_tuple_struct(self, name: &'static str, len: usize) -> Result<TupleLike, Error> {
188        Ok(TupleLike {
189            kserd: Kserd::with_id(name, Value::Tuple(Vec::with_capacity(len)))
190                .map_err(Error::InvalidId)?,
191        })
192    }
193
194    fn serialize_tuple_variant(
195        self,
196        _: &'static str,
197        _: u32,
198        variant: &'static str,
199        len: usize,
200    ) -> Result<TupleLike, Error> {
201        Ok(TupleLike {
202            kserd: Kserd::with_id(variant, Value::Tuple(Vec::with_capacity(len)))
203                .map_err(Error::InvalidId)?,
204        })
205    }
206
207    fn serialize_map(self, _len: Option<usize>) -> Result<MapLike, Error> {
208        Ok(MapLike {
209            key: None,
210            kserd: Kserd::new(Value::Map(BTreeMap::new())),
211        })
212    }
213
214    fn serialize_struct(self, name: &'static str, _len: usize) -> Result<CntrLike, Error> {
215        Ok(CntrLike {
216            kserd: Kserd::with_id(name, Value::Cntr(Fields::new())).map_err(Error::InvalidId)?,
217        })
218    }
219
220    fn serialize_struct_variant(
221        self,
222        _: &'static str,
223        _: u32,
224        variant: &'static str,
225        _: usize,
226    ) -> Result<CntrLike, Error> {
227        Ok(CntrLike {
228            kserd: Kserd::with_id(variant, Value::Cntr(Fields::new())).map_err(Error::InvalidId)?,
229        })
230    }
231
232    fn collect_str<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
233    where
234        T: std::fmt::Display,
235    {
236        self.serialize_str(&value.to_string())
237    }
238}
239
240/// Kserd serialization error.
241#[derive(Debug, PartialEq, Clone)]
242pub enum Error {
243    /// There is only one possible error, if an implementor of
244    /// `Serialize` when serializing a map calls `serialize_value` before
245    /// calling `serialize_key`. This error is extremely rare and would only
246    /// occur where the implementor of `Serialize` does not follow the guidance
247    /// from `serde`.
248    NoKeyAvailable,
249    /// The identity string contains invalid characters.
250    /// See [`Kserd::with_id`](crate::Kserd::with_id).
251    InvalidId(crate::ds::InvalidId),
252    /// Some `Serialize` implementor error occurred.
253    Message(String),
254}
255
256impl ser::Error for Error {
257    fn custom<T: fmt::Display>(msg: T) -> Self {
258        Error::Message(msg.to_string())
259    }
260}
261
262impl error::Error for Error {}
263
264impl fmt::Display for Error {
265    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
266        match self {
267            Error::NoKeyAvailable => {
268                write!(f, "no key was available when trying to serialize map value")
269            }
270            Error::InvalidId(s) => write!(f, "{}", s),
271            Error::Message(s) => write!(f, "custom error: {}", s),
272        }
273    }
274}
275
276pub struct SeqLike {
277    kserd: Kserd<'static>,
278}
279
280impl ser::SerializeSeq for SeqLike {
281    type Ok = Kserd<'static>;
282    type Error = Error;
283
284    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Error> {
285        match &mut self.kserd.val {
286            Value::Seq(v) => v.push(value.serialize(Encoder)?),
287            _ => unreachable!(),
288        }
289
290        Ok(())
291    }
292
293    fn end(self) -> Res {
294        Ok(self.kserd)
295    }
296}
297
298pub struct TupleLike {
299    kserd: Kserd<'static>,
300}
301
302impl ser::SerializeTuple for TupleLike {
303    type Ok = Kserd<'static>;
304    type Error = Error;
305
306    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Error> {
307        match &mut self.kserd.val {
308            Value::Tuple(v) => v.push(value.serialize(Encoder)?),
309            _ => unreachable!(),
310        }
311
312        Ok(())
313    }
314
315    fn end(self) -> Res {
316        Ok(self.kserd)
317    }
318}
319
320impl ser::SerializeTupleStruct for TupleLike {
321    type Ok = Kserd<'static>;
322    type Error = Error;
323
324    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Error> {
325        match &mut self.kserd.val {
326            Value::Tuple(v) => v.push(value.serialize(Encoder)?),
327            _ => unreachable!(),
328        }
329
330        Ok(())
331    }
332
333    fn end(self) -> Res {
334        Ok(self.kserd)
335    }
336}
337
338impl ser::SerializeTupleVariant for TupleLike {
339    type Ok = Kserd<'static>;
340    type Error = Error;
341
342    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Error> {
343        match &mut self.kserd.val {
344            Value::Tuple(v) => v.push(value.serialize(Encoder)?),
345            _ => unreachable!(),
346        }
347
348        Ok(())
349    }
350
351    fn end(self) -> Res {
352        Ok(self.kserd)
353    }
354}
355
356pub struct MapLike {
357    key: Option<Kserd<'static>>,
358    kserd: Kserd<'static>,
359}
360
361impl ser::SerializeMap for MapLike {
362    type Ok = Kserd<'static>;
363    type Error = Error;
364
365    fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<(), Error> {
366        self.key = Some(key.serialize(Encoder)?);
367        Ok(())
368    }
369
370    fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Error> {
371        let key = self.key.take().ok_or(Error::NoKeyAvailable)?;
372
373        match &mut self.kserd.val {
374            Value::Map(v) => {
375                v.insert(key, value.serialize(Encoder)?);
376            }
377            _ => unreachable!(),
378        }
379
380        Ok(())
381    }
382
383    fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<(), Error>
384    where
385        K: ?Sized + Serialize,
386        V: ?Sized + Serialize,
387    {
388        match &mut self.kserd.val {
389            Value::Map(v) => {
390                v.insert(key.serialize(Encoder)?, value.serialize(Encoder)?);
391            }
392            _ => unreachable!(),
393        }
394
395        Ok(())
396    }
397
398    fn end(self) -> Res {
399        Ok(self.kserd)
400    }
401}
402
403pub struct CntrLike {
404    kserd: Kserd<'static>,
405}
406
407impl ser::SerializeStruct for CntrLike {
408    type Ok = Kserd<'static>;
409    type Error = Error;
410
411    fn serialize_field<T: ?Sized + Serialize>(
412        &mut self,
413        key: &'static str,
414        value: &T,
415    ) -> Result<(), Error> {
416        match &mut self.kserd.val {
417            Value::Cntr(cntr) => {
418                cntr.insert(key.into(), value.serialize(Encoder)?);
419            }
420            _ => unreachable!(),
421        }
422        Ok(())
423    }
424
425    fn end(self) -> Res {
426        Ok(self.kserd)
427    }
428}
429
430impl ser::SerializeStructVariant for CntrLike {
431    type Ok = Kserd<'static>;
432    type Error = Error;
433
434    fn serialize_field<T: ?Sized + Serialize>(
435        &mut self,
436        key: &'static str,
437        value: &T,
438    ) -> Result<(), Error> {
439        match &mut self.kserd.val {
440            Value::Cntr(cntr) => {
441                cntr.insert(key.into(), value.serialize(Encoder)?);
442            }
443            _ => unreachable!(),
444        }
445        Ok(())
446    }
447
448    fn end(self) -> Res {
449        Ok(self.kserd)
450    }
451}
452
453#[cfg(test)]
454mod tests {
455    use super::*;
456    use ser::Error as _;
457    use ser::{SerializeMap, Serializer};
458
459    #[test]
460    fn other_tests() {
461        let kserd = Encoder.serialize_newtype_struct("Test", &());
462        assert_eq!(kserd, Ok(Kserd::new(Value::Tuple(vec![Kserd::new_unit()]))));
463        let kserd = kserd.unwrap();
464        assert_eq!(kserd.id(), Some("Test"));
465        let kserd = Encoder
466            .serialize_newtype_struct("\\Test", &())
467            .map_err(|e| e.to_string());
468        assert_eq!(kserd, Err(r#"identity '\Test' contains invalid characters. Invalid characters: '(){}[]<> ,./\='"#.into()));
469
470        let kserd = Encoder
471            .serialize_newtype_variant("\\Test", 0, "\\Test", &())
472            .map_err(|e| e.to_string());
473        assert_eq!(kserd, Err(r#"identity '\Test' contains invalid characters. Invalid characters: '(){}[]<> ,./\='"#.into()));
474
475        let kserd = Encoder.collect_str("Hello, world!");
476        assert_eq!(kserd, Ok(Kserd::new_str("Hello, world!")));
477
478        let err = Error::custom("Hello");
479        assert_eq!(&err.to_string(), "custom error: Hello");
480    }
481
482    #[test]
483    fn map_tests() {
484        let map: std::collections::HashMap<u64, String> =
485            vec![(100, "Hello".into())].into_iter().collect();
486        let kserd = Kserd::enc(&map);
487        assert_eq!(
488            kserd,
489            Ok(Kserd::new_map(vec![(
490                100.into_kserd().unwrap(),
491                "Hello".into_kserd().unwrap()
492            )]))
493        );
494
495        let mut map = MapLike {
496            key: None,
497            kserd: Kserd::new_map(vec![]),
498        };
499
500        let r = map.serialize_key(&100);
501        assert_eq!(r, Ok(()));
502        assert_eq!(map.key, Some(Kserd::new_num(100)));
503
504        let r = map.serialize_value("Hello");
505        assert_eq!(r, Ok(()));
506        assert_eq!(
507            map.kserd,
508            Kserd::new_map(vec![(
509                100.into_kserd().unwrap(),
510                "Hello".into_kserd().unwrap()
511            )])
512        );
513    }
514}