1use core::fmt;
4use core::marker::PhantomData;
5
6use serde::{Deserializer, Serializer};
7
8use crate::common::{self, LengthCheck, SliceVisitor, StrIntoBufVisitor};
9
10#[cfg(feature = "alloc")]
11use ::{
12 alloc::vec::Vec,
13 serde::{Deserialize, Serialize},
14};
15
16#[cfg(feature = "alloc")]
17use crate::common::{StrIntoVecVisitor, VecVisitor};
18
19#[cfg(feature = "zeroize")]
20use zeroize::Zeroize;
21
22pub fn serialize_hex_lower_or_bin<S, T>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
25where
26 S: Serializer,
27 T: AsRef<[u8]>,
28{
29 common::serialize_hex_lower_or_bin(value, serializer)
30}
31
32pub fn serialize_hex_upper_or_bin<S, T>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
35where
36 S: Serializer,
37 T: AsRef<[u8]>,
38{
39 common::serialize_hex_upper_or_bin(value, serializer)
40}
41
42struct UpperBound;
43
44impl LengthCheck for UpperBound {
45 fn length_check(buffer_length: usize, data_length: usize) -> bool {
46 buffer_length >= data_length
47 }
48 fn expecting(
49 formatter: &mut fmt::Formatter<'_>,
50 data_type: &str,
51 data_length: usize,
52 ) -> fmt::Result {
53 write!(
54 formatter,
55 "{data_type} with a maximum length of {data_length}"
56 )
57 }
58}
59
60pub fn deserialize_hex_or_bin<'de, D>(buffer: &mut [u8], deserializer: D) -> Result<&[u8], D::Error>
64where
65 D: Deserializer<'de>,
66{
67 if deserializer.is_human_readable() {
68 deserializer.deserialize_str(StrIntoBufVisitor::<UpperBound>(buffer, PhantomData))
69 } else {
70 deserializer.deserialize_byte_buf(SliceVisitor::<UpperBound>(buffer, PhantomData))
71 }
72}
73
74#[cfg(feature = "alloc")]
77pub fn deserialize_hex_or_bin_vec<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
78where
79 D: Deserializer<'de>,
80{
81 if deserializer.is_human_readable() {
82 deserializer.deserialize_str(StrIntoVecVisitor)
83 } else {
84 deserializer.deserialize_byte_buf(VecVisitor)
85 }
86}
87
88#[cfg(feature = "alloc")]
90pub type HexLowerOrBin = HexOrBin<false>;
91
92#[cfg(feature = "alloc")]
94pub type HexUpperOrBin = HexOrBin<true>;
95
96#[cfg(feature = "alloc")]
100#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
101pub struct HexOrBin<const UPPERCASE: bool>(pub Vec<u8>);
102
103#[cfg(feature = "alloc")]
104impl<const UPPERCASE: bool> AsRef<[u8]> for HexOrBin<UPPERCASE> {
105 fn as_ref(&self) -> &[u8] {
106 self.0.as_ref()
107 }
108}
109
110#[cfg(feature = "alloc")]
111impl<const UPPERCASE: bool> From<&[u8]> for HexOrBin<UPPERCASE> {
112 fn from(bytes: &[u8]) -> HexOrBin<UPPERCASE> {
113 Self(bytes.into())
114 }
115}
116
117#[cfg(feature = "alloc")]
118impl<const UPPERCASE: bool> From<Vec<u8>> for HexOrBin<UPPERCASE> {
119 fn from(vec: Vec<u8>) -> HexOrBin<UPPERCASE> {
120 Self(vec)
121 }
122}
123
124#[cfg(feature = "alloc")]
125impl<const UPPERCASE: bool> From<HexOrBin<UPPERCASE>> for Vec<u8> {
126 fn from(vec: HexOrBin<UPPERCASE>) -> Vec<u8> {
127 vec.0
128 }
129}
130
131#[cfg(feature = "alloc")]
132impl<const UPPERCASE: bool> Serialize for HexOrBin<UPPERCASE> {
133 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
134 where
135 S: Serializer,
136 {
137 if UPPERCASE {
138 serialize_hex_upper_or_bin(self, serializer)
139 } else {
140 serialize_hex_lower_or_bin(self, serializer)
141 }
142 }
143}
144
145#[cfg(feature = "alloc")]
146impl<'de, const UPPERCASE: bool> Deserialize<'de> for HexOrBin<UPPERCASE> {
147 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
148 where
149 D: Deserializer<'de>,
150 {
151 deserialize_hex_or_bin_vec(deserializer).map(Self)
152 }
153}
154
155#[cfg(all(feature = "alloc", feature = "zeroize"))]
156impl<const UPPERCASE: bool> Zeroize for HexOrBin<UPPERCASE> {
157 fn zeroize(&mut self) {
158 self.0.as_mut_slice().zeroize();
159 }
160}