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#[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}