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(stream: I) -> AIParseResult { 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), ); } }