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