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