qubit_codec_text/codec/
ascii_codec.rs1use crate::{
9 Ascii,
10 Charset,
11 CharsetCodec,
12 CharsetDecodeError,
13 CharsetDecodeErrorKind,
14 CharsetDecodeResult,
15 CharsetEncodeError,
16 CharsetEncodeErrorKind,
17 CharsetEncodeProbe,
18 CharsetEncodeResult,
19};
20use qubit_codec::Codec;
21
22#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
27pub struct AsciiCodec;
28
29impl AsciiCodec {
30 #[must_use]
36 #[inline(always)]
37 pub const fn charset(self) -> Charset {
38 Charset::ASCII
39 }
40}
41
42impl CharsetCodec for AsciiCodec {
43 #[inline(always)]
49 fn charset(&self) -> Charset {
50 Charset::ASCII
51 }
52}
53
54impl CharsetEncodeProbe for AsciiCodec {
55 #[inline]
70 fn encode_len(&self, ch: char, index: usize) -> CharsetEncodeResult<usize> {
71 if ch > Ascii::MAX_CHAR {
72 let kind = CharsetEncodeErrorKind::UnmappableCharacter {
73 value: ch as u32,
74 };
75 return Err(CharsetEncodeError::new(Charset::ASCII, kind, index));
76 }
77 Ok(1)
78 }
79}
80
81unsafe impl Codec for AsciiCodec {
82 type Value = char;
83 type Unit = u8;
84 type DecodeError = CharsetDecodeError;
85 type EncodeError = CharsetEncodeError;
86
87 #[inline(always)]
88 fn min_units_per_value(&self) -> core::num::NonZeroUsize {
89 core::num::NonZeroUsize::MIN
90 }
91
92 #[inline(always)]
93 fn max_units_per_value(&self) -> core::num::NonZeroUsize {
94 core::num::NonZeroUsize::MIN
95 }
96
97 #[inline]
98 unsafe fn decode_unchecked(
99 &self,
100 input: &[u8],
101 index: usize,
102 ) -> CharsetDecodeResult<(char, core::num::NonZeroUsize)> {
103 if index > input.len() {
104 let kind = CharsetDecodeErrorKind::InvalidInputIndex {
105 input_len: input.len(),
106 };
107 return Err(CharsetDecodeError::new(Charset::ASCII, kind, index));
108 }
109 if index == input.len() {
110 let kind = CharsetDecodeErrorKind::IncompleteSequence {
111 required: 1,
112 available: 0,
113 };
114 return Err(CharsetDecodeError::new(Charset::ASCII, kind, index));
115 }
116
117 let value = input[index];
118 if value > Ascii::MAX_BYTE {
119 let kind = CharsetDecodeErrorKind::MalformedSequence {
120 value: Some(value as u32),
121 };
122 return Err(CharsetDecodeError::new(Charset::ASCII, kind, index));
123 }
124 debug_assert!(index < input.len());
125 Ok((value as char, core::num::NonZeroUsize::MIN))
126 }
127
128 #[inline]
129 unsafe fn encode_unchecked(
130 &self,
131 ch: &char,
132 output: &mut [u8],
133 index: usize,
134 ) -> CharsetEncodeResult<usize> {
135 if *ch > Ascii::MAX_CHAR {
136 let kind = CharsetEncodeErrorKind::UnmappableCharacter {
137 value: *ch as u32,
138 };
139 return Err(CharsetEncodeError::new(Charset::ASCII, kind, index));
140 }
141 if index >= output.len() {
142 let kind = CharsetEncodeErrorKind::BufferTooSmall {
143 required: required_index(index, 1),
144 available: 0,
145 };
146 return Err(CharsetEncodeError::new(Charset::ASCII, kind, index));
147 }
148 output[index] = *ch as u8;
149 Ok(1)
150 }
151}
152
153#[inline(always)]
154const fn required_index(index: usize, required_units: usize) -> usize {
155 match index.checked_add(required_units) {
156 Some(required) => required,
157 None => usize::MAX,
158 }
159}