use core::ops::{RangeFrom, RangeToInclusive, RangeInclusive, RangeFull};
mod private {
pub trait Sealed {}
}
use private::Sealed;
pub trait Limit: Ord + Sized {
fn limit<B: LimitBounds<Self>>(self, bounds: B) -> Self {
bounds.limit_bounds(self)
}
}
impl<T: Ord> Limit for T {}
pub trait LimitBounds<T>: Sealed + Sized {
#[doc(hidden)]
fn limit_bounds(self, value: T) -> T;
}
impl<T: Ord> Sealed for RangeFrom<T> {}
impl<T: Ord> LimitBounds<T> for RangeFrom<T> {
#[doc(hidden)]
fn limit_bounds(self, value: T) -> T {
value.max(self.start)
}
}
impl<T: Ord> Sealed for RangeToInclusive<T> {}
impl<T: Ord> LimitBounds<T> for RangeToInclusive<T> {
#[doc(hidden)]
fn limit_bounds(self, value: T) -> T {
value.min(self.end)
}
}
impl<T: Ord> Sealed for RangeInclusive<T> {}
impl<T: Ord> LimitBounds<T> for RangeInclusive<T> {
#[doc(hidden)]
fn limit_bounds(self, value: T) -> T {
let (start, end) = self.into_inner();
value.clamp(start, end)
}
}
impl Sealed for RangeFull {}
impl<T: Ord> LimitBounds<T> for RangeFull {
#[doc(hidden)]
fn limit_bounds(self, value: T) -> T {
value
}
}