1#[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#[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#[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
63pub 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}