1 //! Hex encoding with `serde`.
2 #[cfg_attr(
3     all(feature = "alloc", feature = "serde"),
4     doc = r##"
5 # Example
6 
7 ```
8 use serde::{Serialize, Deserialize};
9 
10 #[derive(Serialize, Deserialize)]
11 struct Foo {
12     #[serde(with = "hex")]
13     bar: Vec<u8>,
14 }
15 ```
16 "##
17 )]
18 use serde::de::{Error, Visitor};
19 use serde::Deserializer;
20 #[cfg(feature = "alloc")]
21 use serde::Serializer;
22 
23 #[cfg(feature = "alloc")]
24 use alloc::string::String;
25 
26 use core::fmt;
27 use core::marker::PhantomData;
28 
29 use crate::FromHex;
30 
31 #[cfg(feature = "alloc")]
32 use crate::ToHex;
33 
34 /// Serializes `data` as hex string using uppercase characters.
35 ///
36 /// Apart from the characters' casing, this works exactly like `serialize()`.
37 #[cfg(feature = "alloc")]
serialize_upper<S, T>(data: T, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, T: ToHex,38 pub fn serialize_upper<S, T>(data: T, serializer: S) -> Result<S::Ok, S::Error>
39 where
40     S: Serializer,
41     T: ToHex,
42 {
43     let s = data.encode_hex_upper::<String>();
44     serializer.serialize_str(&s)
45 }
46 
47 /// Serializes `data` as hex string using lowercase characters.
48 ///
49 /// Lowercase characters are used (e.g. `f9b4ca`). The resulting string's length
50 /// is always even, each byte in data is always encoded using two hex digits.
51 /// Thus, the resulting string contains exactly twice as many bytes as the input
52 /// data.
53 #[cfg(feature = "alloc")]
serialize<S, T>(data: T, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, T: ToHex,54 pub fn serialize<S, T>(data: T, serializer: S) -> Result<S::Ok, S::Error>
55 where
56     S: Serializer,
57     T: ToHex,
58 {
59     let s = data.encode_hex::<String>();
60     serializer.serialize_str(&s)
61 }
62 
63 /// Deserializes a hex string into raw bytes.
64 ///
65 /// Both, upper and lower case characters are valid in the input string and can
66 /// even be mixed (e.g. `f9b4ca`, `F9B4CA` and `f9B4Ca` are all valid strings).
deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error> where D: Deserializer<'de>, T: FromHex, <T as FromHex>::Error: fmt::Display,67 pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error>
68 where
69     D: Deserializer<'de>,
70     T: FromHex,
71     <T as FromHex>::Error: fmt::Display,
72 {
73     struct HexStrVisitor<T>(PhantomData<T>);
74 
75     impl<'de, T> Visitor<'de> for HexStrVisitor<T>
76     where
77         T: FromHex,
78         <T as FromHex>::Error: fmt::Display,
79     {
80         type Value = T;
81 
82         fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
83             write!(f, "a hex encoded string")
84         }
85 
86         fn visit_str<E>(self, data: &str) -> Result<Self::Value, E>
87         where
88             E: Error,
89         {
90             FromHex::from_hex(data).map_err(Error::custom)
91         }
92 
93         fn visit_borrowed_str<E>(self, data: &'de str) -> Result<Self::Value, E>
94         where
95             E: Error,
96         {
97             FromHex::from_hex(data).map_err(Error::custom)
98         }
99     }
100 
101     deserializer.deserialize_str(HexStrVisitor(PhantomData))
102 }
103