use jiff::SignedDuration;
use crate::intervals::meta::HasBoundInclusivity;
use crate::intervals::relative::{
RelBound,
RelEndBound,
RelFiniteBound,
RelFiniteBoundPos,
RelFiniteEndBound,
RelFiniteStartBound,
RelStartBound,
};
use crate::ops::{Precision, PrecisionOutOfRangeError};
pub trait PreciseRelBound {
type PrecisedBoundOutput;
#[must_use]
fn precise(&self, precision: Precision) -> Self::PrecisedBoundOutput;
#[must_use]
fn precise_with_base_offset(&self, precision: Precision, base: SignedDuration) -> Self::PrecisedBoundOutput;
}
impl PreciseRelBound for RelFiniteBoundPos {
type PrecisedBoundOutput = Result<Self, PrecisionOutOfRangeError>;
fn precise(&self, precision: Precision) -> Self::PrecisedBoundOutput {
precise_rel_finite_bound_pos(self, precision)
}
fn precise_with_base_offset(&self, precision: Precision, base: SignedDuration) -> Self::PrecisedBoundOutput {
precise_rel_finite_bound_pos_with_base_offset(self, precision, base)
}
}
impl PreciseRelBound for RelFiniteStartBound {
type PrecisedBoundOutput = Result<Self, PrecisionOutOfRangeError>;
fn precise(&self, precision: Precision) -> Self::PrecisedBoundOutput {
precise_rel_finite_start_bound(self, precision)
}
fn precise_with_base_offset(&self, precision: Precision, base: SignedDuration) -> Self::PrecisedBoundOutput {
precise_rel_finite_start_bound_with_base_offset(self, precision, base)
}
}
impl PreciseRelBound for RelFiniteEndBound {
type PrecisedBoundOutput = Result<Self, PrecisionOutOfRangeError>;
fn precise(&self, precision: Precision) -> Self::PrecisedBoundOutput {
precise_rel_finite_end_bound(self, precision)
}
fn precise_with_base_offset(&self, precision: Precision, base: SignedDuration) -> Self::PrecisedBoundOutput {
precise_rel_finite_end_bound_with_base_offset(self, precision, base)
}
}
impl PreciseRelBound for RelFiniteBound {
type PrecisedBoundOutput = Result<Self, PrecisionOutOfRangeError>;
fn precise(&self, precision: Precision) -> Self::PrecisedBoundOutput {
precise_rel_finite_bound(self, precision)
}
fn precise_with_base_offset(&self, precision: Precision, base: SignedDuration) -> Self::PrecisedBoundOutput {
precise_rel_finite_bound_with_base_offset(self, precision, base)
}
}
impl PreciseRelBound for RelStartBound {
type PrecisedBoundOutput = Result<Self, PrecisionOutOfRangeError>;
fn precise(&self, precision: Precision) -> Self::PrecisedBoundOutput {
precise_rel_start_bound(self, precision)
}
fn precise_with_base_offset(&self, precision: Precision, base: SignedDuration) -> Self::PrecisedBoundOutput {
precise_rel_start_bound_with_base_offset(self, precision, base)
}
}
impl PreciseRelBound for RelEndBound {
type PrecisedBoundOutput = Result<Self, PrecisionOutOfRangeError>;
fn precise(&self, precision: Precision) -> Self::PrecisedBoundOutput {
precise_rel_end_bound(self, precision)
}
fn precise_with_base_offset(&self, precision: Precision, base: SignedDuration) -> Self::PrecisedBoundOutput {
precise_rel_end_bound_with_base_offset(self, precision, base)
}
}
impl PreciseRelBound for RelBound {
type PrecisedBoundOutput = Result<Self, PrecisionOutOfRangeError>;
fn precise(&self, precision: Precision) -> Self::PrecisedBoundOutput {
precise_rel_bound(self, precision)
}
fn precise_with_base_offset(&self, precision: Precision, base: SignedDuration) -> Self::PrecisedBoundOutput {
precise_rel_bound_with_base_offset(self, precision, base)
}
}
pub fn precise_rel_finite_bound_pos(
bound: &RelFiniteBoundPos,
precision: Precision,
) -> Result<RelFiniteBoundPos, PrecisionOutOfRangeError> {
Ok(RelFiniteBoundPos::new_with_incl(
precision.precise_signed_duration(bound.offset())?,
bound.inclusivity(),
))
}
pub fn precise_rel_finite_bound_pos_with_base_offset(
bound: &RelFiniteBoundPos,
precision: Precision,
base: SignedDuration,
) -> Result<RelFiniteBoundPos, PrecisionOutOfRangeError> {
Ok(RelFiniteBoundPos::new_with_incl(
precision.precise_signed_duration_with_base_offset(bound.offset(), base)?,
bound.inclusivity(),
))
}
pub fn precise_rel_finite_start_bound(
bound: &RelFiniteStartBound,
precision: Precision,
) -> Result<RelFiniteStartBound, PrecisionOutOfRangeError> {
Ok(RelFiniteStartBound::new(precise_rel_finite_bound_pos(
&bound.pos(),
precision,
)?))
}
pub fn precise_rel_finite_start_bound_with_base_offset(
bound: &RelFiniteStartBound,
precision: Precision,
base: SignedDuration,
) -> Result<RelFiniteStartBound, PrecisionOutOfRangeError> {
Ok(RelFiniteStartBound::new(precise_rel_finite_bound_pos_with_base_offset(
&bound.pos(),
precision,
base,
)?))
}
pub fn precise_rel_finite_end_bound(
bound: &RelFiniteEndBound,
precision: Precision,
) -> Result<RelFiniteEndBound, PrecisionOutOfRangeError> {
Ok(RelFiniteEndBound::new(precise_rel_finite_bound_pos(
&bound.pos(),
precision,
)?))
}
pub fn precise_rel_finite_end_bound_with_base_offset(
bound: &RelFiniteEndBound,
precision: Precision,
base: SignedDuration,
) -> Result<RelFiniteEndBound, PrecisionOutOfRangeError> {
Ok(RelFiniteEndBound::new(precise_rel_finite_bound_pos_with_base_offset(
&bound.pos(),
precision,
base,
)?))
}
pub fn precise_rel_finite_bound(
bound: &RelFiniteBound,
precision: Precision,
) -> Result<RelFiniteBound, PrecisionOutOfRangeError> {
Ok(match bound {
RelFiniteBound::Start(finite_start) => {
RelFiniteBound::Start(precise_rel_finite_start_bound(finite_start, precision)?)
},
RelFiniteBound::End(finite_end) => RelFiniteBound::End(precise_rel_finite_end_bound(finite_end, precision)?),
})
}
pub fn precise_rel_finite_bound_with_base_offset(
bound: &RelFiniteBound,
precision: Precision,
base: SignedDuration,
) -> Result<RelFiniteBound, PrecisionOutOfRangeError> {
Ok(match bound {
RelFiniteBound::Start(finite_start) => RelFiniteBound::Start(precise_rel_finite_start_bound_with_base_offset(
finite_start,
precision,
base,
)?),
RelFiniteBound::End(finite_end) => RelFiniteBound::End(precise_rel_finite_end_bound_with_base_offset(
finite_end, precision, base,
)?),
})
}
pub fn precise_rel_start_bound(
bound: &RelStartBound,
precision: Precision,
) -> Result<RelStartBound, PrecisionOutOfRangeError> {
Ok(match bound {
RelStartBound::Finite(finite_start) => {
RelStartBound::Finite(precise_rel_finite_start_bound(finite_start, precision)?)
},
RelStartBound::InfinitePast => *bound,
})
}
pub fn precise_rel_start_bound_with_base_offset(
bound: &RelStartBound,
precision: Precision,
base: SignedDuration,
) -> Result<RelStartBound, PrecisionOutOfRangeError> {
Ok(match bound {
RelStartBound::Finite(finite_start) => RelStartBound::Finite(precise_rel_finite_start_bound_with_base_offset(
finite_start,
precision,
base,
)?),
RelStartBound::InfinitePast => *bound,
})
}
pub fn precise_rel_end_bound(
bound: &RelEndBound,
precision: Precision,
) -> Result<RelEndBound, PrecisionOutOfRangeError> {
Ok(match bound {
RelEndBound::Finite(finite_end) => RelEndBound::Finite(precise_rel_finite_end_bound(finite_end, precision)?),
RelEndBound::InfiniteFuture => *bound,
})
}
pub fn precise_rel_end_bound_with_base_offset(
bound: &RelEndBound,
precision: Precision,
base: SignedDuration,
) -> Result<RelEndBound, PrecisionOutOfRangeError> {
Ok(match bound {
RelEndBound::Finite(finite_end) => RelEndBound::Finite(precise_rel_finite_end_bound_with_base_offset(
finite_end, precision, base,
)?),
RelEndBound::InfiniteFuture => *bound,
})
}
pub fn precise_rel_bound(bound: &RelBound, precision: Precision) -> Result<RelBound, PrecisionOutOfRangeError> {
Ok(match bound {
RelBound::Start(start_bound) => RelBound::Start(precise_rel_start_bound(start_bound, precision)?),
RelBound::End(end_bound) => RelBound::End(precise_rel_end_bound(end_bound, precision)?),
})
}
pub fn precise_rel_bound_with_base_offset(
bound: &RelBound,
precision: Precision,
base: SignedDuration,
) -> Result<RelBound, PrecisionOutOfRangeError> {
Ok(match bound {
RelBound::Start(start_bound) => {
RelBound::Start(precise_rel_start_bound_with_base_offset(start_bound, precision, base)?)
},
RelBound::End(end_bound) => RelBound::End(precise_rel_end_bound_with_base_offset(end_bound, precision, base)?),
})
}