use core::ops::{RangeFrom, RangeToInclusive, RangeInclusive, RangeFull};
mod private {
pub trait Sealed {}
}
use private::Sealed;
pub trait LimitFloat: Sized {
fn limit<B: LimitFloatBounds<Self>>(self, bounds: B) -> Self {
bounds.limit_bounds(self)
}
}
pub trait LimitFloatBounds<T>: Sealed + Sized {
#[doc(hidden)]
fn limit_bounds(self, value: T) -> T;
}
impl Sealed for RangeFull {}
macro_rules! limit_float {
($(#[$m:meta])* $t:ty) => {
$(#[$m])* impl LimitFloat for $t {}
$(#[$m])* impl Sealed for RangeFrom<$t> {}
$(#[$m])* impl LimitFloatBounds<$t> for RangeFrom<$t> {
#[doc(hidden)]
fn limit_bounds(self, value: $t) -> $t {
value.clamp(self.start, <$t>::INFINITY)
}
}
$(#[$m])* impl Sealed for RangeToInclusive<$t> {}
$(#[$m])* impl LimitFloatBounds<$t> for RangeToInclusive<$t> {
#[doc(hidden)]
fn limit_bounds(self, value: $t) -> $t {
value.clamp(<$t>::NEG_INFINITY, self.end)
}
}
$(#[$m])* impl Sealed for RangeInclusive<$t> {}
$(#[$m])* impl LimitFloatBounds<$t> for RangeInclusive<$t> {
#[doc(hidden)]
fn limit_bounds(self, value: $t) -> $t {
let (start, end) = self.into_inner();
value.clamp(start, end)
}
}
$(#[$m])* impl LimitFloatBounds<$t> for RangeFull {
#[doc(hidden)]
fn limit_bounds(self, value: $t) -> $t {
value
}
}
}
}
limit_float!(f32);
limit_float!(f64);
limit_float!(#[cfg(feature = "nightly")] #[doc(cfg(feature = "nightly"))] f16);
limit_float!(#[cfg(feature = "nightly")] #[doc(cfg(feature = "nightly"))] f128);