120 lines
3.0 KiB
Rust
120 lines
3.0 KiB
Rust
use crate::rstd::inlining::*;
|
|
|
|
use super::*;
|
|
|
|
impl Serializable for bool {
|
|
fn serialize(&self, serializer: &mut dyn Serializer) {
|
|
match self {
|
|
true => serializer.write(&[0]),
|
|
false => serializer.write(&[1]),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
pub enum BooleanParseError {
|
|
OutOfBounds(u8),
|
|
Eof,
|
|
ExtraData(usize),
|
|
}
|
|
|
|
impl Display for BooleanParseError {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
Self::OutOfBounds(value) => {
|
|
write!(f, "boolean value out of bounds: {}.", value)
|
|
}
|
|
Self::Eof => write!(f, "encountered EOF write parsing a boolean."),
|
|
Self::ExtraData(length) => write!(
|
|
f,
|
|
"encountered extra data of length {length} while parsing a boolean.",
|
|
),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Error for BooleanParseError {}
|
|
|
|
impl From<&[u8]> for BooleanParseError {
|
|
fn from(_value: &[u8]) -> Self {
|
|
Self::Eof
|
|
}
|
|
}
|
|
|
|
impl Atomic for bool {
|
|
type AParseError = BooleanParseError;
|
|
|
|
fn a_deserialize(deserializer: &mut dyn Deserializer) -> AParseResult<Self> {
|
|
let byte = deserializer.read_n_const::<1>()?;
|
|
match byte[0] {
|
|
0 => Ok(false),
|
|
1 => Ok(true),
|
|
value => Err(BooleanParseError::OutOfBounds(value)),
|
|
}
|
|
}
|
|
|
|
fn a_extend(self, tail: &[u8]) -> AParseResult<Self> {
|
|
Err(Self::a_extension_error(tail))
|
|
}
|
|
}
|
|
|
|
impl InlineableAtomic for bool {
|
|
fn a_extension_error(tail: &[u8]) -> Self::AParseError {
|
|
BooleanParseError::ExtraData(tail.len())
|
|
}
|
|
|
|
fn a_ideserialize<D: Inlining>(deserializer: D) -> ADParseResult<Self, D> {
|
|
let (byte, deserializer) =
|
|
deserializer.iread_n_const::<1>(|slice| BooleanParseError::from(slice))?;
|
|
match byte[0] {
|
|
0 => Ok((false, deserializer)),
|
|
1 => Ok((true, deserializer)),
|
|
value => Err(BooleanParseError::OutOfBounds(value)),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl ConstSizeAtomic for bool {
|
|
const SIZE: usize = 1;
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn can_parse_false() {
|
|
assert_eq!(bool::parse_slice(&[0]).unwrap(), false)
|
|
}
|
|
|
|
#[test]
|
|
fn can_parse_true() {
|
|
assert_eq!(bool::parse_slice(&[1]).unwrap(), true)
|
|
}
|
|
|
|
#[test]
|
|
fn cannot_parse_out_of_bound_value() {
|
|
assert_eq!(
|
|
bool::parse_slice(&[2]).unwrap_err(),
|
|
BooleanParseError::OutOfBounds(2)
|
|
);
|
|
assert_eq!(
|
|
bool::parse_slice(&[2, 0]).unwrap_err(),
|
|
BooleanParseError::OutOfBounds(2)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn cannot_parse_empty_slice() {
|
|
assert_eq!(bool::parse_slice(&[]).unwrap_err(), BooleanParseError::Eof);
|
|
}
|
|
|
|
#[test]
|
|
fn cannot_parse_extra_tail() {
|
|
assert_eq!(
|
|
bool::parse_slice(&[0, 10, 20, 30]).unwrap_err(),
|
|
BooleanParseError::ExtraData(3)
|
|
);
|
|
}
|
|
}
|