1#![doc = include_str!("../README.md")]
2
3mod decode;
4mod encode;
5
6mod fmt;
7mod from_str;
8
9#[cfg(feature = "serde")]
10mod deserialize;
11#[cfg(feature = "serde")]
12mod serialize;
13
14#[cfg(test)]
15mod tests;
16
17use std::ops::{Deref, DerefMut};
18
19#[cfg(feature = "bytemuck")]
20use bytemuck::{Pod, TransparentWrapper, Zeroable};
21
22#[derive(Copy, Clone, Default, PartialOrd, Ord, Hash, Eq, PartialEq)]
31#[cfg_attr(feature = "bytemuck", derive(TransparentWrapper, Pod, Zeroable))]
32#[cfg_attr(feature = "bytemuck", transparent(T))]
33#[repr(transparent)]
34pub struct Hex<T: ?Sized>(pub T);
35
36#[derive(Copy, Clone, Default, PartialOrd, Ord, Hash, Eq, PartialEq)]
45#[cfg_attr(feature = "bytemuck", derive(TransparentWrapper, Pod, Zeroable))]
46#[cfg_attr(feature = "bytemuck", transparent(T))]
47#[repr(transparent)]
48pub struct UpperHex<T: ?Sized>(pub T);
49
50macro_rules! impl_basic {
51 ($Hex:ident) => {
52 impl<T> Deref for $Hex<T>
56 where
57 T: ?Sized,
58 {
59 type Target = T;
60
61 fn deref(&self) -> &Self::Target {
62 &self.0
63 }
64 }
65 impl<T> DerefMut for $Hex<T>
66 where
67 T: ?Sized,
68 {
69 fn deref_mut(&mut self) -> &mut Self::Target {
70 &mut self.0
71 }
72 }
73
74 impl<T, V> AsRef<V> for $Hex<T>
76 where
77 T: ?Sized + AsRef<V>,
78 V: ?Sized,
79 {
80 fn as_ref(&self) -> &V {
81 self.0.as_ref()
82 }
83 }
84 impl<T, V> AsMut<V> for $Hex<T>
85 where
86 T: ?Sized + AsMut<V>,
87 V: ?Sized,
88 {
89 fn as_mut(&mut self) -> &mut V {
90 self.0.as_mut()
91 }
92 }
93
94 impl<T> From<T> for $Hex<T> {
96 fn from(value: T) -> Self {
97 Self(value)
98 }
99 }
100 #[cfg(feature = "bytemuck")]
101 impl<'a, T> From<&'a T> for &'a $Hex<T>
102 where
103 T: ?Sized,
104 {
105 fn from(value: &'a T) -> Self {
106 TransparentWrapper::wrap_ref(value)
107 }
108 }
109 #[cfg(feature = "bytemuck")]
110 impl<'a, T> From<&'a mut T> for &'a mut $Hex<T>
111 where
112 T: ?Sized,
113 {
114 fn from(value: &'a mut T) -> Self {
115 TransparentWrapper::wrap_mut(value)
116 }
117 }
118 };
119}
120
121impl_basic!(Hex);
122impl_basic!(UpperHex);
123
124pub(crate) const LOWER: bool = false;
126pub(crate) const UPPER: bool = true;
127
128pub trait HexExt {
132 fn into_hex(self) -> Hex<Self>
133 where
134 Self: Sized;
135 #[cfg(feature = "bytemuck")]
136 fn as_hex(&self) -> &Hex<Self>;
137 #[cfg(feature = "bytemuck")]
138 fn as_hex_mut(&mut self) -> &mut Hex<Self>;
139
140 fn into_upper_hex(self) -> UpperHex<Self>
141 where
142 Self: Sized;
143 #[cfg(feature = "bytemuck")]
144 fn as_upper_hex(&self) -> &UpperHex<Self>;
145 #[cfg(feature = "bytemuck")]
146 fn as_upper_hex_mut(&mut self) -> &mut UpperHex<Self>;
147}
148
149impl<T> HexExt for T
150where
151 T: ?Sized,
152{
153 fn into_hex(self) -> Hex<Self>
154 where
155 Self: Sized,
156 {
157 self.into()
158 }
159
160 #[cfg(feature = "bytemuck")]
161 fn as_hex(&self) -> &Hex<Self> {
162 self.into()
163 }
164
165 #[cfg(feature = "bytemuck")]
166 fn as_hex_mut(&mut self) -> &mut Hex<Self> {
167 self.into()
168 }
169
170 fn into_upper_hex(self) -> UpperHex<Self>
171 where
172 Self: Sized,
173 {
174 self.into()
175 }
176
177 #[cfg(feature = "bytemuck")]
178 fn as_upper_hex(&self) -> &UpperHex<Self> {
179 self.into()
180 }
181
182 #[cfg(feature = "bytemuck")]
183 fn as_upper_hex_mut(&mut self) -> &mut UpperHex<Self> {
184 self.into()
185 }
186}
187
188#[cfg(feature = "serde")]
191pub mod serde {
192 pub use crate::deserialize::deserialize;
193 pub use crate::serialize::serialize;
194}
195
196#[cfg(feature = "serde")]
199pub mod serde_upper {
200 pub use crate::deserialize::deserialize;
201 pub use crate::serialize::serialize_upper as serialize;
202}
203
204pub use decode::decode;
205pub use decode::decode_into;
206pub use encode::encode;
207pub use encode::encode_upper;
208pub use hex::FromHexError;