1pub mod option_unit_as_null_or_true {
5 use serde::{de, ser, Deserialize, Serialize};
6
7 #[doc(hidden)]
8 pub fn serialize<S>(value: &Option<()>, ser: S) -> Result<S::Ok, S::Error>
9 where
10 S: ser::Serializer,
11 {
12 match value {
13 None => ().serialize(ser),
14 Some(()) => true.serialize(ser),
15 }
16 }
17
18 #[doc(hidden)]
19 pub fn deserialize<'de, D>(de: D) -> Result<Option<()>, D::Error>
20 where
21 D: de::Deserializer<'de>,
22 {
23 match OptionAsNullOrTrue::deserialize(de)? {
24 OptionAsNullOrTrue::Null(()) => Ok(None),
25 OptionAsNullOrTrue::True(true) => Ok(Some(())),
26 _ => Err(de::Error::invalid_value(
27 de::Unexpected::Bool(false),
28 &"null or true",
29 )),
30 }
31 }
32
33 #[derive(Deserialize)]
34 #[serde(untagged)]
35 enum OptionAsNullOrTrue {
36 Null(()),
37 True(bool),
38 }
39}
40
41pub mod option_unit_as_bool {
43 use serde::{de, ser, Deserialize, Serialize};
44
45 #[doc(hidden)]
46 pub fn serialize<S>(value: &Option<()>, ser: S) -> Result<S::Ok, S::Error>
47 where
48 S: ser::Serializer,
49 {
50 value.is_some().serialize(ser)
51 }
52
53 #[doc(hidden)]
54 pub fn deserialize<'de, D>(de: D) -> Result<Option<()>, D::Error>
55 where
56 D: de::Deserializer<'de>,
57 {
58 Ok(if bool::deserialize(de)? {
59 Some(())
60 } else {
61 None
62 })
63 }
64}
65
66pub mod option_unit_as_list {
68 use serde::{de, ser, Deserialize, Serialize};
69
70 #[doc(hidden)]
71 pub fn serialize<S>(value: &Option<()>, ser: S) -> Result<S::Ok, S::Error>
72 where
73 S: ser::Serializer,
74 {
75 OptionAsList { unit: *value }.serialize(ser)
76 }
77
78 #[doc(hidden)]
79 pub fn deserialize<'de, D>(de: D) -> Result<Option<()>, D::Error>
80 where
81 D: de::Deserializer<'de>,
82 {
83 let o = OptionAsList::deserialize(de)?;
84 Ok(o.unit)
85 }
86
87 #[derive(Serialize, Deserialize)]
88 struct OptionAsList {
89 #[serde(default)]
90 #[serde(skip_serializing_if = "Option::is_none")]
91 #[serde(deserialize_with = "deserialize_prefer_some")]
92 unit: Option<()>,
93 }
94
95 fn deserialize_prefer_some<'de, D>(de: D) -> Result<Option<()>, D::Error>
96 where
97 D: de::Deserializer<'de>,
98 {
99 let _ = <()>::deserialize(de)?;
100 Ok(Some(()))
101 }
102}
103
104pub mod u64_as_i64 {
106 use serde::{de, ser, Deserialize, Serialize};
107
108 #[doc(hidden)]
109 pub fn serialize<S>(value: &u64, ser: S) -> Result<S::Ok, S::Error>
110 where
111 S: ser::Serializer,
112 {
113 i64::from_be_bytes(value.to_be_bytes()).serialize(ser)
114 }
115
116 #[doc(hidden)]
117 pub fn deserialize<'de, D>(de: D) -> Result<u64, D::Error>
118 where
119 D: de::Deserializer<'de>,
120 {
121 let value = i64::deserialize(de)?;
122 Ok(u64::from_be_bytes(value.to_be_bytes()))
123 }
124}
125
126pub mod u64_as_bytes {
128 use super::array_as_bytes::ByteArrayVisitor;
129 use serde::{de, ser};
130
131 #[doc(hidden)]
132 pub fn serialize<S>(value: &u64, ser: S) -> Result<S::Ok, S::Error>
133 where
134 S: ser::Serializer,
135 {
136 ser.serialize_bytes(&value.to_be_bytes())
137 }
138
139 #[doc(hidden)]
140 pub fn deserialize<'de, D>(de: D) -> Result<u64, D::Error>
141 where
142 D: de::Deserializer<'de>,
143 {
144 let bytes = de.deserialize_bytes(ByteArrayVisitor::default())?;
145 Ok(u64::from_be_bytes(bytes))
146 }
147}
148
149pub mod u64_as_i64_or_bytes {
151 use serde::{de, ser, Deserialize};
152
153 #[doc(hidden)]
154 pub fn serialize<S>(value: &u64, ser: S) -> Result<S::Ok, S::Error>
155 where
156 S: ser::Serializer,
157 {
158 if *value > i64::MAX as u64 {
159 super::u64_as_bytes::serialize(value, ser)
160 } else {
161 super::u64_as_i64::serialize(value, ser)
162 }
163 }
164
165 #[doc(hidden)]
166 pub fn deserialize<'de, D>(de: D) -> Result<u64, D::Error>
167 where
168 D: de::Deserializer<'de>,
169 {
170 match U64AsI64OrRaw::deserialize(de)? {
171 U64AsI64OrRaw::I64(value) if value <= i64::MAX as u64 => Ok(value as u64),
172 U64AsI64OrRaw::Raw(value) if value > i64::MAX as u64 => Ok(value),
173 _ => Err(de::Error::invalid_value(
174 de::Unexpected::Other("out-of-bounds i64 or raw"),
175 &"i64 >= 0 or raw <= i64::MAX",
176 )),
177 }
178 }
179
180 #[derive(Deserialize)]
181 #[serde(untagged)]
182 enum U64AsI64OrRaw {
183 I64(u64),
184 #[serde(with = "super::u64_as_bytes")]
185 Raw(u64),
186 }
187}
188
189pub mod array_as_bytes {
191 use serde::{de, ser};
192 use std::{fmt, marker::PhantomData};
193
194 #[doc(hidden)]
195 pub trait CopyFromSlice: Default {
196 const LENGTH: usize;
197 fn copy_from_slice(&mut self, slice: &[u8]);
198 }
199
200 macro_rules! copy_from_slice_array_impl {
201 ($n:literal) => {
202 impl CopyFromSlice for [u8; $n] {
203 const LENGTH: usize = $n;
204 fn copy_from_slice(&mut self, slice: &[u8]) {
205 <[u8]>::copy_from_slice(self, slice)
206 }
207 }
208 };
209 }
210
211 copy_from_slice_array_impl!(0);
212 copy_from_slice_array_impl!(1);
213 copy_from_slice_array_impl!(2);
214 copy_from_slice_array_impl!(3);
215 copy_from_slice_array_impl!(4);
216 copy_from_slice_array_impl!(5);
217 copy_from_slice_array_impl!(6);
218 copy_from_slice_array_impl!(7);
219 copy_from_slice_array_impl!(8);
220 copy_from_slice_array_impl!(9);
221 copy_from_slice_array_impl!(10);
222 copy_from_slice_array_impl!(11);
223 copy_from_slice_array_impl!(12);
224 copy_from_slice_array_impl!(13);
225 copy_from_slice_array_impl!(14);
226 copy_from_slice_array_impl!(15);
227 copy_from_slice_array_impl!(16);
228 copy_from_slice_array_impl!(17);
229 copy_from_slice_array_impl!(18);
230 copy_from_slice_array_impl!(19);
231 copy_from_slice_array_impl!(20);
232 copy_from_slice_array_impl!(21);
233 copy_from_slice_array_impl!(22);
234 copy_from_slice_array_impl!(23);
235 copy_from_slice_array_impl!(24);
236 copy_from_slice_array_impl!(25);
237 copy_from_slice_array_impl!(26);
238 copy_from_slice_array_impl!(27);
239 copy_from_slice_array_impl!(28);
240 copy_from_slice_array_impl!(29);
241 copy_from_slice_array_impl!(30);
242 copy_from_slice_array_impl!(31);
243 copy_from_slice_array_impl!(32);
244
245 #[derive(Default)]
246 pub(crate) struct ByteArrayVisitor<T>
247 where
248 T: CopyFromSlice,
249 {
250 array: PhantomData<T>,
251 }
252
253 impl<'de, T> de::Visitor<'de> for ByteArrayVisitor<T>
254 where
255 T: CopyFromSlice,
256 {
257 type Value = T;
258
259 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
260 formatter.write_str("byte array")
261 }
262
263 fn visit_bytes<E>(self, bytes: &[u8]) -> Result<T, E>
264 where
265 E: de::Error,
266 {
267 if bytes.len() != T::LENGTH {
268 return Err(de::Error::invalid_length(bytes.len(), &"array size"));
269 }
270 let mut buf = T::default();
271 buf.copy_from_slice(bytes);
272 Ok(buf)
273 }
274
275 fn visit_byte_buf<E>(self, bytes: Vec<u8>) -> Result<T, E>
276 where
277 E: de::Error,
278 {
279 self.visit_bytes(&bytes)
280 }
281 }
282
283 #[doc(hidden)]
284 pub fn serialize<S, T>(value: &T, ser: S) -> Result<S::Ok, S::Error>
285 where
286 S: ser::Serializer,
287 T: AsRef<[u8]>,
288 {
289 ser.serialize_bytes(value.as_ref())
290 }
291
292 #[doc(hidden)]
293 pub fn deserialize<'de, D, T>(de: D) -> Result<T, D::Error>
294 where
295 D: de::Deserializer<'de>,
296 T: CopyFromSlice,
297 {
298 de.deserialize_bytes(ByteArrayVisitor::default())
299 }
300}
301
302#[cfg(test)]
303mod test {
304 use super::*;
305 use crate::from_slice;
306 use crate::to_vec;
307 use hex_literal::hex;
308 use serde::{Deserialize, Serialize};
309
310 #[test]
311 fn customize_option_unit() {
312 #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
313 struct Test {
314 #[serde(with = "option_unit_as_null_or_true")]
315 a0: Option<()>,
316 #[serde(with = "option_unit_as_null_or_true")]
317 a1: Option<()>,
318 #[serde(with = "option_unit_as_bool")]
319 b0: Option<()>,
320 #[serde(with = "option_unit_as_bool")]
321 b1: Option<()>,
322 #[serde(with = "option_unit_as_list")]
323 c0: Option<()>,
324 #[serde(with = "option_unit_as_list")]
325 c1: Option<()>,
326 }
327 let input = Test {
328 a0: None,
329 a1: Some(()),
330 b0: None,
331 b1: Some(()),
332 c0: None,
333 c1: Some(()),
334 };
335 let buf = to_vec(&input).unwrap();
336 assert_eq!(
337 hex!("60 00 11 10 11 60 80 60 00 80 80").as_ref(),
338 buf.as_slice()
339 );
340
341 let output = from_slice(&buf).unwrap();
342
343 assert_eq!(input, output);
344 }
345
346 #[test]
347 fn customize_u64() {
348 #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
349 struct Test {
350 #[serde(with = "u64_as_i64")]
351 a0: u64,
352 #[serde(with = "u64_as_i64")]
353 a1: u64,
354 #[serde(with = "u64_as_bytes")]
355 b0: u64,
356 #[serde(with = "u64_as_bytes")]
357 b1: u64,
358 #[serde(with = "u64_as_i64_or_bytes")]
359 c0: u64,
360 #[serde(with = "u64_as_i64_or_bytes")]
361 c1: u64,
362 }
363 let input = Test {
364 a0: 17,
365 a1: 0x8765432101234567,
366 b0: 17,
367 b1: 0x8765432101234567,
368 c0: 17,
369 c1: 0x8765432101234567,
370 };
371 let buf = to_vec(&input).unwrap();
372 assert_eq!(
373 hex!("60 2111 288765432101234567 51080000000000000011 51088765432101234567 2111 51088765432101234567 80").as_ref(),
374 buf.as_slice()
375 );
376
377 let output = from_slice(&buf).unwrap();
378
379 assert_eq!(input, output);
380 }
381}