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