1use serde::{
2 de::{Error, Unexpected, Visitor},
3 Deserialize, Deserializer, Serialize, Serializer,
4};
5use std::fmt;
6
7#[derive(Clone, Default, PartialEq, Eq, Hash)]
9pub struct Bytes(pub Vec<u8>);
10
11impl<T: Into<Vec<u8>>> From<T> for Bytes {
12 fn from(data: T) -> Self {
13 Bytes(data.into())
14 }
15}
16
17impl Serialize for Bytes {
18 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
19 where
20 S: Serializer,
21 {
22 let mut serialized = "0x".to_owned();
23 serialized.push_str(&hex::encode(&self.0));
24 serializer.serialize_str(serialized.as_ref())
25 }
26}
27
28impl<'a> Deserialize<'a> for Bytes {
29 fn deserialize<D>(deserializer: D) -> Result<Bytes, D::Error>
30 where
31 D: Deserializer<'a>,
32 {
33 deserializer.deserialize_identifier(BytesVisitor)
34 }
35}
36
37impl fmt::Debug for Bytes {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 let serialized = format!("0x{}", hex::encode(&self.0));
40 f.debug_tuple("Bytes").field(&serialized).finish()
41 }
42}
43
44struct BytesVisitor;
45
46impl<'a> Visitor<'a> for BytesVisitor {
47 type Value = Bytes;
48
49 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
50 write!(formatter, "a 0x-prefixed hex-encoded vector of bytes")
51 }
52
53 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
54 where
55 E: Error,
56 {
57 if let Some(value) = value.strip_prefix("0x") {
58 let bytes = hex::decode(value).map_err(|e| Error::custom(format!("Invalid hex: {}", e)))?;
59 Ok(Bytes(bytes))
60 } else {
61 Err(Error::invalid_value(Unexpected::Str(value), &"0x prefix"))
62 }
63 }
64
65 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
66 where
67 E: Error,
68 {
69 self.visit_str(value.as_ref())
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76
77 #[test]
78 fn deserialize() {
79 assert_eq!(serde_json::from_str::<Bytes>(r#""0x00""#).unwrap(), Bytes(vec![0x00]));
80 assert_eq!(
81 serde_json::from_str::<Bytes>(r#""0x0123456789AaBbCcDdEeFf""#).unwrap(),
82 Bytes(vec![0x01, 0x23, 0x45, 0x67, 0x89, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF])
83 );
84 assert_eq!(serde_json::from_str::<Bytes>(r#""0x""#).unwrap(), Bytes(vec![]));
85
86 assert!(serde_json::from_str::<Bytes>("0").is_err(), "Not a string");
87 assert!(serde_json::from_str::<Bytes>(r#""""#).is_err(), "Empty string");
88 assert!(serde_json::from_str::<Bytes>(r#""0xZZ""#).is_err(), "Invalid hex");
89 assert!(
90 serde_json::from_str::<Bytes>(r#""deadbeef""#).is_err(),
91 "Missing 0x prefix"
92 );
93 assert!(serde_json::from_str::<Bytes>(r#""数字""#).is_err(), "Non-ASCII");
94 assert!(serde_json::from_str::<Bytes>(r#""0x数字""#).is_err(), "Non-ASCII");
95 }
96}