|
|
@@ -0,0 +1,83 @@
|
|
|
+pub mod hex {
|
|
|
+ use {
|
|
|
+ hex::FromHex,
|
|
|
+ serde::{
|
|
|
+ de::IntoDeserializer,
|
|
|
+ Deserialize,
|
|
|
+ Deserializer,
|
|
|
+ Serializer,
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+ pub fn serialize<S, const N: usize>(b: &[u8; N], s: S) -> Result<S::Ok, S::Error>
|
|
|
+ where
|
|
|
+ S: Serializer,
|
|
|
+ {
|
|
|
+ s.serialize_str(hex::encode(b).as_str())
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn deserialize<'de, D, R>(d: D) -> Result<R, D::Error>
|
|
|
+ where
|
|
|
+ D: Deserializer<'de>,
|
|
|
+ R: FromHex,
|
|
|
+ <R as hex::FromHex>::Error: std::fmt::Display,
|
|
|
+ {
|
|
|
+ let s: String = Deserialize::deserialize(d)?;
|
|
|
+ let p = s.starts_with("0x") || s.starts_with("0X");
|
|
|
+ let s = if p { &s[2..] } else { &s[..] };
|
|
|
+ hex::serde::deserialize(s.into_deserializer())
|
|
|
+ }
|
|
|
+
|
|
|
+ #[cfg(test)]
|
|
|
+ mod tests {
|
|
|
+ use serde::Deserialize;
|
|
|
+
|
|
|
+ #[derive(Debug, Deserialize, PartialEq)]
|
|
|
+ struct H(#[serde(with = "super")] [u8; 32]);
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn test_deserialize() {
|
|
|
+ let e = H([
|
|
|
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
|
|
|
+ 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67,
|
|
|
+ 0x89, 0xab, 0xcd, 0xef,
|
|
|
+ ]);
|
|
|
+
|
|
|
+ let l = "\"0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"";
|
|
|
+ let u = "\"0x0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\"";
|
|
|
+ assert_eq!(serde_json::from_str::<H>(l).unwrap(), e);
|
|
|
+ assert_eq!(serde_json::from_str::<H>(u).unwrap(), e);
|
|
|
+
|
|
|
+ let l = "\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"";
|
|
|
+ let u = "\"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\"";
|
|
|
+ assert_eq!(serde_json::from_str::<H>(l).unwrap(), e);
|
|
|
+ assert_eq!(serde_json::from_str::<H>(u).unwrap(), e);
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn test_deserialize_invalid_length() {
|
|
|
+ let l = "\"0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde\"";
|
|
|
+ let u = "\"0X0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE\"";
|
|
|
+ assert!(serde_json::from_str::<H>(l).is_err());
|
|
|
+ assert!(serde_json::from_str::<H>(u).is_err());
|
|
|
+
|
|
|
+ let l = "\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde\"";
|
|
|
+ let u = "\"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE\"";
|
|
|
+ assert!(serde_json::from_str::<H>(l).is_err());
|
|
|
+ assert!(serde_json::from_str::<H>(u).is_err());
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn test_deserialize_invalid_hex() {
|
|
|
+ let l = "\"0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdeg\"";
|
|
|
+ let u = "\"0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdeg\"";
|
|
|
+ assert!(serde_json::from_str::<H>(l).is_err());
|
|
|
+ assert!(serde_json::from_str::<H>(u).is_err());
|
|
|
+
|
|
|
+ let l = "\"0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdeg\"";
|
|
|
+ let u = "\"0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdeg\"";
|
|
|
+ assert!(serde_json::from_str::<H>(l).is_err());
|
|
|
+ assert!(serde_json::from_str::<H>(u).is_err());
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|