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}