qubit_codec_misc/
hex_byte_codec.rs1use crate::{
11 MiscCodecError,
12 hex_codec::{
13 hex_digit,
14 hex_value,
15 invalid_hex_digit,
16 },
17 misc_codec_error::map_misc_decode_failure_with_consumed,
18};
19use qubit_codec::Codec;
20
21#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
28pub struct HexByteCodec {
29 uppercase: bool,
30}
31
32impl HexByteCodec {
33 #[must_use]
35 #[inline]
36 pub const fn new() -> Self {
37 Self { uppercase: false }
38 }
39
40 #[must_use]
42 #[inline]
43 pub const fn upper() -> Self {
44 Self { uppercase: true }
45 }
46
47 #[must_use]
49 #[inline]
50 pub const fn with_uppercase(mut self, uppercase: bool) -> Self {
51 self.uppercase = uppercase;
52 self
53 }
54
55 #[must_use]
57 #[inline]
58 pub const fn is_uppercase(self) -> bool {
59 self.uppercase
60 }
61}
62
63impl Codec for HexByteCodec {
64 type Value = u8;
65 type Unit = u8;
66 type DecodeError = MiscCodecError;
67 type EncodeError = MiscCodecError;
68
69 const MIN_UNITS_PER_VALUE: usize = 2;
70 const MAX_ENCODE_UNITS_PER_VALUE: usize = 2;
71 const MAX_DECODE_UNITS_PER_VALUE: usize = 2;
72
73 #[inline]
78 unsafe fn decode(
79 &mut self,
80 input: &[u8],
81 input_index: usize,
82 ) -> Result<
83 (u8, core::num::NonZeroUsize),
84 qubit_codec::DecodeFailure<Self::DecodeError>,
85 > {
86 debug_assert!(input_index + 2 <= input.len());
87
88 let high_char = char::from(input[input_index]);
89 let low_char = char::from(input[input_index + 1]);
90 let high = hex_value(high_char)
91 .ok_or_else(|| invalid_hex_digit(input_index, high_char))
92 .map_err(|error| {
93 map_misc_decode_failure_with_consumed(
94 error,
95 qubit_codec::nz!(2),
96 )
97 })?;
98 let low = hex_value(low_char)
99 .ok_or_else(|| invalid_hex_digit(input_index + 1, low_char))
100 .map_err(|error| {
101 map_misc_decode_failure_with_consumed(
102 error,
103 qubit_codec::nz!(2),
104 )
105 })?;
106 Ok(((high << 4) | low, qubit_codec::nz!(2)))
107 }
108
109 #[inline]
114 unsafe fn encode(
115 &mut self,
116 value: &u8,
117 output: &mut [u8],
118 output_index: usize,
119 ) -> Result<usize, Self::EncodeError> {
120 debug_assert!(output_index + 2 <= output.len());
121
122 output[output_index] = hex_digit(*value >> 4, self.uppercase) as u8;
123 output[output_index + 1] =
124 hex_digit(*value & 0x0f, self.uppercase) as u8;
125 Ok(2)
126 }
127}