radn-rs/src/rstd/atomic/au64.rs

98 lines
2.2 KiB
Rust

use crate::rstd::inlining::*;
use super::*;
impl Serializable for u64 {
fn serialize(&self, serializer: &mut dyn Serializer) {
serializer.write(&self.to_le_bytes());
}
}
#[derive(Debug, PartialEq)]
pub enum IntParseError {
Eof,
ExtraData(usize),
}
impl Display for IntParseError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Eof => write!(f, "encountered EOF write parsing an integer"),
Self::ExtraData(length) => write!(
f,
"encountered extra data of length {length} while parsing an integer",
),
}
}
}
impl Error for IntParseError {}
impl From<&[u8]> for IntParseError {
fn from(_value: &[u8]) -> Self {
Self::Eof
}
}
impl AtomicBase for u64 {
type AParseError = IntParseError;
}
impl ImplMode for u64 {
type Mode = InliningMode;
}
impl CInliningAtomic for u64 {
fn ca_extension_error(tail: &[u8]) -> Self::AParseError {
IntParseError::ExtraData(tail.len())
}
fn ca_ideserialize<I: Stream>(stream: I) -> AIParseResult<Self, I> {
let (x, stream) = stream.iread_n_const::<8>(|slice| IntParseError::from(slice))?;
Ok((u64::from_le_bytes(x), stream))
}
}
impl ConstSizeAtomic for u64 {
const SIZE: usize = 8;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn can_parse_zero() {
assert_eq!(u64::parse_slice(&[0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), 0);
}
#[test]
fn can_parse_le() {
assert_eq!(
u64::parse_slice(&[1, 2, 3, 4, 5, 6, 7, 8]).unwrap(),
0x0807060504030201,
);
}
#[test]
fn cannot_parse_empty_slice() {
assert_eq!(u64::parse_slice(&[]).unwrap_err(), IntParseError::Eof);
}
#[test]
fn cannot_parse_undersized_slice() {
assert_eq!(
u64::parse_slice(&[0, 0, 0, 0, 0, 0, 0]).unwrap_err(),
IntParseError::Eof,
);
}
#[test]
fn cannot_parse_oversized_slice() {
assert_eq!(
u64::parse_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap_err(),
IntParseError::ExtraData(1),
);
}
}