1use super::{StringExtT, StringT};
7
8#[derive(Debug, Clone)]
9pub enum HexStr<'s, const N: usize, const P: bool = false, const U: bool = false> {
20 Owned(Vec<u8>),
22
23 Borrowed(&'s [u8]),
25}
26
27impl<'s, const N: usize, const P: bool, const U: bool> HexStr<'s, N, P, U> {
28 #[inline]
29 pub const fn new(value: &'s [u8]) -> Self {
31 Self::Borrowed(value)
32 }
33
34 #[inline]
35 pub const fn new_owned(value: Vec<u8>) -> Self {
37 Self::Owned(value)
38 }
39
40 #[inline]
41 pub fn set_with_prefix<const NP: bool>(self) -> HexStr<'s, N, NP, U> {
43 match self {
44 Self::Borrowed(value) => HexStr::Borrowed(value),
45 Self::Owned(value) => HexStr::Owned(value),
46 }
47 }
48
49 #[inline]
50 pub fn set_uppercase<const NU: bool>(self) -> HexStr<'s, N, P, NU> {
52 match self {
53 Self::Borrowed(value) => HexStr::Borrowed(value),
54 Self::Owned(value) => HexStr::Owned(value),
55 }
56 }
57
58 #[inline]
59 fn encode<T>(&self, string: &mut T)
61 where
62 T: for<'a> Extend<&'a u8>,
63 {
64 let mut buffer = [0; N];
65
66 for (idx, &i) in (0..N).rev().zip(
67 match self {
68 Self::Borrowed(value) => value,
69 Self::Owned(value) => value.as_slice(),
70 }
71 .iter()
72 .rev(),
73 ) {
74 buffer[idx] = i
75 }
76
77 if U {
78 string.extend(
79 const_hex::Buffer::<N, P>::new()
80 .const_format_upper(&buffer)
81 .as_bytes(),
82 );
83 } else {
84 string.extend(
85 const_hex::Buffer::<N, P>::new()
86 .const_format(&buffer)
87 .as_bytes(),
88 );
89 }
90 }
91}
92
93impl<const N: usize, const P: bool, const U: bool> StringT for HexStr<'_, N, P, U> {
94 #[inline]
95 fn encode_to_buf(self, string: &mut Vec<u8>) {
96 self.encode(string);
97 }
98
99 #[inline]
100 fn encode_to_buf_with_separator(self, string: &mut Vec<u8>, separator: &str) {
101 self.encode(string);
102 string.extend(separator.as_bytes());
103 }
104
105 #[inline]
106 fn encode_to_bytes_buf(self, string: &mut bytes::BytesMut) {
107 self.encode(string);
108 }
109
110 #[inline]
111 fn encode_to_bytes_buf_with_separator(self, string: &mut bytes::BytesMut, separator: &str) {
112 self.encode(string);
113 string.extend(separator.as_bytes());
114 }
115}
116
117impl<const N: usize, const P: bool, const U: bool> StringExtT for HexStr<'_, N, P, U> {}
118
119impl<const N: usize, const P: bool> StringT for const_hex::Buffer<N, P> {
120 #[inline]
121 fn encode_to_buf(self, string: &mut Vec<u8>) {
122 string.extend(self.as_bytes());
123 }
124
125 #[inline]
126 fn encode_to_buf_with_separator(self, string: &mut Vec<u8>, separator: &str) {
127 string.extend(self.as_bytes());
128 string.extend(separator.as_bytes());
129 }
130
131 #[inline]
132 fn encode_to_bytes_buf(self, string: &mut bytes::BytesMut) {
133 string.extend(self.as_bytes());
134 }
135
136 #[inline]
137 fn encode_to_bytes_buf_with_separator(self, string: &mut bytes::BytesMut, separator: &str) {
138 string.extend(self.as_bytes());
139 string.extend(separator.as_bytes());
140 }
141}
142
143impl<const N: usize, const P: bool> StringExtT for const_hex::Buffer<N, P> {}
144
145#[cfg(test)]
146mod test {
147 use crate::string::{HexStr, StringExtT};
148
149 #[test]
150 fn test() {
151 assert_eq!(
152 HexStr::<0>::new(&[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]).to_string_ext(),
153 ""
154 );
155 assert_eq!(
156 HexStr::<7>::new(&[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]).to_string_ext(),
157 "01020304050607"
158 );
159 assert_eq!(
160 HexStr::<8>::new(&[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]).to_string_ext(),
161 "0001020304050607"
162 );
163 assert_eq!(
164 HexStr::<9>::new(&[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]).to_string_ext(),
165 "000001020304050607"
166 );
167 }
168
169 #[test]
170 fn test_with_prefix() {
171 assert_eq!(
172 HexStr::<0>::new(&[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07])
173 .set_with_prefix::<true>()
174 .to_string_ext(),
175 "0x"
176 );
177 assert_eq!(
178 HexStr::<7>::new(&[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07])
179 .set_with_prefix::<true>()
180 .to_string_ext(),
181 "0x01020304050607"
182 );
183 assert_eq!(
184 HexStr::<8>::new(&[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07])
185 .set_with_prefix::<true>()
186 .to_string_ext(),
187 "0x0001020304050607"
188 );
189 assert_eq!(
190 HexStr::<9>::new(&[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07])
191 .set_with_prefix::<true>()
192 .to_string_ext(),
193 "0x000001020304050607"
194 );
195 }
196
197 #[test]
198 fn test_uppcase() {
199 assert_eq!(
200 HexStr::<7>::new(&[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xa7])
201 .set_with_prefix::<true>()
202 .set_uppercase::<true>()
203 .to_string_ext(),
204 "0x010203040506A7"
205 );
206 assert_eq!(
207 HexStr::<8>::new(&[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xa7])
208 .set_with_prefix::<true>()
209 .set_uppercase::<true>()
210 .to_string_ext(),
211 "0x00010203040506A7"
212 );
213 assert_eq!(
214 HexStr::<9>::new(&[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xa7])
215 .set_with_prefix::<true>()
216 .set_uppercase::<true>()
217 .to_string_ext(),
218 "0x0000010203040506A7"
219 );
220 }
221}