1use std::fmt;
2
3use serde::{
4 de::{self, Visitor},
5 Deserializer, Serializer,
6};
7
8pub fn ser_bytes<S>(value: &[u8], serializer: S, include_0x: bool) -> Result<S::Ok, S::Error>
9where
10 S: Serializer,
11{
12 if serializer.is_human_readable() {
13 if include_0x {
14 serializer.serialize_str(&format!("0x{}", hex::encode(value)))
15 } else {
16 serializer.serialize_str(&hex::encode(value))
17 }
18 } else {
19 serializer.serialize_bytes(value)
20 }
21}
22
23pub fn de_bytes<'de, D, T>(deserializer: D) -> Result<T, D::Error>
24where
25 D: Deserializer<'de>,
26 T: TryFrom<Vec<u8>>,
27{
28 if deserializer.is_human_readable() {
29 struct HexOrBytesVisitor;
30
31 impl Visitor<'_> for HexOrBytesVisitor {
32 type Value = Vec<u8>;
33
34 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
35 formatter.write_str("a byte buffer or hex string with an optional 0x prefix")
36 }
37
38 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> {
39 Ok(v.to_vec())
40 }
41
42 fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E> {
43 Ok(v)
44 }
45
46 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
47 where
48 E: de::Error,
49 {
50 if let Some(rest) = v.strip_prefix("0x") {
51 Ok(hex::decode(rest).map_err(de::Error::custom)?)
52 } else if let Some(rest) = v.strip_prefix("0X") {
53 Ok(hex::decode(rest).map_err(de::Error::custom)?)
54 } else {
55 Ok(hex::decode(v).map_err(de::Error::custom)?)
56 }
57 }
58
59 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
60 where
61 E: de::Error,
62 {
63 self.visit_str(&v)
64 }
65 }
66
67 let bytes = deserializer.deserialize_any(HexOrBytesVisitor)?;
68 let length = bytes.len();
69
70 bytes.try_into().map_err(|_: T::Error| {
71 de::Error::custom(format_args!(
72 "Can't convert a byte buffer of length {length} to the output type."
73 ))
74 })
75 } else {
76 struct BytesVisitor;
77
78 impl Visitor<'_> for BytesVisitor {
79 type Value = Vec<u8>;
80
81 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
82 formatter.write_str("a byte buffer")
83 }
84
85 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> {
86 Ok(v.to_vec())
87 }
88
89 fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E> {
90 Ok(v)
91 }
92 }
93
94 let bytes = deserializer.deserialize_byte_buf(BytesVisitor)?;
95 let length = bytes.len();
96
97 bytes.try_into().map_err(|_: T::Error| {
98 de::Error::custom(format_args!(
99 "Can't convert a byte buffer of length {length} to the output type."
100 ))
101 })
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108
109 use anyhow::Result;
110
111 #[test]
112 fn test_encode_hex() -> Result<()> {
113 let original = b"hello";
114
115 let mut ser = serde_json::Serializer::new(Vec::new());
116 ser_bytes(original, &mut ser, false)?;
117 let result = String::from_utf8(ser.into_inner())?;
118 assert_eq!(result, "\"68656c6c6f\"");
119
120 let mut de = serde_json::Deserializer::from_str(&result);
121 let bytes = de_bytes::<_, Vec<u8>>(&mut de)?;
122 assert_eq!(bytes, original);
123
124 Ok(())
125 }
126
127 #[test]
128 fn test_encode_0x() -> Result<()> {
129 let original = b"hello";
130
131 let mut ser = serde_json::Serializer::new(Vec::new());
132 ser_bytes(original, &mut ser, true)?;
133 let result = String::from_utf8(ser.into_inner())?;
134 assert_eq!(result, "\"0x68656c6c6f\"");
135
136 let mut de = serde_json::Deserializer::from_str(&result);
137 let bytes = de_bytes::<_, Vec<u8>>(&mut de)?;
138 assert_eq!(bytes, original);
139
140 Ok(())
141 }
142
143 #[test]
144 fn test_encode_binary() -> Result<()> {
145 let original = b"hello";
146
147 let mut output = Vec::new();
148 let mut ser = bincode::Serializer::new(&mut output, bincode::options());
149 ser_bytes(original, &mut ser, true)?;
150 assert_eq!(hex::encode(&output), "0568656c6c6f");
151
152 let mut de = bincode::Deserializer::from_slice(&output, bincode::options());
153 let bytes = de_bytes::<_, Vec<u8>>(&mut de)?;
154 assert_eq!(bytes, original);
155
156 Ok(())
157 }
158}