const_varint/
char.rs

1use super::{
2  decode_u32_varint, encode_u32_varint, encode_u32_varint_to, encoded_u32_varint_len, DecodeError,
3  EncodeError, U32VarintBuffer, Varint,
4};
5
6/// A buffer for storing LEB128 encoded [`char`] value.
7pub type CharBuffer = U32VarintBuffer;
8
9/// Returns the encoded length of the value in LEB128 variable length format.
10/// The returned value will be in range [`char::ENCODED_LEN_RANGE`].
11#[inline]
12pub const fn encoded_char_len(char: &char) -> usize {
13  encoded_u32_varint_len(*char as u32)
14}
15
16/// Encodes a `char` value into LEB128 variable length format, and writes it to the buffer.
17#[inline]
18pub const fn encode_char(char: &char) -> CharBuffer {
19  encode_u32_varint(*char as u32)
20}
21
22/// Encodes a `char` value into LEB128 variable length format, and writes it to the buffer.
23#[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/// Decodes a `char` in LEB128 encoded format from the buffer.
29///
30/// Returns the bytes readed and the decoded value if successful.
31#[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}