serde_ext/
lib.rs

1pub use serde_ext_macros::*;
2
3pub mod de {
4
5    #[derive(derive_more::Deref, derive_more::DerefMut)]
6    pub struct Parsable<T>(pub T);
7
8    impl<'de, T> serde::Deserialize<'de> for Parsable<T>
9    where
10        T: std::str::FromStr,
11        <T as std::str::FromStr>::Err: std::fmt::Display,
12    {
13        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
14        where
15            D: serde::de::Deserializer<'de>,
16        {
17            let s: std::borrow::Cow<str> = serde::Deserialize::deserialize(deserializer)?;
18            Ok(Parsable(s.parse().map_err(serde::de::Error::custom)?))
19        }
20    }
21
22    pub fn parsable<'de, D, T>(deserializer: D) -> Result<T, D::Error>
23    where
24        D: serde::de::Deserializer<'de>,
25        T: std::str::FromStr,
26        <T as std::str::FromStr>::Err: std::fmt::Display,
27    {
28        let out: Parsable<T> = serde::Deserialize::deserialize(deserializer)?;
29        Ok(out.0)
30    }
31
32    pub struct NonEmptyString(pub Option<String>);
33
34    impl<'de> serde::Deserialize<'de> for NonEmptyString
35    {
36        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
37        where
38            D: serde::de::Deserializer<'de>,
39        {
40            let s: Option<String> = serde::Deserialize::deserialize(deserializer)?;
41            Ok(NonEmptyString(s.and_then(|t| if t.is_empty() { None } else { Some(t) })))
42        }
43    }
44
45    pub fn non_empty_string<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
46    where
47        D: serde::de::Deserializer<'de>,
48    {
49        let out: NonEmptyString = serde::Deserialize::deserialize(deserializer)?;
50        Ok(out.0)
51    }
52
53}
54
55#[cfg(feature = "base64")]
56pub mod base64 {
57
58    #[derive(derive_more::Deref, derive_more::DerefMut)]
59    pub struct Base64(pub Vec<u8>);
60
61    impl<'de> serde::Deserialize<'de> for Base64 where {
62        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
63        where
64            D: serde::de::Deserializer<'de>,
65        {
66            let s: std::borrow::Cow<str> = serde::Deserialize::deserialize(deserializer)?;
67            Ok(Base64(base64::decode(s.as_ref()).map_err(serde::de::Error::custom)?))
68        }
69    }
70
71    impl serde::Serialize for Base64 {
72        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
73        where
74            S: serde::ser::Serializer,
75        {
76            serialize(&self.0, serializer)
77        }
78    }
79
80    pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
81    where
82        D: serde::de::Deserializer<'de>,
83    {
84        let out: Base64 = serde::Deserialize::deserialize(deserializer)?;
85        Ok(out.0)
86    }
87
88    fn serialize<S>(base64_bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
89    where
90        S: serde::ser::Serializer,
91    {
92        use serde::ser::Serialize;
93        base64::encode(&base64_bytes).serialize(serializer)
94    }
95
96}
97
98#[cfg(test)]
99mod tests {
100    #[test]
101    fn it_works() {
102        assert_eq!(2 + 2, 4);
103    }
104}