use std::error::Error;
use std::fmt::Display;
use std::ops::Bound;
use jiff::Timestamp;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use crate::intervals::absolute::{AbsEndBound, AbsFiniteEndBound, AbsFiniteStartBound, AbsStartBound};
use crate::intervals::meta::{BoundInclusivity, HasBoundInclusivity};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct AbsFiniteBoundPos {
time: Timestamp,
inclusivity: BoundInclusivity,
}
impl AbsFiniteBoundPos {
#[must_use]
pub fn new(time: Timestamp) -> Self {
Self::new_with_incl(time, BoundInclusivity::default())
}
#[must_use]
pub fn new_with_incl(time: Timestamp, inclusivity: BoundInclusivity) -> Self {
AbsFiniteBoundPos {
time,
inclusivity,
}
}
#[must_use]
pub fn time(&self) -> Timestamp {
self.time
}
pub fn set_time(&mut self, new_time: Timestamp) {
self.time = new_time;
}
pub fn set_inclusivity(&mut self, new_inclusivity: BoundInclusivity) {
self.inclusivity = new_inclusivity;
}
#[must_use]
pub fn to_finite_start_bound(self) -> AbsFiniteStartBound {
AbsFiniteStartBound::new(self)
}
#[must_use]
pub fn to_start_bound(self) -> AbsStartBound {
AbsStartBound::from(self)
}
#[must_use]
pub fn to_finite_end_bound(self) -> AbsFiniteEndBound {
AbsFiniteEndBound::new(self)
}
#[must_use]
pub fn to_end_bound(self) -> AbsEndBound {
AbsEndBound::from(self)
}
}
impl HasBoundInclusivity for AbsFiniteBoundPos {
fn inclusivity(&self) -> BoundInclusivity {
self.inclusivity
}
}
impl From<Timestamp> for AbsFiniteBoundPos {
fn from(value: Timestamp) -> Self {
AbsFiniteBoundPos::new(value)
}
}
impl From<(Timestamp, BoundInclusivity)> for AbsFiniteBoundPos {
fn from((time, inclusivity): (Timestamp, BoundInclusivity)) -> Self {
AbsFiniteBoundPos::new_with_incl(time, inclusivity)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct AbsFiniteBoundPosTryFromBoundError;
impl Display for AbsFiniteBoundPosTryFromBoundError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"An error occurred when trying to convert `Bound<Timestamp>` into `AbsFiniteBoundPos`"
)
}
}
impl Error for AbsFiniteBoundPosTryFromBoundError {}
impl TryFrom<Bound<Timestamp>> for AbsFiniteBoundPos {
type Error = AbsFiniteBoundPosTryFromBoundError;
fn try_from(value: Bound<Timestamp>) -> Result<Self, Self::Error> {
match value {
Bound::Included(time) => Ok(AbsFiniteBoundPos::new_with_incl(time, BoundInclusivity::Inclusive)),
Bound::Excluded(time) => Ok(AbsFiniteBoundPos::new_with_incl(time, BoundInclusivity::Exclusive)),
Bound::Unbounded => Err(AbsFiniteBoundPosTryFromBoundError),
}
}
}