Skip to main content

g_string/
serde.rs

1use serde::{
2    Deserialize, Deserializer, Serialize, Serializer,
3    de::{self, Visitor},
4};
5
6use crate::{GString, GStringError, Validator};
7use core::{fmt, marker::PhantomData};
8
9#[cfg(feature = "alloc")]
10extern crate alloc;
11
12#[cfg(feature = "alloc")]
13use alloc::string::String;
14
15impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool> Serialize
16    for GString<V, MIN, MAX, ASCII_ONLY>
17{
18    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
19        serializer.serialize_str(self.as_str())
20    }
21}
22
23struct GStringVisitor<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool>(
24    PhantomData<V>,
25);
26
27impl<'de, V, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool> Visitor<'de>
28    for GStringVisitor<V, MIN, MAX, ASCII_ONLY>
29where
30    V: Validator,
31    GStringError<V::Err>: fmt::Display,
32{
33    type Value = GString<V, MIN, MAX, ASCII_ONLY>;
34
35    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
36        write!(
37            formatter,
38            "a string with length between {} and {}{}",
39            MIN,
40            MAX,
41            if ASCII_ONLY { " (ASCII only)" } else { "" }
42        )
43    }
44
45    fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
46        GString::try_new(v).map_err(de::Error::custom)
47    }
48
49    #[cfg(feature = "alloc")]
50    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
51    where
52        E: de::Error,
53    {
54        GString::try_from(v).map_err(de::Error::custom)
55    }
56}
57
58impl<'de, V, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool> Deserialize<'de>
59    for GString<V, MIN, MAX, ASCII_ONLY>
60where
61    V: Validator,
62    GStringError<V::Err>: fmt::Display,
63{
64    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
65        deserializer.deserialize_str(GStringVisitor(PhantomData))
66    }
67}
68
69// GSecret serde
70#[cfg(feature = "secret")]
71mod secret_serde {
72    use crate::{GSecret, GStringError, Validator};
73    use core::{fmt, marker::PhantomData};
74    use serde::{
75        Deserialize, Deserializer,
76        de::{self, Visitor},
77    };
78
79    #[cfg(feature = "alloc")]
80    extern crate alloc;
81
82    #[cfg(feature = "alloc")]
83    use alloc::string::String;
84
85    struct GSecretVisitor<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool>(
86        PhantomData<V>,
87    );
88
89    impl<'de, V, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool> Visitor<'de>
90        for GSecretVisitor<V, MIN, MAX, ASCII_ONLY>
91    where
92        V: Validator,
93        GStringError<V::Err>: fmt::Display,
94    {
95        type Value = GSecret<V, MIN, MAX, ASCII_ONLY>;
96
97        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
98            write!(
99                formatter,
100                "a secret string between {} and {}{}",
101                MIN,
102                MAX,
103                if ASCII_ONLY { " (ASCII only)" } else { "" }
104            )
105        }
106
107        fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
108        where
109            E: de::Error,
110        {
111            GSecret::try_new(v).map_err(de::Error::custom)
112        }
113
114        #[cfg(feature = "alloc")]
115        fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
116        where
117            E: de::Error,
118        {
119            GSecret::try_from(v).map_err(de::Error::custom)
120        }
121    }
122
123    impl<'de, V, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool> Deserialize<'de>
124        for GSecret<V, MIN, MAX, ASCII_ONLY>
125    where
126        V: Validator,
127        GStringError<V::Err>: fmt::Display,
128    {
129        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
130        where
131            D: Deserializer<'de>,
132        {
133            deserializer.deserialize_str(GSecretVisitor(PhantomData))
134        }
135    }
136}