use core::str;
use alloc::format;
#[cfg(test)] use serde::Serialize;
use serde::{Deserialize, Deserializer, Serializer, de::Error as _, ser::Error as _};
use crate::{Dehexify, Hexify, prelude::*};
pub fn ser_bytes_stringify<S, T>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
T: AsRef<[u8]>,
{
serializer.serialize_str(str::from_utf8(value.as_ref()).map_err(S::Error::custom)?)
}
pub fn ser_hexify<S, T>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
T: Hexify,
{
serializer.serialize_str(&value.hexify())
}
pub fn ser_hexify_upper<S, T>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
T: Hexify,
{
serializer.serialize_str(&value.hexify_upper())
}
pub fn ser_hexify_prefixed<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
where
T: Hexify,
S: Serializer,
{
serializer.serialize_str(&value.hexify_prefixed())
}
pub fn ser_hexify_prefixed_upper<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
T: Hexify,
{
serializer.serialize_str(&value.hexify_prefixed_upper())
}
pub fn de_bytes_destringify<'de, D>(str: D) -> Result<Vec<u8>, D::Error>
where
D: Deserializer<'de>,
{
let str = <&str>::deserialize(str)?;
Ok(str.as_bytes().to_vec())
}
pub fn de_dehexify<'de, D, T>(hex: D) -> Result<T, D::Error>
where
D: Deserializer<'de>,
T: Dehexify,
{
let hex = <&str>::deserialize(hex)?;
T::dehexify(hex).map_err(|e| D::Error::custom(alloc::format!("{e:?}")))
}
pub fn dehexify_vec_then_deserialize_into<'de, D, T>(hex: D) -> Result<T, D::Error>
where
D: Deserializer<'de>,
T: From<Vec<u8>>,
{
let hex = <&str>::deserialize(hex)?;
<Vec<u8>>::dehexify(hex).map(|sv| sv.into()).map_err(|e| D::Error::custom(format!("{e:?}")))
}
#[test]
fn dehexify_vec_then_deserialize_into_should_work() {
#[derive(Debug, PartialEq, Deserialize)]
struct WrappedLjf {
#[serde(deserialize_with = "dehexify_vec_then_deserialize_into")]
ljf: Ljf,
}
assert_eq!(
serde_json::from_str::<WrappedLjf>(
r#"{
"ljf": "0x4c6f7665204a616e6520466f7265766572"
}"#
)
.unwrap(),
WrappedLjf { ljf: Ljf(b"Love Jane Forever".to_vec()) }
);
assert_eq!(
serde_json::from_str::<WrappedLjf>(
r#"{
"ljf": "4c6f7665204a616e6520466f7265766572"
}"#
)
.unwrap(),
WrappedLjf { ljf: Ljf(b"Love Jane Forever".to_vec()) }
);
}
pub fn dehexify_array_then_deserialize_into<'de, D, T, const N: usize>(
hex: D,
) -> Result<T, D::Error>
where
D: Deserializer<'de>,
T: From<[u8; N]>,
{
let hex = <&str>::deserialize(hex)?;
<[u8; N]>::dehexify(hex).map(Into::into).map_err(|e| D::Error::custom(format!("{e:?}")))
}
#[test]
fn dehexify_array_then_deserialize_into_should_work() {
#[derive(Debug, PartialEq, Deserialize)]
struct WrappedLjf {
#[serde(deserialize_with = "dehexify_array_then_deserialize_into")]
ljf: Ljfn,
}
assert_eq!(
serde_json::from_str::<WrappedLjf>(
r#"{
"ljf": "0x4c6f7665204a616e6520466f7265766572"
}"#
)
.unwrap(),
WrappedLjf { ljf: Ljfn(*b"Love Jane Forever") }
);
assert_eq!(
serde_json::from_str::<WrappedLjf>(
r#"{
"ljf": "4c6f7665204a616e6520466f7265766572"
}"#
)
.unwrap(),
WrappedLjf { ljf: Ljfn(*b"Love Jane Forever") }
);
}
#[test]
fn serde_should_work() {
#[derive(Debug, PartialEq, Deserialize, Serialize)]
struct LjfPredefined {
#[serde(deserialize_with = "de_dehexify", serialize_with = "ser_hexify")]
_0: u8,
#[serde(deserialize_with = "de_dehexify", serialize_with = "ser_hexify_upper")]
_1: u16,
#[serde(deserialize_with = "de_dehexify", serialize_with = "ser_hexify_prefixed")]
_2: u32,
#[serde(deserialize_with = "de_dehexify", serialize_with = "ser_hexify_prefixed_upper")]
_3: u64,
#[serde(deserialize_with = "de_dehexify", serialize_with = "ser_hexify")]
_4: u128,
#[serde(deserialize_with = "de_dehexify", serialize_with = "ser_hexify_upper")]
_5: usize,
#[serde(deserialize_with = "de_dehexify", serialize_with = "ser_hexify_prefixed")]
_6: [u8; 17],
#[serde(deserialize_with = "de_dehexify", serialize_with = "ser_hexify_prefixed_upper")]
_7: Vec<u8>,
#[serde(deserialize_with = "de_bytes_destringify", serialize_with = "ser_bytes_stringify")]
_8: Vec<u8>,
}
impl Default for LjfPredefined {
fn default() -> Self {
Self {
_0: 52,
_1: 520,
_2: 5_201_314,
_3: 5_201_314,
_4: 5_201_314,
_5: 5_201_314,
_6: *b"Love Jane Forever",
_7: b"Love Jane Forever".to_vec(),
_8: b"Love Jane Forever".to_vec(),
}
}
}
let ljf = LjfPredefined::default();
let result = serde_json::to_string(&ljf);
assert!(result.is_ok());
let json = result.unwrap();
assert_eq!(
json,
r#"{"_0":"34","_1":"208","_2":"0x4f5da2","_3":"0x4F5DA2","_4":"4f5da2","_5":"4F5DA2","_6":"0x4c6f7665204a616e6520466f7265766572","_7":"0x4C6F7665204A616E6520466F7265766572","_8":"Love Jane Forever"}"#
);
let result = serde_json::from_str::<LjfPredefined>(&json);
assert!(result.is_ok());
assert_eq!(result.unwrap(), ljf);
}