const_hex/serde.rs
1//! Hex encoding with [`serde`](serde_core).
2//!
3//! # Examples
4//!
5//! ```
6//! # #[cfg(feature = "alloc")] {
7//! use serde::{Serialize, Deserialize};
8//!
9//! #[derive(Serialize, Deserialize)]
10//! struct Foo {
11//! #[serde(with = "const_hex")]
12//! bar: Vec<u8>,
13//! }
14//! # }
15//! ```
16
17use crate::FromHex;
18use core::fmt;
19use core::marker::PhantomData;
20use serde_core::de::{Error, Visitor};
21use serde_core::Deserializer;
22
23#[cfg(feature = "alloc")]
24mod serialize {
25 use serde_core::Serializer;
26
27 /// Serializes `data` as hex string using lowercase characters with a `0x` prefix.
28 ///
29 /// Lowercase characters are used (e.g. `f9b4ca`). The resulting string's length
30 /// is always even, each byte in data is always encoded using two hex digits.
31 /// Thus, the resulting string contains exactly twice as many bytes as the input
32 /// data plus two (for the prefix).
33 #[inline]
34 pub fn serialize<S, T>(data: T, serializer: S) -> Result<S::Ok, S::Error>
35 where
36 S: Serializer,
37 T: AsRef<[u8]>,
38 {
39 serializer.serialize_str(&crate::encode_prefixed(data.as_ref()))
40 }
41
42 /// Serializes `data` as hex string using uppercase characters.
43 ///
44 /// Apart from the characters' casing, this works exactly like [`serialize`].
45 #[inline]
46 pub fn serialize_upper<S, T>(data: T, serializer: S) -> Result<S::Ok, S::Error>
47 where
48 S: Serializer,
49 T: AsRef<[u8]>,
50 {
51 serializer.serialize_str(&crate::encode_upper_prefixed(data.as_ref()))
52 }
53}
54
55#[cfg(feature = "alloc")]
56pub use serialize::{serialize, serialize_upper};
57
58/// Deserializes a hex string into raw bytes.
59///
60/// Both, upper and lower case characters are valid in the input string and can
61/// even be mixed (e.g. `f9b4ca`, `F9B4CA` and `f9B4Ca` are all valid strings).
62#[inline]
63pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error>
64where
65 D: Deserializer<'de>,
66 T: FromHex,
67 <T as FromHex>::Error: fmt::Display,
68{
69 struct HexStrVisitor<T>(PhantomData<T>);
70
71 impl<T> Visitor<'_> for HexStrVisitor<T>
72 where
73 T: FromHex,
74 <T as FromHex>::Error: fmt::Display,
75 {
76 type Value = T;
77
78 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79 f.write_str("a hex encoded string")
80 }
81
82 fn visit_bytes<E: Error>(self, data: &[u8]) -> Result<Self::Value, E> {
83 FromHex::from_hex(data).map_err(Error::custom)
84 }
85
86 fn visit_str<E: Error>(self, data: &str) -> Result<Self::Value, E> {
87 FromHex::from_hex(data.as_bytes()).map_err(Error::custom)
88 }
89 }
90
91 deserializer.deserialize_str(HexStrVisitor(PhantomData))
92}
93
94/// Hex encoding with [`serde`](serde_core).
95///
96/// # Examples
97///
98/// ```
99/// # #[cfg(feature = "alloc")] {
100/// use serde::{Serialize, Deserialize};
101///
102/// #[derive(Serialize, Deserialize)]
103/// struct Foo {
104/// #[serde(with = "const_hex::serde::no_prefix")]
105/// bar: Vec<u8>,
106/// }
107/// # }
108/// ```
109pub mod no_prefix {
110 #[cfg(feature = "alloc")]
111 mod serialize {
112 use serde_core::Serializer;
113
114 /// Serializes `data` as hex string using lowercase characters.
115 ///
116 /// Lowercase characters are used (e.g. `f9b4ca`). The resulting string's length
117 /// is always even, each byte in data is always encoded using two hex digits.
118 /// Thus, the resulting string contains exactly twice as many bytes as the input
119 /// data.
120 #[inline]
121 pub fn serialize<S, T>(data: T, serializer: S) -> Result<S::Ok, S::Error>
122 where
123 S: Serializer,
124 T: AsRef<[u8]>,
125 {
126 serializer.serialize_str(&crate::encode(data.as_ref()))
127 }
128
129 /// Serializes `data` as hex string using uppercase characters.
130 ///
131 /// Apart from the characters' casing, this works exactly like [`serialize`].
132 #[inline]
133 pub fn serialize_upper<S, T>(data: T, serializer: S) -> Result<S::Ok, S::Error>
134 where
135 S: Serializer,
136 T: AsRef<[u8]>,
137 {
138 serializer.serialize_str(&crate::encode_upper(data.as_ref()))
139 }
140 }
141
142 #[cfg(feature = "alloc")]
143 pub use serialize::{serialize, serialize_upper};
144
145 pub use super::deserialize;
146}