texcraft_stdext/
serde_tools.rs

1//! A collection of tools for working with serde.
2use serde::{Deserialize, Serialize};
3
4/// Module for serializing and deserializing fixed size arrays.
5///
6/// This is intended for use with serde derive's
7/// `#[serde(with = "texcraft_stdext::serde_tools::array")]` field attribute.
8pub mod array {
9    use super::*;
10
11    /// Function that serializes fixed size arrays
12    pub fn serialize<T, S, const N: usize>(input: &[T; N], serializer: S) -> Result<S::Ok, S::Error>
13    where
14        T: serde::Serialize,
15        S: serde::Serializer,
16    {
17        // TODO: we should not allocate a vector
18        let v: Vec<&T> = input.iter().collect();
19        v.serialize(serializer)
20    }
21
22    /// Function that deserializes fixed size arrays
23    pub fn deserialize<'de, T, D, const N: usize>(deserializer: D) -> Result<[T; N], D::Error>
24    where
25        T: Deserialize<'de> + std::fmt::Debug,
26        D: serde::Deserializer<'de>,
27    {
28        // TODO: we should not allocate a vector
29        let v = Vec::<T>::deserialize(deserializer)?;
30        // TODO: error instead of panic
31        let a: [T; N] = v.try_into().unwrap();
32        Ok(a)
33    }
34}
35
36/// Module for serializing and deserializing iterables collections.
37///
38/// This is intended for use with serde derive's
39/// `#[serde(with = "texcraft_stdext::serde_tools::iter")]` field attribute.
40pub mod iter {
41    use super::*;
42
43    /// Function that serializes an iterable type.
44    pub fn serialize<T, I, S>(input: I, serializer: S) -> Result<S::Ok, S::Error>
45    where
46        T: serde::Serialize,
47        I: IntoIterator<Item = T>,
48        S: serde::Serializer,
49    {
50        serializer.collect_seq(input)
51    }
52
53    /// Function that deserializes types that can be built from iterators
54    pub fn deserialize<'de, T, C, D>(deserializer: D) -> Result<C, D::Error>
55    where
56        T: Deserialize<'de> + std::fmt::Debug,
57        C: FromIterator<T>,
58        D: serde::Deserializer<'de>,
59    {
60        // TODO: we should not allocate a vector
61        let v = Vec::<T>::deserialize(deserializer)?;
62        Ok(C::from_iter(v))
63    }
64}
65
66/// Function that serializes strings
67///
68/// This is intended for use with serde derive's
69/// `#[serde(serialize_with = "path")]` field attribute.
70pub fn serialize_str<T, S>(input: T, serializer: S) -> Result<S::Ok, S::Error>
71where
72    T: AsRef<str>,
73    S: serde::Serializer,
74{
75    let s: &str = input.as_ref();
76    s.serialize(serializer)
77}
78
79/// Function that deserializes reference counted constant strings
80///
81/// This is intended for use with serde derive's
82/// `#[serde(deserialize_with = "path")]` field attribute.
83pub fn deserialize_rc_str<'de, D>(deserializer: D) -> Result<std::rc::Rc<str>, D::Error>
84where
85    D: serde::Deserializer<'de>,
86{
87    // TODO: should probably use Cow<> here to support not coping the string
88    let s = String::deserialize(deserializer)?;
89    Ok(s.into())
90}