1#![expect(missing_docs)]
8#![forbid(unsafe_code)]
9
10mod prelude {
11 pub use serde::Deserialize;
12 pub use serde::Deserializer;
13 pub use serde::Serialize;
14 pub use serde::Serializer;
15}
16
17pub mod base64_vec {
19 use crate::prelude::*;
20 use base64::Engine;
21
22 pub fn serialize<S: Serializer>(v: &Vec<u8>, ser: S) -> Result<S::Ok, S::Error> {
23 ser.serialize_str(&base64::engine::general_purpose::STANDARD.encode(v))
24 }
25
26 pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Vec<u8>, D::Error> {
27 let s: &str = Deserialize::deserialize(d)?;
28 base64::engine::general_purpose::STANDARD
29 .decode(s)
30 .map_err(serde::de::Error::custom)
31 }
32}
33
34pub mod as_string {
36 use crate::prelude::*;
37 use std::fmt::Display;
38 use std::str::FromStr;
39
40 pub fn serialize<T: Display, S: Serializer>(value: &T, ser: S) -> Result<S::Ok, S::Error> {
41 ser.collect_str(value)
42 }
43
44 pub fn deserialize<'de, T, D: Deserializer<'de>>(d: D) -> Result<T, D::Error>
45 where
46 T: FromStr,
47 T::Err: std::error::Error,
48 {
49 let s: &str = Deserialize::deserialize(d)?;
50 s.parse().map_err(serde::de::Error::custom)
51 }
52}
53
54pub mod as_debug {
56 use crate::prelude::*;
57 use std::fmt::Debug;
58
59 pub fn serialize<T: Debug, S: Serializer>(value: &T, ser: S) -> Result<S::Ok, S::Error> {
60 ser.collect_str(&format_args!("{:?}", value))
61 }
62}
63
64pub mod opt_guid_str {
67 use crate::prelude::*;
68 use guid::Guid;
69
70 pub fn serialize<S: Serializer>(guid: &Option<Guid>, ser: S) -> Result<S::Ok, S::Error> {
71 match guid {
72 Some(guid) => ser.serialize_some(&guid.to_string()),
73 None => ser.serialize_none(),
74 }
75 }
76
77 pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Option<Guid>, D::Error> {
78 let s: Option<&str> = Deserialize::deserialize(d)?;
79 Ok(match s {
80 None => None,
81 Some(s) => Some(s.parse().map_err(serde::de::Error::custom)?),
82 })
83 }
84}
85
86pub mod opt_base64_json {
90 use crate::prelude::*;
91 use base64::Engine;
92
93 pub fn serialize<S: Serializer, T: Serialize>(
94 t: &Option<T>,
95 ser: S,
96 ) -> Result<S::Ok, S::Error> {
97 match t {
98 Some(t) => ser.serialize_str(
99 &base64::engine::general_purpose::STANDARD
100 .encode(serde_json::to_string(t).map_err(serde::ser::Error::custom)?),
101 ),
102 None => ser.serialize_none(),
103 }
104 }
105 pub fn deserialize<'de, D: Deserializer<'de>, T: serde::de::DeserializeOwned>(
106 d: D,
107 ) -> Result<Option<T>, D::Error> {
108 let s: Option<&str> = Deserialize::deserialize(d)?;
109 Ok(match s {
110 None => None,
111 Some(s) => {
112 let s = base64::engine::general_purpose::STANDARD
113 .decode(s)
114 .map_err(serde::de::Error::custom)?;
115 Some(serde_json::from_slice(&s).map_err(serde::de::Error::custom)?)
116 }
117 })
118 }
119}
120
121pub mod opt_base64_vec {
122 use base64::Engine;
123 use serde::*;
124
125 pub fn serialize<S: Serializer>(v: &Option<Vec<u8>>, ser: S) -> Result<S::Ok, S::Error> {
126 match v {
127 Some(v) => ser.serialize_str(&base64::engine::general_purpose::STANDARD.encode(v)),
128 None => ser.serialize_none(),
129 }
130 }
131
132 pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Option<Vec<u8>>, D::Error> {
133 let s: Option<&str> = Deserialize::deserialize(d)?;
134 Ok(match s {
135 Some(s) => Some(
136 base64::engine::general_purpose::STANDARD
137 .decode(s)
138 .map_err(de::Error::custom)?,
139 ),
140 None => None,
141 })
142 }
143}
144
145pub mod vec_base64_vec {
146 use base64::Engine;
147 use ser::SerializeSeq;
148 use serde::*;
149
150 pub fn serialize<S: Serializer>(v: &Vec<Vec<u8>>, ser: S) -> Result<S::Ok, S::Error> {
151 let mut seq = ser.serialize_seq(Some(v.len()))?;
152 for element in v {
153 seq.serialize_element(&base64::engine::general_purpose::STANDARD.encode(element))?;
154 }
155 seq.end()
156 }
157
158 pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Vec<Vec<u8>>, D::Error> {
159 let ss: Vec<&str> = Deserialize::deserialize(d)?;
160 let mut vs = Vec::new();
161 for s in ss {
162 vs.push(
163 base64::engine::general_purpose::STANDARD
164 .decode(s)
165 .map_err(de::Error::custom)?,
166 );
167 }
168 Ok(vs)
169 }
170}
171
172#[cfg(test)]
173mod test {
174 use super::*;
175 use guid::Guid;
176 use serde::Deserialize;
177
178 #[test]
179 fn opt_guid() {
180 #[derive(Deserialize)]
181 struct OptGuidSample {
182 field1: u32,
183 #[serde(default)]
184 #[serde(with = "opt_guid_str")]
185 field2: Option<Guid>,
186 }
187
188 let json = r#"
189 {
190 "field1": 123,
191 "field2": "12345678-9abc-def0-1234-56789abcdef0"
192 }"#;
193 let guid_sample: OptGuidSample = serde_json::from_str(json).expect("deserialization");
194 assert_eq!(guid_sample.field1, 123);
195 assert_eq!(
196 guid_sample.field2.expect("field2 set"),
197 guid::guid!("12345678-9abc-def0-1234-56789abcdef0")
198 );
199
200 let json = r#"
201 {
202 "field1": 123
203 }"#;
204 let guid_sample: OptGuidSample = serde_json::from_str(json).expect("deserialization");
205 assert_eq!(guid_sample.field1, 123);
206 assert!(guid_sample.field2.is_none());
207 }
208}