1#![allow(clippy::ptr_as_ptr, clippy::borrow_as_ptr, clippy::missing_errors_doc)]
4
5use core::iter;
6
7#[cfg(feature = "alloc")]
8#[allow(unused_imports)]
9use alloc::{
10 borrow::{Cow, ToOwned},
11 boxed::Box,
12 rc::Rc,
13 string::String,
14 vec::Vec,
15};
16
17#[cfg(all(feature = "alloc", target_has_atomic = "ptr"))]
18#[allow(unused_imports)]
19use alloc::sync::Arc;
20
21#[cfg_attr(feature = "alloc", doc = "\n[`encode`]: crate::encode")]
35#[cfg_attr(not(feature = "alloc"), doc = "\n[`encode`]: crate::encode_to_slice")]
36#[deprecated(note = "use `ToHexExt` instead")]
37pub trait ToHex {
38 fn encode_hex<T: iter::FromIterator<char>>(&self) -> T;
41}
42
43#[cfg(feature = "alloc")]
57pub trait ToHexExt {
58 fn encode_hex(&self) -> String;
61
62 fn encode_hex_with_prefix(&self) -> String;
65}
66
67struct BytesToHexChars<'a> {
68 inner: core::slice::Iter<'a, u8>,
69 next: Option<char>,
70}
71
72impl<'a> BytesToHexChars<'a> {
73 fn new(inner: &'a [u8]) -> Self {
74 BytesToHexChars {
75 inner: inner.iter(),
76 next: None,
77 }
78 }
79}
80
81impl Iterator for BytesToHexChars<'_> {
82 type Item = char;
83
84 fn next(&mut self) -> Option<Self::Item> {
85 match self.next.take() {
86 Some(current) => Some(current),
87 None => self.inner.next().map(|byte| {
88 let (high, low) = crate::byte2hex(*byte);
89 self.next = Some(low as char);
90 high as char
91 }),
92 }
93 }
94}
95
96#[inline]
97fn encode_to_iter<T: iter::FromIterator<char>>(source: &[u8]) -> T {
98 BytesToHexChars::new(source).collect()
99}
100
101#[allow(deprecated)]
102impl<T: AsRef<[u8]>> ToHex for T {
103 #[inline]
104 fn encode_hex<U: iter::FromIterator<char>>(&self) -> U {
105 encode_to_iter(self.as_ref())
106 }
107}
108
109#[cfg(feature = "alloc")]
110impl<T: AsRef<[u8]>> ToHexExt for T {
111 #[inline]
112 fn encode_hex(&self) -> String {
113 crate::encode(self)
114 }
115
116 #[inline]
117 fn encode_hex_with_prefix(&self) -> String {
118 crate::encode_prefixed(self)
119 }
120}
121
122pub trait FromHex: Sized {
136 type Error;
138
139 fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error>;
145}
146
147#[cfg(feature = "alloc")]
148impl<T: FromHex> FromHex for Box<T> {
149 type Error = T::Error;
150
151 #[inline]
152 fn from_hex<U: AsRef<[u8]>>(hex: U) -> Result<Self, Self::Error> {
153 FromHex::from_hex(hex.as_ref()).map(Self::new)
154 }
155}
156
157#[cfg(feature = "alloc")]
158impl<T> FromHex for Cow<'_, T>
159where
160 T: ToOwned + ?Sized,
161 T::Owned: FromHex,
162{
163 type Error = <T::Owned as FromHex>::Error;
164
165 #[inline]
166 fn from_hex<U: AsRef<[u8]>>(hex: U) -> Result<Self, Self::Error> {
167 FromHex::from_hex(hex.as_ref()).map(Cow::Owned)
168 }
169}
170
171#[cfg(feature = "alloc")]
172impl<T: FromHex> FromHex for Rc<T> {
173 type Error = T::Error;
174
175 #[inline]
176 fn from_hex<U: AsRef<[u8]>>(hex: U) -> Result<Self, Self::Error> {
177 FromHex::from_hex(hex.as_ref()).map(Self::new)
178 }
179}
180
181#[cfg(all(feature = "alloc", target_has_atomic = "ptr"))]
182impl<T: FromHex> FromHex for Arc<T> {
183 type Error = T::Error;
184
185 #[inline]
186 fn from_hex<U: AsRef<[u8]>>(hex: U) -> Result<Self, Self::Error> {
187 FromHex::from_hex(hex.as_ref()).map(Self::new)
188 }
189}
190
191#[cfg(feature = "alloc")]
192impl FromHex for Vec<u8> {
193 type Error = crate::FromHexError;
194
195 #[inline]
196 fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
197 crate::decode(hex.as_ref())
198 }
199}
200
201#[cfg(feature = "alloc")]
202impl FromHex for Vec<i8> {
203 type Error = crate::FromHexError;
204
205 #[inline]
206 fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
207 crate::decode(hex.as_ref()).map(|vec| unsafe { core::mem::transmute::<Vec<u8>, Self>(vec) })
209 }
210}
211
212#[cfg(feature = "alloc")]
213impl FromHex for Box<[u8]> {
214 type Error = crate::FromHexError;
215
216 #[inline]
217 fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
218 <Vec<u8>>::from_hex(hex).map(Vec::into_boxed_slice)
219 }
220}
221
222#[cfg(feature = "alloc")]
223impl FromHex for Box<[i8]> {
224 type Error = crate::FromHexError;
225
226 #[inline]
227 fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
228 <Vec<i8>>::from_hex(hex).map(Vec::into_boxed_slice)
229 }
230}
231
232impl<const N: usize> FromHex for [u8; N] {
233 type Error = crate::FromHexError;
234
235 #[inline]
236 fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
237 crate::decode_to_array(hex.as_ref())
238 }
239}
240
241impl<const N: usize> FromHex for [i8; N] {
242 type Error = crate::FromHexError;
243
244 #[inline]
245 fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
246 crate::decode_to_array(hex.as_ref())
248 .map(|buf| unsafe { *(&buf as *const [u8; N] as *const [i8; N]) })
249 }
250}