hex/
serde.rs

1//! Hex encoding with `serde`.
2#[cfg_attr(
3    all(feature = "alloc", feature = "serde"),
4    doc = r##"
5# Example
6
7```
8use serde::{Serialize, Deserialize};
9
10#[derive(Serialize, Deserialize)]
11struct Foo {
12    #[serde(with = "hex")]
13    bar: Vec<u8>,
14}
15```
16"##
17)]
18use serde::de::{Error, Visitor};
19use serde::Deserializer;
20#[cfg(feature = "alloc")]
21use serde::Serializer;
22
23#[cfg(feature = "alloc")]
24use alloc::string::String;
25
26use core::fmt;
27use core::marker::PhantomData;
28
29use crate::FromHex;
30
31#[cfg(feature = "alloc")]
32use 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")]
38pub fn serialize_upper<S, T>(data: T, serializer: S) -> Result<S::Ok, S::Error>
39where
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")]
54pub fn serialize<S, T>(data: T, serializer: S) -> Result<S::Ok, S::Error>
55where
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).
67pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error>
68where
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}