use crate::calc::*;
use crate::conv::*;
use crate::parts::*;
use crate::shorthands::aliases::*;
use crate::shorthands::*;
use crate::*;
use core::borrow::Borrow;
use core::ops::{Add, Bound, Range, RangeBounds, Sub};
use rustdoc_copy::prelude::*;
#[doc_on_only]
#[doc_share(doc_rrb)]
pub trait RichRangeBounds<T>: RangeBounds<T>
where
T: ?Sized,
{
#[must_use]
#[doc_on_only]
fn is_empty(&self) -> bool
where
T: PartialOrd,
{
match (self.start_bound(), self.end_bound()) {
(Ub, _) => false,
(_, Ub) => false,
(In(s), Ex(e)) => s >= e,
(Ex(s), In(e)) => s >= e,
(Ex(s), Ex(e)) => s >= e,
(In(s), In(e)) => s > e,
}
}
#[must_use]
#[doc_on_only]
fn is_broken(&self) -> bool
where
T: PartialOrd,
{
rv::new(self).is_empty() && !self.is_cursor()
}
#[must_use]
#[doc_on_only]
fn is_cursor(&self) -> bool
where
T: PartialEq,
{
self.is_cursor_fwd() || self.is_cursor_bwd()
}
#[must_use]
#[doc_on_only]
fn is_cursor_fwd(&self) -> bool
where
T: PartialEq,
{
matches!((self.start_bound(), self.end_bound()), (In(s), Ex(e)) if s == e)
}
#[must_use]
#[doc_on_only]
fn is_cursor_bwd(&self) -> bool
where
T: PartialEq,
{
matches!((self.start_bound(), self.end_bound()), (Ex(s), In(e)) if s == e)
}
#[must_use]
#[doc_on_only]
fn is_point(&self) -> bool
where
T: PartialEq,
{
matches!((self.start_bound(), self.end_bound()), (In(s), In(e)) if s == e)
}
#[must_use]
#[doc_on_only]
fn is_wide(&self) -> bool
where
T: PartialOrd,
{
matches!((self.start_bound(), self.end_bound()), (Ub, _) | (_, Ub))
}
#[must_use]
#[doc_on_only]
fn is_full(&self) -> bool
where
T: PartialOrd,
{
matches!((self.start_bound(), self.end_bound()), (Ub, Ub))
}
#[must_use]
#[doc_on_only]
fn start_edge(&self) -> Edge<&T> {
Edge::new(Side::S, self.start_bound())
}
#[must_use]
#[doc_on_only]
fn end_edge(&self) -> Edge<&T> {
Edge::new(Side::E, self.end_bound())
}
#[must_use]
#[doc_on_only]
fn head(&self) -> T
where
T: Clone + HasLimits + HasNexts,
{
norm::sb_to_head(self.start_bound()).expect(msg::NO_OVF)
}
#[must_use]
#[doc_on_only]
fn tail(&self) -> T
where
T: Clone + HasLimits + HasNexts,
{
norm::eb_to_tail(self.end_bound()).expect(msg::NO_OVF)
}
#[must_use]
#[doc_on_only]
fn prev(&self) -> T
where
T: Clone + HasLimits + HasNexts,
{
norm::sb_to_prev(self.start_bound()).expect(msg::NO_OVF)
}
#[must_use]
#[doc_on_only]
fn next(&self) -> T
where
T: Clone + HasLimits + HasNexts,
{
norm::eb_to_next(self.end_bound()).expect(msg::NO_OVF)
}
#[must_use]
#[doc_on_only]
fn cursor(&self) -> Option<&T>
where
T: PartialEq,
{
if !self.is_cursor() {
return None;
}
match (self.start_bound(), self.end_bound()) {
(In(s), Ex(_)) => Some(s),
(Ex(_), In(e)) => Some(e),
_ => unreachable!(),
}
}
#[must_use]
#[doc_on_only]
fn point(&self) -> Option<&T>
where
T: PartialEq,
{
self.is_point()
.then(|| bound(self.start_bound()).pos().unwrap())
}
#[must_use]
#[doc_on_only]
fn len(&self) -> Option<usize>
where
T: Step,
{
util::len_usize_between(self.start_bound(), self.end_bound())
}
#[must_use]
#[doc_on_only]
fn size(&self) -> Option<T>
where
T: Step,
for<'a> &'a T: Sub<&'a T, Output = T>,
{
util::len_between(self.start_bound(), self.end_bound())
}
#[must_use]
#[doc_on_only]
fn width(&self) -> Option<T>
where
T: Sized + PartialOrd,
for<'a> &'a T: Sub<&'a T, Output = T>,
{
let empty = rv::new(self).is_empty();
let s = bound(self.start_bound()).pos()?;
let e = bound(self.end_bound()).pos()?;
Some(e - (if empty { e } else { s }))
}
#[must_use]
#[doc_on_only]
fn bounds(&self) -> (Bound<&T>, Bound<&T>) {
(self.start_bound(), self.end_bound())
}
#[must_use]
#[doc_on_only]
fn edges(&self) -> (Edge<&T>, Edge<&T>) {
(self.start_edge(), self.end_edge())
}
#[must_use]
#[doc_on_only]
fn as_ref(&self) -> Self::Range<&T>
where
T: Sized,
Self: RangeSrc<T>,
{
let s = self.start_bound();
let e = self.end_bound();
<Self as RangeSrc<_>>::new((s, e)).unwrap()
}
#[must_use]
#[doc_on_only]
fn cast<U>(self) -> Self::Range<U>
where
T: Sized,
U: From<T>,
Self: Sized + RangeSrc<T> + RangeParts<T>,
{
self.map(U::from)
}
#[must_use]
#[doc_on_only]
fn try_cast<U>(self) -> Option<Self::Range<U>>
where
T: Sized,
U: TryFrom<T>,
Self: Sized + RangeSrc<T> + RangeParts<T>,
{
self.try_map(|x| U::try_from(x).ok())
}
#[must_use]
#[doc_on_only]
fn to_range(&self) -> Range<T>
where
T: Clone,
T: HasLimits + HasNexts,
{
let s = norm::sb_to_head(self.start_bound()).expect(msg::NO_OVF);
let e = norm::eb_to_next(self.end_bound()).expect(msg::NO_OVF);
s..e
}
#[must_use]
#[doc_on_only]
fn into_option(self) -> Option<Self>
where
Self: Sized,
T: PartialOrd,
{
(!rv::new(&self).is_empty()).then_some(self)
}
#[doc_on_only]
fn iter(&self) -> IterRichRange<T>
where
T: Step,
{
let s = self.start_bound().cloned();
let e = self.end_bound().cloned();
IterRichRange::new(s, e)
}
#[must_use]
#[doc_on_only]
fn flip(&self) -> (Option<RangeUniv<T>>, Option<RangeUniv<T>>)
where
T: Clone + PartialOrd,
{
calc::flip(self)
}
#[must_use]
#[doc_on_only]
fn flip_adv(&self, mode: CursorMode) -> (Option<RangeUniv<T>>, Option<RangeUniv<T>>)
where
T: Clone + PartialOrd,
{
calc::flip_adv(self, mode)
}
#[must_use]
#[doc_on_only]
fn shl(&self, value: impl Borrow<T>) -> Self::Range<T>
where
T: Sized,
Self: RangeSrc<T>,
for<'a> &'a T: Sub<&'a T, Output = T>,
{
calc::shl(self, value)
}
#[must_use]
#[doc_on_only]
fn shr(&self, value: impl Borrow<T>) -> Self::Range<T>
where
T: Sized,
Self: RangeSrc<T>,
for<'a> &'a T: Add<&'a T, Output = T>,
{
calc::shr(self, value)
}
#[must_use]
#[doc_on_only]
fn add_start(&self, value: impl Borrow<T>) -> Self::Range<T>
where
T: Clone,
Self: RangeSrc<T>,
for<'a> &'a T: Add<&'a T, Output = T>,
{
calc::add_start(self, value)
}
#[must_use]
#[doc_on_only]
fn add_end(&self, value: impl Borrow<T>) -> Self::Range<T>
where
T: Clone,
Self: RangeSrc<T>,
for<'a> &'a T: Add<&'a T, Output = T>,
{
calc::add_end(self, value)
}
#[must_use]
#[doc_on_only]
fn sub_start(&self, value: impl Borrow<T>) -> Self::Range<T>
where
T: Clone,
Self: RangeSrc<T>,
for<'a> &'a T: Sub<&'a T, Output = T>,
{
calc::sub_start(self, value)
}
#[must_use]
#[doc_on_only]
fn sub_end(&self, value: impl Borrow<T>) -> Self::Range<T>
where
T: Clone,
Self: RangeSrc<T>,
for<'a> &'a T: Sub<&'a T, Output = T>,
{
calc::sub_end(self, value)
}
#[must_use]
#[doc_on_only]
fn calc_start(&self, width: impl Borrow<T>) -> Self::Range<T>
where
T: Clone,
Self: RangeSrc<T>,
for<'a> &'a T: Sub<&'a T, Output = T>,
{
calc::calc_start(self, width)
}
#[must_use]
#[doc_on_only]
fn calc_end(&self, width: impl Borrow<T>) -> Self::Range<T>
where
T: Clone,
Self: RangeSrc<T>,
for<'a> &'a T: Add<&'a T, Output = T>,
{
calc::calc_end(self, width)
}
#[must_use]
#[doc_on_only]
fn align_start(&self, value: impl Borrow<T>) -> Self::Range<T>
where
T: Clone + PartialOrd,
Self: RangeSrc<T>,
for<'a> &'a T: CheckedAdd<&'a T, Output = T>,
for<'a> &'a T: CheckedSub<&'a T, Output = T>,
{
calc::align_start(self, value).unwrap()
}
#[must_use]
#[doc_on_only]
fn align_end(&self, value: impl Borrow<T>) -> Self::Range<T>
where
T: Clone + PartialOrd,
Self: RangeSrc<T>,
for<'a> &'a T: CheckedAdd<&'a T, Output = T>,
for<'a> &'a T: CheckedSub<&'a T, Output = T>,
{
calc::align_end(self, value).unwrap()
}
#[must_use]
#[doc_on_only]
fn map<F, U>(self, mut f: F) -> Self::Range<U>
where
T: Sized,
F: FnMut(T) -> U,
Self: Sized + RangeSrc<T> + RangeParts<T>,
{
let bounds = RangeParts::parts(self);
let s = bounds.0.map(&mut f);
let e = bounds.1.map(&mut f);
<Self as RangeSrc<_>>::new((s, e)).unwrap()
}
#[must_use]
#[doc_on_only]
fn try_map<F, U>(self, mut f: F) -> Option<Self::Range<U>>
where
T: Sized,
F: FnMut(T) -> Option<U>,
Self: Sized + RangeSrc<T> + RangeParts<T>,
{
let bounds = RangeParts::parts(self);
let s = bound(bounds.0).try_map(&mut f)?;
let e = bound(bounds.1).try_map(&mut f)?;
Some(<Self as RangeSrc<_>>::new((s, e)).unwrap())
}
#[must_use]
#[doc_on_only]
fn checked_shl(&self, value: impl Borrow<T>) -> Option<Self::Range<T>>
where
T: Sized,
Self: RangeSrc<T>,
for<'a> &'a T: CheckedSub<&'a T, Output = T>,
{
calc::checked_shl(self, value)
}
#[must_use]
#[doc_on_only]
fn checked_shr(&self, value: impl Borrow<T>) -> Option<Self::Range<T>>
where
T: Sized,
Self: RangeSrc<T>,
for<'a> &'a T: CheckedAdd<&'a T, Output = T>,
{
calc::checked_shr(self, value)
}
#[must_use]
#[doc_on_only]
fn checked_add_start(&self, value: impl Borrow<T>) -> Option<Self::Range<T>>
where
T: Clone,
Self: RangeSrc<T>,
for<'a> &'a T: CheckedAdd<&'a T, Output = T>,
{
calc::checked_add_start(self, value)
}
#[must_use]
#[doc_on_only]
fn checked_add_end(&self, value: impl Borrow<T>) -> Option<Self::Range<T>>
where
T: Clone,
Self: RangeSrc<T>,
for<'a> &'a T: CheckedAdd<&'a T, Output = T>,
{
calc::checked_add_end(self, value)
}
#[must_use]
#[doc_on_only]
fn checked_sub_start(&self, value: impl Borrow<T>) -> Option<Self::Range<T>>
where
T: Clone,
Self: RangeSrc<T>,
for<'a> &'a T: CheckedSub<&'a T, Output = T>,
{
calc::checked_sub_start(self, value)
}
#[must_use]
#[doc_on_only]
fn checked_sub_end(&self, value: impl Borrow<T>) -> Option<Self::Range<T>>
where
T: Clone,
Self: RangeSrc<T>,
for<'a> &'a T: CheckedSub<&'a T, Output = T>,
{
calc::checked_sub_end(self, value)
}
#[must_use]
#[doc_on_only]
fn checked_calc_start(&self, width: impl Borrow<T>) -> Option<Self::Range<T>>
where
T: Clone,
Self: RangeSrc<T>,
for<'a> &'a T: CheckedSub<&'a T, Output = T>,
{
calc::checked_calc_start(self, width)
}
#[must_use]
#[doc_on_only]
fn checked_calc_end(&self, width: impl Borrow<T>) -> Option<Self::Range<T>>
where
T: Clone,
Self: RangeSrc<T>,
for<'a> &'a T: CheckedAdd<&'a T, Output = T>,
{
calc::checked_calc_end(self, width)
}
#[must_use]
#[doc_on_only]
fn checked_align_start(&self, value: impl Borrow<T>) -> Option<Self::Range<T>>
where
T: Clone + PartialOrd,
Self: RangeSrc<T>,
for<'a> &'a T: CheckedAdd<&'a T, Output = T>,
for<'a> &'a T: CheckedSub<&'a T, Output = T>,
{
let ret = calc::align_start(self, value);
match ret {
Err(Error::Overflow) => None,
x => x.ok(),
}
}
#[must_use]
#[doc_on_only]
fn checked_align_end(&self, value: impl Borrow<T>) -> Option<Self::Range<T>>
where
T: Clone + PartialOrd,
Self: RangeSrc<T>,
for<'a> &'a T: CheckedAdd<&'a T, Output = T>,
for<'a> &'a T: CheckedSub<&'a T, Output = T>,
{
let ret = calc::align_end(self, value);
match ret {
Err(Error::Overflow) => None,
x => x.ok(),
}
}
#[must_use]
#[doc_on_only]
fn equiv<R2>(&self, other: &R2) -> bool
where
R2: ?Sized + RangeBounds<T>,
T: PartialOrd,
{
calc::is_equiv(self, other)
}
#[must_use]
#[doc_on_only]
fn intersects<R2>(&self, other: &R2) -> bool
where
R2: ?Sized + RangeBounds<T>,
T: PartialOrd,
{
calc::is_intersects(self, other)
}
#[must_use]
#[doc_on_only]
fn includes<R2>(&self, other: &R2) -> bool
where
R2: ?Sized + RangeBounds<T>,
T: PartialOrd,
{
calc::is_includes(self, other)
}
#[must_use]
#[doc_on_only]
fn included<R>(&self, other: &R) -> bool
where
R: ?Sized + RangeBounds<T>,
T: PartialOrd,
{
rv::new(other).includes(self)
}
#[must_use]
#[doc_on_only]
fn adjoins<R2>(&self, other: &R2) -> bool
where
R2: ?Sized + RangeBounds<T>,
T: PartialOrd,
{
calc::is_adjoins(self, other)
}
#[must_use]
#[doc_on_only]
fn adjoins_prev<R2>(&self, other: &R2) -> bool
where
R2: ?Sized + RangeBounds<T>,
T: PartialOrd,
{
calc::is_adjoins_prev(self, other)
}
#[must_use]
#[doc_on_only]
fn adjoins_next<R2>(&self, other: &R2) -> bool
where
R2: ?Sized + RangeBounds<T>,
T: PartialOrd,
{
calc::is_adjoins_next(self, other)
}
#[must_use]
#[doc_on_only]
fn touches<R2>(&self, other: &R2) -> bool
where
R2: ?Sized + RangeBounds<T>,
T: PartialOrd,
{
calc::is_touches(self, other)
}
#[must_use]
#[doc_on_only]
fn touches_prev<R2>(&self, other: &R2) -> bool
where
R2: ?Sized + RangeBounds<T>,
T: PartialOrd,
{
calc::is_touches_prev(self, other)
}
#[must_use]
#[doc_on_only]
fn touches_next<R2>(&self, other: &R2) -> bool
where
R2: ?Sized + RangeBounds<T>,
T: PartialOrd,
{
calc::is_touches_next(self, other)
}
#[must_use]
#[doc_on_only]
fn rel<R2>(&self, other: &R2, ps: PosStyle) -> RangeRel
where
R2: ?Sized + RangeBounds<T>,
T: PartialOrd,
{
calc::rel(self, other, ps)
}
#[must_use]
#[doc_on_only]
fn cut(&self, pos: &T, mode: CutMode) -> (Option<RangeUniv<T>>, Option<RangeUniv<T>>)
where
T: Clone + PartialOrd,
{
calc::cut(self, pos, mode)
}
#[must_use]
#[doc_on_only]
fn interval(&self, other: &Self) -> Option<RangeUniv<T>>
where
T: Clone + PartialOrd,
{
assert!(calc::is_mixable(self, other), "{}", msg::BOUNDS_ORDERED);
let ret = calc::interval(self, other)?;
Some(<RangeUniv<T> as RangeSrc<T>>::new_from(ret).unwrap())
}
#[must_use]
#[doc_on_only]
fn interval_adv(&self, other: &Self, mode: CursorMode) -> Option<RangeUniv<T>>
where
T: Clone + PartialOrd,
{
assert!(calc::is_mixable(self, other), "{}", msg::BOUNDS_ORDERED);
let ret = calc::interval_adv(self, other, mode)?;
Some(<RangeUniv<T> as RangeSrc<T>>::new_from(ret).unwrap())
}
#[must_use]
#[doc_on_only]
fn prod(&self, other: &Self) -> Option<Self::Range<T>>
where
Self: RangeSrc<T>,
T: Clone + PartialOrd,
{
assert!(calc::is_mixable(self, other), "{}", msg::BOUNDS_ORDERED);
let ret = calc::prod(self, other)?;
Some(<Self as RangeSrc<T>>::new_from(ret).unwrap())
}
#[must_use]
#[doc_on_only]
fn enwrap(&self, other: &Self) -> Option<Self::Range<T>>
where
Self: RangeSrc<T>,
T: Clone + PartialOrd,
{
assert!(calc::is_mixable(self, other), "{}", msg::BOUNDS_ORDERED);
let ret = calc::enwrap(self, other)?;
Some(<Self as RangeSrc<T>>::new_from(ret).unwrap())
}
#[must_use]
#[doc_on_only]
fn union(&self, other: &Self) -> (Self::Range<T>, Option<Self::Range<T>>)
where
Self: RangeSrc<T>,
T: Clone + PartialOrd,
{
assert!(calc::is_mixable(self, other), "{}", msg::BOUNDS_ORDERED);
let (fst, snd) = calc::union(self, other);
let fst = <Self as RangeSrc<T>>::new_from(fst).unwrap();
let snd = snd.map(|snd| <Self as RangeSrc<T>>::new_from(snd).unwrap());
(fst, snd)
}
#[must_use]
#[doc_on_only]
fn diff<R>(&self, other: &R) -> (Option<RangeUniv<T>>, Option<RangeUniv<T>>)
where
R: ?Sized + RangeBounds<T>,
T: Clone + PartialOrd,
{
assert!(calc::is_mixable(self, other), "{}", msg::BOUNDS_ORDERED);
calc::diff(self, other)
}
#[must_use]
#[doc_on_only]
fn diff_adv<R>(
&self,
other: &R,
mode: CursorMode,
) -> (Option<RangeUniv<T>>, Option<RangeUniv<T>>)
where
R: ?Sized + RangeBounds<T>,
T: Clone + PartialOrd,
{
assert!(calc::is_mixable(self, other), "{}", msg::BOUNDS_ORDERED);
calc::diff_adv(self, other, mode)
}
}
pub(crate) trait RichRangeBoundsPv<T>: RichRangeBounds<T>
where
T: ?Sized,
{
fn at_edge(&self, pos: &T) -> bool
where
T: PartialEq,
{
let stt = bound(self.start_bound()).pos();
let end = bound(self.end_bound()).pos();
Some(pos) == stt || Some(pos) == end
}
}
impl<T, U> RichRangeBoundsPv<U> for T
where
T: ?Sized + RichRangeBounds<U>,
U: ?Sized,
{
}