use std::{
io::{self, Read, Write},
time::{Duration as StdDuration, SystemTime, UNIX_EPOCH},
};
use crate::io::{LenBm, ReadFrom, WriteTo};
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct Duration(u64);
impl From<u64> for Duration {
fn from(secs: u64) -> Self {
Self(secs)
}
}
impl Duration {
pub const fn new(secs: u64) -> Self {
Self(secs)
}
pub fn as_secs(self) -> u64 {
self.0
}
}
impl WriteTo for Duration {
fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
self.0.write_to(w)
}
}
impl ReadFrom for Duration {
fn read_from(r: &mut dyn Read) -> io::Result<Self>
where
Self: Sized,
{
Ok(Self(u64::read_from(r)?))
}
}
#[test]
fn test_duration_write_to() {
let test: Duration = 0x0123_4567_89ab_cdef.into();
let mut bytes = Vec::new();
test.write_to(&mut bytes).unwrap();
let expected = [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef];
assert_eq!(bytes, expected);
}
#[test]
fn test_duration_read_from() {
use std::io::Cursor;
let mut bytes = Cursor::new([0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);
let test = Duration::read_from(&mut bytes).unwrap();
let expected: Duration = 0x0123_4567_89ab_cdef.into();
assert_eq!(test, expected);
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct Time(u64);
impl From<u64> for Time {
fn from(secs: u64) -> Self {
Self(secs)
}
}
impl From<SystemTime> for Time {
fn from(time: SystemTime) -> Self {
Self(
time.duration_since(UNIX_EPOCH)
.expect("Clock set before epoch")
.as_secs(),
)
}
}
impl From<Time> for SystemTime {
fn from(time: Time) -> Self {
UNIX_EPOCH + StdDuration::from_secs(time.0)
}
}
impl Time {
pub fn now() -> Self {
SystemTime::now().into()
}
pub const fn new(secs: u64) -> Self {
Self(secs)
}
pub fn as_secs(self) -> u64 {
self.0
}
pub fn checked_add(self, duration: Duration) -> Option<Self> {
match self.0.checked_add(duration.0) {
Some(value) => Some(Self(value)),
None => None,
}
}
}
impl WriteTo for Time {
fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
self.0.write_to(w)
}
}
impl ReadFrom for Time {
fn read_from(r: &mut dyn Read) -> io::Result<Self>
where
Self: Sized,
{
Ok(Self(u64::read_from(r)?))
}
}
impl LenBm for Time {
fn len_bm(&self) -> usize {
self.0.len_bm()
}
}
#[test]
fn test_time_write_to() {
let test: Time = 0x0123_4567_89ab_cdef.into();
let mut bytes = Vec::new();
test.write_to(&mut bytes).unwrap();
let expected = [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef];
assert_eq!(bytes, expected);
}
#[test]
fn test_time_read_from() {
use std::io::Cursor;
let mut bytes = Cursor::new(vec![0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);
let test = Time::read_from(&mut bytes).unwrap();
let expected: Time = 0x0123_4567_89ab_cdef.into();
assert_eq!(test, expected);
}