use crate::error::parser::DateParseError;
use nom::{number::complete::be_u64, IResult};
use alloc::vec::Vec;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Date {
date: u64,
}
impl Date {
pub fn new(date: u64) -> Self {
Self { date }
}
pub fn serialize(&self) -> Vec<u8> {
self.date.to_be_bytes().to_vec()
}
pub fn parse_frame(input: &[u8]) -> IResult<&[u8], Date, DateParseError> {
let (rest, date) = be_u64(input)?;
Ok((rest, Date { date }))
}
pub fn parse(bytes: impl AsRef<[u8]>) -> Result<Date, DateParseError> {
Ok(Self::parse_frame(bytes.as_ref())?.1)
}
pub fn date(&self) -> &u64 {
&self.date
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::time::SystemTime;
#[test]
fn serialize() {
let since_epoch =
SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_secs();
let serialized = Date::new(since_epoch).serialize();
let date = Date::parse(&serialized).unwrap();
assert_eq!(date.date, since_epoch);
}
#[test]
fn valid_date() {
let time = 1719940343u64;
let time = time.to_be_bytes();
assert_eq!(
Date::parse(time),
Ok(Date {
date: 1719940343u64
})
);
}
#[test]
fn valid_date_with_extra_bytes() {
let time = 1719940343u64;
let mut time = time.to_be_bytes().to_vec();
time.push(1);
time.push(2);
time.push(3);
time.push(4);
assert_eq!(
Date::parse(time),
Ok(Date {
date: 1719940343u64
})
);
}
#[test]
fn extra_bytes_returned() {
let time = 1719940343u64;
let mut time = time.to_be_bytes().to_vec();
time.push(1);
time.push(2);
time.push(3);
time.push(4);
let (rest, date) = Date::parse_frame(&time).unwrap();
assert_eq!(
date,
Date {
date: 1719940343u64
}
);
assert_eq!(rest, [1, 2, 3, 4]);
}
#[test]
fn empty_date() {
assert_eq!(
Date::parse(Vec::<u8>::new()).unwrap_err(),
DateParseError::InvalidBitstream
);
}
#[test]
fn incomplete_date() {
for i in 0..7 {
let empty = vec![1 as u8; i];
assert_eq!(
Date::parse(empty).unwrap_err(),
DateParseError::InvalidBitstream
);
}
}
}