array_bytes/serde.rs
1// core
2use core::str;
3// alloc
4use alloc::format;
5// crates.io
6#[cfg(test)] use serde::Serialize;
7use serde::{Deserialize, Deserializer, Serializer, de::Error as _, ser::Error as _};
8// self
9use crate::{Dehexify, Hexify, prelude::*};
10
11/// Serialize bytes to string.
12///
13/// # Examples
14/// ```
15/// use serde::Serialize;
16///
17/// #[derive(Debug, PartialEq, Serialize)]
18/// struct Ljf {
19/// #[serde(serialize_with = "array_bytes::ser_bytes_stringify")]
20/// _0: Vec<u8>,
21/// }
22///
23/// assert_eq!(
24/// serde_json::to_string::<Ljf>(&Ljf { _0: b"Love Jane Forever".to_vec() }).unwrap(),
25/// r#"{"_0":"Love Jane Forever"}"#
26/// );
27/// ```
28pub fn ser_bytes_stringify<S, T>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
29where
30 S: Serializer,
31 T: AsRef<[u8]>,
32{
33 serializer.serialize_str(str::from_utf8(value.as_ref()).map_err(S::Error::custom)?)
34}
35
36/// Serialize `T` to hex.
37///
38/// # Examples
39/// ```
40/// use serde::Serialize;
41///
42/// #[derive(Debug, PartialEq, Serialize)]
43/// struct Ljf {
44/// #[serde(serialize_with = "array_bytes::ser_hexify")]
45/// _0: u8,
46/// #[serde(serialize_with = "array_bytes::ser_hexify")]
47/// _1: u16,
48/// #[serde(serialize_with = "array_bytes::ser_hexify")]
49/// _2: u32,
50/// #[serde(serialize_with = "array_bytes::ser_hexify")]
51/// _3: [u8; 4],
52/// }
53///
54/// assert_eq!(
55/// serde_json::to_string::<Ljf>(&Ljf { _0: 5, _1: 2, _2: 0, _3: [1, 3, 1, 4] }).unwrap(),
56/// r#"{"_0":"5","_1":"2","_2":"0","_3":"01030104"}"#
57/// );
58/// ```
59pub fn ser_hexify<S, T>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
60where
61 S: Serializer,
62 T: Hexify,
63{
64 serializer.serialize_str(&value.hexify())
65}
66
67/// Serialize `T` to hex with uppercase.
68///
69/// # Examples
70/// ```
71/// use serde::Serialize;
72///
73/// #[derive(Debug, PartialEq, Serialize)]
74/// struct Ljf {
75/// #[serde(serialize_with = "array_bytes::ser_hexify_upper")]
76/// _0: u8,
77/// #[serde(serialize_with = "array_bytes::ser_hexify_upper")]
78/// _1: u16,
79/// #[serde(serialize_with = "array_bytes::ser_hexify_upper")]
80/// _2: u32,
81/// #[serde(serialize_with = "array_bytes::ser_hexify_upper")]
82/// _3: [u8; 4],
83/// }
84///
85/// assert_eq!(
86/// serde_json::to_string::<Ljf>(&Ljf { _0: 5, _1: 2, _2: 0, _3: [1, 3, 1, 4] }).unwrap(),
87/// r#"{"_0":"5","_1":"2","_2":"0","_3":"01030104"}"#
88/// );
89/// ```
90pub fn ser_hexify_upper<S, T>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
91where
92 S: Serializer,
93 T: Hexify,
94{
95 serializer.serialize_str(&value.hexify_upper())
96}
97
98/// Serialize `T` to hex with `0x` prefix.
99///
100/// # Examples
101/// ```
102/// use serde::Serialize;
103///
104/// #[derive(Debug, PartialEq, Serialize)]
105/// struct Ljf {
106/// #[serde(serialize_with = "array_bytes::ser_hexify_prefixed")]
107/// _0: u8,
108/// #[serde(serialize_with = "array_bytes::ser_hexify_prefixed")]
109/// _1: u16,
110/// #[serde(serialize_with = "array_bytes::ser_hexify_prefixed")]
111/// _2: u32,
112/// #[serde(serialize_with = "array_bytes::ser_hexify_prefixed")]
113/// _3: [u8; 4],
114/// }
115///
116/// assert_eq!(
117/// serde_json::to_string::<Ljf>(&Ljf { _0: 5, _1: 2, _2: 0, _3: [1, 3, 1, 4] }).unwrap(),
118/// r#"{"_0":"0x5","_1":"0x2","_2":"0x0","_3":"0x01030104"}"#
119/// );
120/// ```
121pub fn ser_hexify_prefixed<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
122where
123 T: Hexify,
124 S: Serializer,
125{
126 serializer.serialize_str(&value.hexify_prefixed())
127}
128
129/// Serialize `T` to hex with `0x` prefix and uppercase.
130///
131/// # Examples
132/// ```
133/// use serde::Serialize;
134///
135/// #[derive(Debug, PartialEq, Serialize)]
136/// struct Ljf {
137/// #[serde(serialize_with = "array_bytes::ser_hexify_prefixed")]
138/// _0: u8,
139/// #[serde(serialize_with = "array_bytes::ser_hexify_prefixed")]
140/// _1: u16,
141/// #[serde(serialize_with = "array_bytes::ser_hexify_prefixed")]
142/// _2: u32,
143/// #[serde(serialize_with = "array_bytes::ser_hexify_prefixed")]
144/// _3: [u8; 4],
145/// }
146///
147/// assert_eq!(
148/// serde_json::to_string::<Ljf>(&Ljf { _0: 5, _1: 2, _2: 0, _3: [1, 3, 1, 4] }).unwrap(),
149/// r#"{"_0":"0x5","_1":"0x2","_2":"0x0","_3":"0x01030104"}"#
150/// );
151/// ```
152pub fn ser_hexify_prefixed_upper<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
153where
154 S: Serializer,
155 T: Hexify,
156{
157 serializer.serialize_str(&value.hexify_prefixed_upper())
158}
159
160/// Deserialize string to bytes.
161///
162/// # Examples
163/// ```
164/// use serde::Deserialize;
165///
166/// #[derive(Debug, PartialEq, Deserialize)]
167/// struct Ljf {
168/// #[serde(deserialize_with = "array_bytes::de_bytes_destringify")]
169/// _0: Vec<u8>,
170/// }
171///
172/// assert_eq!(
173/// serde_json::from_str::<Ljf>(r#"{"_0":"Love Jane Forever"}"#).unwrap(),
174/// Ljf { _0: b"Love Jane Forever".to_vec() }
175/// );
176/// ```
177pub fn de_bytes_destringify<'de, D>(str: D) -> Result<Vec<u8>, D::Error>
178where
179 D: Deserializer<'de>,
180{
181 let str = <&str>::deserialize(str)?;
182
183 Ok(str.as_bytes().to_vec())
184}
185
186/// Deserialize hex to `T`.
187///
188/// # Examples
189/// ```
190/// use serde::Deserialize;
191///
192/// #[derive(Debug, PartialEq, Deserialize)]
193/// struct Ljf {
194/// #[serde(deserialize_with = "array_bytes::de_dehexify")]
195/// _0: u8,
196/// #[serde(deserialize_with = "array_bytes::de_dehexify")]
197/// _1: u16,
198/// #[serde(deserialize_with = "array_bytes::de_dehexify")]
199/// _2: u32,
200/// #[serde(deserialize_with = "array_bytes::de_dehexify")]
201/// _3: [u8; 4],
202/// }
203///
204/// assert_eq!(
205/// serde_json::from_str::<Ljf>(
206/// r#"{
207/// "_0": "0x5",
208/// "_1": "0x2",
209/// "_2": "0x0",
210/// "_3": "0x01030104"
211/// }"#
212/// )
213/// .unwrap(),
214/// Ljf { _0: 5, _1: 2, _2: 0, _3: [1, 3, 1, 4] }
215/// );
216/// ```
217pub fn de_dehexify<'de, D, T>(hex: D) -> Result<T, D::Error>
218where
219 D: Deserializer<'de>,
220 T: Dehexify,
221{
222 let hex = <&str>::deserialize(hex)?;
223
224 T::dehexify(hex).map_err(|e| D::Error::custom(alloc::format!("{e:?}")))
225}
226
227/// Deserialize hex to `T` where `T: From<Vec<u8>>`.
228///
229/// # Examples
230/// ```
231/// use serde::Deserialize;
232///
233/// #[derive(Debug, PartialEq)]
234/// struct Ljf(Vec<u8>);
235/// impl From<Vec<u8>> for Ljf {
236/// fn from(vec: Vec<u8>) -> Self {
237/// Self(vec)
238/// }
239/// }
240///
241/// #[derive(Debug, PartialEq, Deserialize)]
242/// struct WrappedLjf {
243/// #[serde(deserialize_with = "array_bytes::dehexify_vec_then_deserialize_into")]
244/// ljf: Ljf,
245/// }
246///
247/// assert_eq!(
248/// serde_json::from_str::<WrappedLjf>(r#"{
249/// "ljf": "0x4c6f7665204a616e6520466f7265766572"
250/// }"#).unwrap(),
251/// WrappedLjf {
252/// ljf: Ljf(b"Love Jane Forever".to_vec())
253/// }
254/// );
255pub fn dehexify_vec_then_deserialize_into<'de, D, T>(hex: D) -> Result<T, D::Error>
256where
257 D: Deserializer<'de>,
258 T: From<Vec<u8>>,
259{
260 let hex = <&str>::deserialize(hex)?;
261
262 <Vec<u8>>::dehexify(hex).map(|sv| sv.into()).map_err(|e| D::Error::custom(format!("{e:?}")))
263}
264#[test]
265fn dehexify_vec_then_deserialize_into_should_work() {
266 #[derive(Debug, PartialEq, Deserialize)]
267 struct WrappedLjf {
268 #[serde(deserialize_with = "dehexify_vec_then_deserialize_into")]
269 ljf: Ljf,
270 }
271
272 assert_eq!(
273 serde_json::from_str::<WrappedLjf>(
274 r#"{
275 "ljf": "0x4c6f7665204a616e6520466f7265766572"
276 }"#
277 )
278 .unwrap(),
279 WrappedLjf { ljf: Ljf(b"Love Jane Forever".to_vec()) }
280 );
281 assert_eq!(
282 serde_json::from_str::<WrappedLjf>(
283 r#"{
284 "ljf": "4c6f7665204a616e6520466f7265766572"
285 }"#
286 )
287 .unwrap(),
288 WrappedLjf { ljf: Ljf(b"Love Jane Forever".to_vec()) }
289 );
290}
291
292/// Deserialize hex to `T` where `T: From<[u8; N]>`.
293///
294/// # Examples
295/// ```
296/// use serde::Deserialize;
297///
298/// #[derive(Debug, PartialEq)]
299/// struct Ljf([u8; 17]);
300/// impl From<[u8; 17]> for Ljf {
301/// fn from(array: [u8; 17]) -> Self {
302/// Self(array)
303/// }
304/// }
305///
306/// #[derive(Debug, PartialEq, Deserialize)]
307/// struct WrappedLjf {
308/// #[serde(deserialize_with = "array_bytes::dehexify_array_then_deserialize_into")]
309/// ljf: Ljf,
310/// }
311///
312/// assert_eq!(
313/// serde_json::from_str::<WrappedLjf>(r#"{
314/// "ljf": "0x4c6f7665204a616e6520466f7265766572"
315/// }"#).unwrap(),
316/// WrappedLjf {
317/// ljf: Ljf(*b"Love Jane Forever")
318/// }
319/// );
320pub fn dehexify_array_then_deserialize_into<'de, D, T, const N: usize>(
321 hex: D,
322) -> Result<T, D::Error>
323where
324 D: Deserializer<'de>,
325 T: From<[u8; N]>,
326{
327 let hex = <&str>::deserialize(hex)?;
328
329 <[u8; N]>::dehexify(hex).map(Into::into).map_err(|e| D::Error::custom(format!("{e:?}")))
330}
331#[test]
332fn dehexify_array_then_deserialize_into_should_work() {
333 #[derive(Debug, PartialEq, Deserialize)]
334 struct WrappedLjf {
335 #[serde(deserialize_with = "dehexify_array_then_deserialize_into")]
336 ljf: Ljfn,
337 }
338
339 assert_eq!(
340 serde_json::from_str::<WrappedLjf>(
341 r#"{
342 "ljf": "0x4c6f7665204a616e6520466f7265766572"
343 }"#
344 )
345 .unwrap(),
346 WrappedLjf { ljf: Ljfn(*b"Love Jane Forever") }
347 );
348 assert_eq!(
349 serde_json::from_str::<WrappedLjf>(
350 r#"{
351 "ljf": "4c6f7665204a616e6520466f7265766572"
352 }"#
353 )
354 .unwrap(),
355 WrappedLjf { ljf: Ljfn(*b"Love Jane Forever") }
356 );
357}
358
359#[test]
360fn serde_should_work() {
361 #[derive(Debug, PartialEq, Deserialize, Serialize)]
362 struct LjfPredefined {
363 #[serde(deserialize_with = "de_dehexify", serialize_with = "ser_hexify")]
364 _0: u8,
365 #[serde(deserialize_with = "de_dehexify", serialize_with = "ser_hexify_upper")]
366 _1: u16,
367 #[serde(deserialize_with = "de_dehexify", serialize_with = "ser_hexify_prefixed")]
368 _2: u32,
369 #[serde(deserialize_with = "de_dehexify", serialize_with = "ser_hexify_prefixed_upper")]
370 _3: u64,
371 #[serde(deserialize_with = "de_dehexify", serialize_with = "ser_hexify")]
372 _4: u128,
373 #[serde(deserialize_with = "de_dehexify", serialize_with = "ser_hexify_upper")]
374 _5: usize,
375 #[serde(deserialize_with = "de_dehexify", serialize_with = "ser_hexify_prefixed")]
376 _6: [u8; 17],
377 #[serde(deserialize_with = "de_dehexify", serialize_with = "ser_hexify_prefixed_upper")]
378 _7: Vec<u8>,
379 #[serde(deserialize_with = "de_bytes_destringify", serialize_with = "ser_bytes_stringify")]
380 _8: Vec<u8>,
381 }
382 impl Default for LjfPredefined {
383 fn default() -> Self {
384 Self {
385 _0: 52,
386 _1: 520,
387 _2: 5_201_314,
388 _3: 5_201_314,
389 _4: 5_201_314,
390 _5: 5_201_314,
391 _6: *b"Love Jane Forever",
392 _7: b"Love Jane Forever".to_vec(),
393 _8: b"Love Jane Forever".to_vec(),
394 }
395 }
396 }
397
398 let ljf = LjfPredefined::default();
399 let result = serde_json::to_string(&ljf);
400 assert!(result.is_ok());
401
402 let json = result.unwrap();
403 assert_eq!(
404 json,
405 r#"{"_0":"34","_1":"208","_2":"0x4f5da2","_3":"0x4F5DA2","_4":"4f5da2","_5":"4F5DA2","_6":"0x4c6f7665204a616e6520466f7265766572","_7":"0x4C6F7665204A616E6520466F7265766572","_8":"Love Jane Forever"}"#
406 );
407
408 let result = serde_json::from_str::<LjfPredefined>(&json);
409 assert!(result.is_ok());
410 assert_eq!(result.unwrap(), ljf);
411}