From 82e35f8deb14684caf7ee2b6054dcd7fba123e17 Mon Sep 17 00:00:00 2001 From: Eval EXEC Date: Thu, 2 Mar 2023 10:47:47 +0800 Subject: [PATCH] wip serde Signed-off-by: Eval EXEC --- src/serde.rs | 81 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 63 insertions(+), 18 deletions(-) diff --git a/src/serde.rs b/src/serde.rs index e7a9e0c..56a76e2 100644 --- a/src/serde.rs +++ b/src/serde.rs @@ -40,16 +40,16 @@ where D: Deserializer<'de>, T: FromIterator, { - let raw: &[u8] = serde::Deserialize::deserialize(deserializer)?; - if with_prefix && (raw.len() < 2 || raw[0] != b'0' || raw[1] != b'x') { + let raw_src: &[u8] = serde::Deserialize::deserialize(deserializer)?; + if with_prefix && (raw_src.len() < 2 || raw_src[0] != b'0' || raw_src[1] != b'x') { return Err(D::Error::custom("invalid prefix".to_string())); } let src: &[u8] = { if with_prefix { - &raw[2..] + &raw_src[2..] } else { - raw + raw_src } }; @@ -57,7 +57,8 @@ where return Err(D::Error::custom("invalid length".to_string())); } - let mut buffer = vec![0; raw.len() >> 1]; // we checked length + // we have already checked src's length, so src's length is a even integer + let mut dst = vec![0; src.len() >> 1]; let check_case = { if with_cap { CheckCase::Upper @@ -66,9 +67,9 @@ where } }; - hex_decode_with_case(src, &mut buffer, check_case) + hex_decode_with_case(src, &mut dst, check_case) .map_err(|e| Error::custom(format!("{:?}", e)))?; - Ok(buffer.into_iter().collect()) + Ok(dst.into_iter().collect()) } /// Serialize and deserialize without 0x-prefix and lowercase @@ -168,6 +169,8 @@ mod tests { use super::{strict, strict_cap, strict_pfx, strict_pfx_cap}; use bytes::Bytes; + use proptest::proptest; + #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] struct Foo { #[serde(with = "strict")] @@ -192,18 +195,60 @@ mod tests { } #[test] - fn serde_basic() { + fn test_serde_default() { + { + let foo_defuault = Foo { + bar_strict_vec: vec![], + bar_strict_bytes: Default::default(), + bar_strict_pfx_vec: vec![], + bar_strict_pfx_bytes: Default::default(), + bar_strict_cap_vec: vec![], + bar_strict_cap_bytes: Default::default(), + bar_strict_pfx_cap_vec: vec![], + bar_strict_pfx_cap_bytes: Default::default(), + }; + let serde_result = serde_json::to_string(&foo_defuault).unwrap(); + let expect = "{\"bar_strict_vec\":\"\",\"bar_strict_bytes\":\"\",\"bar_strict_pfx_vec\":\"0x\",\"bar_strict_pfx_bytes\":\"0x\",\"bar_strict_cap_vec\":\"\",\"bar_strict_cap_bytes\":\"\",\"bar_strict_pfx_cap_vec\":\"0x\",\"bar_strict_pfx_cap_bytes\":\"0x\"}"; + assert_eq!(serde_result, expect); + + let foo_src: Foo = serde_json::from_str(&serde_result).unwrap(); + assert_eq!(foo_defuault, foo_src); + } + } + + fn _test_serde(src: &str) { let foo = Foo { - bar_strict_vec: vec![], - bar_strict_bytes: Default::default(), - bar_strict_pfx_vec: vec![], - bar_strict_pfx_bytes: Default::default(), - bar_strict_cap_vec: vec![], - bar_strict_cap_bytes: Default::default(), - bar_strict_pfx_cap_vec: vec![], - bar_strict_pfx_cap_bytes: Default::default(), + bar_strict_vec: Vec::from(src), + bar_strict_bytes: Bytes::from(Vec::from(src)), + bar_strict_pfx_vec: Vec::from(src), + bar_strict_pfx_bytes: Bytes::from(Vec::from(src)), + bar_strict_cap_vec: src.into(), + bar_strict_cap_bytes: Bytes::from(Vec::from(src)), + bar_strict_pfx_cap_vec: src.into(), + bar_strict_pfx_cap_bytes: Bytes::from(Vec::from(src)), }; - let v = serde_json::to_string(&foo).unwrap(); - println!("{v}") + let hex_str = hex::encode(src); + let serde_result = serde_json::to_string(&foo).unwrap(); + let expect = format!("{{\"bar_strict_vec\":\"{}\",\"bar_strict_bytes\":\"{}\",\"bar_strict_pfx_vec\":\"0x{}\",\"bar_strict_pfx_bytes\":\"0x{}\",\"bar_strict_cap_vec\":\"{}\",\"bar_strict_cap_bytes\":\"{}\",\"bar_strict_pfx_cap_vec\":\"0x{}\",\"bar_strict_pfx_cap_bytes\":\"0x{}\"}}", + hex_str, + hex_str, + hex_str, + hex_str, + hex_str.to_uppercase(), + hex_str.to_uppercase(), + hex_str.to_uppercase(), + hex_str.to_uppercase()); + + assert_eq!(serde_result, expect); + + let foo_src: Foo = serde_json::from_str(&serde_result).unwrap(); + assert_eq!(foo, foo_src); + } + + proptest! { + #[test] + fn test_serde(ref s in ".*") { + _test_serde(s); + } } }