use std::time;
use std::ops::{
Add,
Sub
};
use super::{
Point,
Span
};
impl Point {
pub const MIN: Self = Self::from_epoch(i64::MIN);
pub const MAX: Self = Self::from_epoch(i64::MAX);
pub const fn from_epoch(timestamp: i64) -> Self {
Self {timestamp}
}
pub fn now() -> Self {
let sys = time::SystemTime::now();
let timestamp = match sys.duration_since(time::UNIX_EPOCH) {
Ok(duration) => duration.as_secs() as i64,
Err(err) => -(err.duration().as_secs() as i64)
};
Self {timestamp}
}
pub const fn checked_add(self, span: Span) -> Option<Self> {
match self.shift_to_u64().checked_add(span.seconds) {
Some(unsigned) => Some(Self::shift_from_u64(unsigned)),
None => None
}
}
pub const fn checked_sub(self, span: Span) -> Option<Self> {
match self.shift_to_u64().checked_sub(span.seconds) {
Some(unsigned) => Some(Self::shift_from_u64(unsigned)),
None => None
}
}
pub const fn saturating_add(self, span: Span) -> Self {
Self::shift_from_u64(
self.shift_to_u64().saturating_add(span.seconds)
)
}
pub const fn saturating_sub(self, span: Span) -> Self {
Self::shift_from_u64(
self.shift_to_u64().saturating_sub(span.seconds)
)
}
const fn shift_to_u64(self) -> u64 {
(self.timestamp as u64).wrapping_add(u64::MAX / 2 + 1)
}
const fn shift_from_u64(u: u64) -> Self {
Self { timestamp: u.wrapping_sub(u64::MAX / 2 + 1) as i64 }
}
}
impl Add<Span> for Point {
type Output = Self;
fn add(self, rhs: Span) -> Self::Output {
let timestamp = self.timestamp + rhs.seconds as i64;
Self {timestamp}
}
}
impl Sub<Span> for Point {
type Output = Self;
fn sub(self, rhs: Span) -> Self::Output {
let timestamp = self.timestamp - rhs.seconds as i64;
Self {timestamp}
}
}
impl Sub<Point> for Point {
type Output = Span;
fn sub(self, rhs: Point) -> Self::Output {
let seconds = self.timestamp.abs_diff(rhs.timestamp);
Span {seconds}
}
}
impl From<time::SystemTime> for Point {
fn from(sys: time::SystemTime) -> Self {
let timestamp = match sys.duration_since(time::UNIX_EPOCH) {
Ok(duration) => duration.as_secs() as i64,
Err(err) => -(err.duration().as_secs() as i64)
};
Self {timestamp}
}
}