1use core::{
2 fmt::{Formatter, Result as FmtResult},
3 str,
4};
5use serde::{
6 de::{Error as DeError, Visitor},
7 Deserializer, Serializer,
8};
9use tiny_keccak::{Hasher as _, Keccak};
10
11pub fn keccak256(bytes: &[u8]) -> [u8; 32] {
12 let mut output = [0; 32];
13 let mut hasher = Keccak::v256();
14 hasher.update(bytes);
15 hasher.finalize(&mut output);
16 output
17}
18
19pub fn bytes_to_hex<const N: usize, const M: usize>(bytes: &[u8; N]) -> [u8; M] {
20 debug_assert_eq!(M, 2 * N + 2);
22 let mut result = [0u8; M];
23 result[0] = b'0';
24 result[1] = b'x';
25 hex::encode_to_slice(&bytes[..], &mut result[2..]).expect("the buffer is correctly sized");
26 result
27}
28
29pub fn serialize_bytes<const N: usize, const M: usize, S: Serializer>(
31 serializer: S,
32 bytes: &[u8; N],
33) -> Result<S::Ok, S::Error> {
34 debug_assert_eq!(M, 2 * N + 2);
36 if serializer.is_human_readable() {
37 let buffer = bytes_to_hex::<N, M>(bytes);
39 let string = str::from_utf8(&buffer).expect("the buffer is valid UTF-8");
40 serializer.serialize_str(string)
41 } else {
42 serializer.serialize_bytes(&bytes[..])
44 }
45}
46
47pub fn bytes_from_hex<const N: usize>(s: &str) -> Result<[u8; N], hex::FromHexError> {
51 let str = trim_hex_prefix(s);
52 let mut result = [0_u8; N];
53 hex::decode_to_slice(str, &mut result)?;
54 Ok(result)
55}
56
57fn trim_hex_prefix(str: &str) -> &str {
59 str.trim_start_matches("0x").trim_start_matches("0X")
60}
61
62pub fn deserialize_bytes<'de, const N: usize, D: Deserializer<'de>>(
64 deserializer: D,
65) -> Result<[u8; N], D::Error> {
66 if deserializer.is_human_readable() {
67 struct StrVisitor<const N: usize>;
68 impl<const N: usize> Visitor<'_> for StrVisitor<N> {
69 type Value = [u8; N];
70
71 fn expecting(&self, formatter: &mut Formatter) -> FmtResult {
72 write!(formatter, "a {N} byte hex string")
73 }
74
75 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
76 where
77 E: DeError,
78 {
79 bytes_from_hex(value).map_err(|e| E::custom(format!("Error in hex: {e}")))
80 }
81 }
82 deserializer.deserialize_str(StrVisitor)
83 } else {
84 struct ByteVisitor<const N: usize>;
85 impl<const N: usize> Visitor<'_> for ByteVisitor<N> {
86 type Value = [u8; N];
87
88 fn expecting(&self, formatter: &mut Formatter) -> FmtResult {
89 write!(formatter, "{N} bytes of binary data")
90 }
91
92 fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
93 where
94 E: DeError,
95 {
96 if value.len() != N {
97 return Err(E::invalid_length(value.len(), &self));
98 }
99 let mut result = [0_u8; N];
100 result.copy_from_slice(value);
101 Ok(result)
102 }
103 }
104 deserializer.deserialize_bytes(ByteVisitor)
105 }
106}
107
108#[cfg(test)]
109mod test {
110 use super::*;
111
112 #[test]
113 fn test_serialize_bytes_hex() {
114 let bytes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
115 let mut ser = serde_json::Serializer::new(Vec::new());
116 serialize_bytes::<16, 34, _>(&mut ser, &bytes).unwrap();
117 let json = ser.into_inner();
118 assert_eq!(json, b"\"0x0102030405060708090a0b0c0d0e0f10\"");
119 }
120
121 #[test]
122 fn test_serialize_bytes_bin() {
123 let bytes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
124 let mut bin: Vec<u8> = Vec::new();
125 {
126 let mut ser = bincode::Serializer::new(&mut bin, bincode::options());
127 serialize_bytes::<16, 34, _>(&mut ser, &bytes).unwrap();
128 }
129 assert_eq!(
131 bin,
132 [16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
133 );
134 }
135}