1use crate::utils::Buffer;
2
3use super::{
4 decode_u32_varint, encode_u32_varint, encode_u32_varint_to, encoded_u32_varint_len, DecodeError,
5 EncodeError, Varint,
6};
7
8pub type CharBuffer = Buffer<{ u32::MAX_ENCODED_LEN + 1 }>;
10
11#[inline]
14pub const fn encoded_char_len(char: &char) -> usize {
15 encoded_u32_varint_len(*char as u32)
16}
17
18#[inline]
20pub const fn encode_char(char: &char) -> CharBuffer {
21 encode_u32_varint(*char as u32)
22}
23
24#[inline]
26pub const fn encode_char_to(char: &char, buf: &mut [u8]) -> Result<usize, EncodeError> {
27 encode_u32_varint_to(*char as u32, buf)
28}
29
30#[inline]
34pub const fn decode_char(buf: &[u8]) -> Result<(usize, char), DecodeError> {
35 match decode_u32_varint(buf) {
36 Ok((bytes_read, value)) => match char::from_u32(value) {
37 Some(c) => Ok((bytes_read, c)),
38 None => Err(DecodeError::other("invalid char value")),
39 },
40 Err(e) => Err(e),
41 }
42}
43
44impl Varint for char {
45 const MIN_ENCODED_LEN: usize = u32::MIN_ENCODED_LEN;
46 const MAX_ENCODED_LEN: usize = u32::MAX_ENCODED_LEN;
47
48 #[inline]
49 fn encoded_len(&self) -> usize {
50 encoded_char_len(self)
51 }
52
53 #[inline]
54 fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
55 encode_char_to(self, buf)
56 }
57
58 #[inline]
59 fn decode(buf: &[u8]) -> Result<(usize, Self), DecodeError>
60 where
61 Self: Sized,
62 {
63 decode_char(buf)
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 use quickcheck_macros::quickcheck;
72
73 #[quickcheck]
74 fn encode_decode_char(value: char) -> bool {
75 let encoded = encode_char(&value);
76 if encoded.len() != encoded_char_len(&value) || (encoded.len() > <char>::MAX_ENCODED_LEN) {
77 return false;
78 }
79
80 if let Ok((bytes_read, decoded)) = decode_char(&encoded) {
81 value == decoded && encoded.len() == bytes_read
82 } else {
83 false
84 }
85 }
86
87 #[quickcheck]
88 fn encode_decode_char_varint(value: char) -> bool {
89 let mut buf = [0; <char>::MAX_ENCODED_LEN];
90 let Ok(encoded_len) = value.encode(&mut buf) else {
91 return false;
92 };
93 if encoded_len != value.encoded_len() || (value.encoded_len() > <char>::MAX_ENCODED_LEN) {
94 return false;
95 }
96
97 if let Ok((bytes_read, decoded)) = <char>::decode(&buf) {
98 value == decoded && encoded_len == bytes_read
99 } else {
100 false
101 }
102 }
103}