serde_encoded_bytes/encoding/
hex.rs1use alloc::{format, string::String, vec::Vec};
2
3use serde::de;
4
5use super::Encoding;
6
7pub struct Hex;
9
10impl Encoding for Hex {
11 fn encode(bytes: &[u8]) -> String {
12 format!("0x{}", hex::encode(bytes))
13 }
14
15 fn decode<E: de::Error>(string: &str) -> Result<Vec<u8>, E> {
16 let digits = string.strip_prefix("0x").ok_or_else(|| {
17 de::Error::invalid_value(
18 de::Unexpected::Str(string),
19 &"0x-prefixed hex-encoded bytes",
20 )
21 })?;
22 hex::decode(digits).map_err(de::Error::custom)
23 }
24}
25
26#[cfg(test)]
27mod tests {
28 use alloc::string::{String, ToString};
29
30 use serde::{Deserialize, Serialize};
31
32 use super::Hex;
33 use crate::ArrayLike;
34
35 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
36 struct ArrayStruct(#[serde(with = "ArrayLike::<Hex>")] [u8; 4]);
37
38 fn hr_serialize<T: Serialize>(value: T) -> Result<String, String> {
39 serde_json::to_string(&value).map_err(|err| err.to_string())
40 }
41
42 fn hr_deserialize<'de, T: Deserialize<'de>>(string: &'de str) -> Result<T, String> {
43 serde_json::from_str::<T>(string).map_err(|err| err.to_string())
44 }
45
46 #[test]
47 fn roundtrip() {
48 let val = ArrayStruct([1, 0xf2, 3, 0xf4]);
49
50 let val_str = hr_serialize(&val).unwrap();
51 assert_eq!(val_str, "\"0x01f203f4\"");
52 let val_back = hr_deserialize::<ArrayStruct>(&val_str).unwrap();
53 assert_eq!(val, val_back);
54 }
55
56 #[test]
57 fn errors() {
58 assert_eq!(
59 hr_deserialize::<ArrayStruct>("\"01f203f4\"").unwrap_err(),
60 concat![
61 "invalid value: string \"01f203f4\", expected 0x-prefixed ",
62 "hex-encoded bytes at line 1 column 10"
63 ]
64 );
65 assert_eq!(
66 hr_deserialize::<ArrayStruct>("\"0\"").unwrap_err(),
67 "invalid value: string \"0\", expected 0x-prefixed hex-encoded bytes at line 1 column 3"
68 );
69 }
70
71 #[test]
72 fn multi_byte_character() {
73 assert_eq!(
81 hr_deserialize::<ArrayStruct>("\"\u{1D01}\"").unwrap_err(),
82 concat![
83 "invalid value: string \"\u{1D01}\", expected 0x-prefixed ",
84 "hex-encoded bytes at line 1 column 5"
85 ]
86 );
87 }
88}