1use crate::FromHex;
18use core::fmt;
19use core::marker::PhantomData;
20use serde_core::de::{Error, Visitor};
21use serde_core::Deserializer;
22
23#[inline]
30pub fn serialize<S, T>(data: T, serializer: S) -> Result<S::Ok, S::Error>
31where
32 S: serde_core::Serializer,
33 T: AsRef<[u8]>,
34{
35 serialize_inner::<S, false, true>(data.as_ref(), serializer)
36}
37
38#[inline]
42pub fn serialize_upper<S, T>(data: T, serializer: S) -> Result<S::Ok, S::Error>
43where
44 S: serde_core::Serializer,
45 T: AsRef<[u8]>,
46{
47 serialize_inner::<S, true, true>(data.as_ref(), serializer)
48}
49
50const STACK_LEN: usize = 128;
52
53fn serialize_inner<S, const UPPER: bool, const PREFIX: bool>(
59 data: &[u8],
60 serializer: S,
61) -> Result<S::Ok, S::Error>
62where
63 S: serde_core::Serializer,
64{
65 if data.len() <= STACK_LEN {
66 let mut buf = crate::impl_core::uninit_array::<u8, { STACK_LEN * 2 + 2 }>();
67 let prefix_len = PREFIX as usize * 2;
68 let len = prefix_len + data.len() * 2;
69 if PREFIX {
70 buf[0].write(b'0');
71 buf[1].write(b'x');
72 }
73 unsafe { crate::imp::encode::<UPPER>(data, &mut buf[prefix_len..len]) };
75 let s = unsafe {
78 core::str::from_utf8_unchecked(crate::impl_core::slice_assume_init(&buf[..len]))
79 };
80 serializer.serialize_str(s)
81 } else {
82 #[cfg(feature = "alloc")]
83 {
84 serializer.serialize_str(&crate::encode_inner::<UPPER, PREFIX>(data))
85 }
86 #[cfg(not(feature = "alloc"))]
87 {
88 let display = crate::display(data);
89 match (UPPER, PREFIX) {
90 (false, false) => serializer.collect_str(&format_args!("{display:x}")),
91 (false, true) => serializer.collect_str(&format_args!("{display:#x}")),
92 (true, false) => serializer.collect_str(&format_args!("{display:X}")),
93 (true, true) => serializer.collect_str(&format_args!("{display:#X}")),
94 }
95 }
96 }
97}
98
99#[inline]
104pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error>
105where
106 D: Deserializer<'de>,
107 T: FromHex,
108 <T as FromHex>::Error: fmt::Display,
109{
110 struct HexStrVisitor<T>(PhantomData<T>);
111
112 impl<T> Visitor<'_> for HexStrVisitor<T>
113 where
114 T: FromHex,
115 <T as FromHex>::Error: fmt::Display,
116 {
117 type Value = T;
118
119 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
120 f.write_str("a hex encoded string")
121 }
122
123 fn visit_bytes<E: Error>(self, data: &[u8]) -> Result<Self::Value, E> {
124 FromHex::from_hex(data).map_err(Error::custom)
125 }
126
127 fn visit_str<E: Error>(self, data: &str) -> Result<Self::Value, E> {
128 FromHex::from_hex(data.as_bytes()).map_err(Error::custom)
129 }
130 }
131
132 deserializer.deserialize_str(HexStrVisitor(PhantomData))
133}
134
135pub mod no_prefix {
151 #[inline]
158 pub fn serialize<S, T>(data: T, serializer: S) -> Result<S::Ok, S::Error>
159 where
160 S: serde_core::Serializer,
161 T: AsRef<[u8]>,
162 {
163 super::serialize_inner::<S, false, false>(data.as_ref(), serializer)
164 }
165
166 #[inline]
170 pub fn serialize_upper<S, T>(data: T, serializer: S) -> Result<S::Ok, S::Error>
171 where
172 S: serde_core::Serializer,
173 T: AsRef<[u8]>,
174 {
175 super::serialize_inner::<S, true, false>(data.as_ref(), serializer)
176 }
177
178 pub use super::deserialize;
179}