#![deny(missing_docs)]
use num_traits::{Num, NumCast};
use std::cmp;
use std::fmt::Debug;
use std::ops::{Range, RangeInclusive};
pub fn clamp<N>(value: N, range: RangeInclusive<N>) -> N
where
N: PartialOrd,
{
let (low, high) = range.into_inner();
assert!(low <= high);
if value < low {
low
} else if value > high {
high
} else {
value
}
}
pub fn map_range<N, M>(
value: N,
Range {
start: in_low,
end: in_high,
}: Range<N>,
Range {
start: out_low,
end: out_high,
}: Range<M>,
) -> M
where
N: Num + NumCast + Copy + PartialOrd + Debug,
M: Num + NumCast + Copy + PartialOrd + Debug,
{
assert!(in_low < in_high, "{:?} < {:?}", in_low, in_high);
assert!(out_low < out_high, "{:?} < {:?}", out_low, out_high);
assert!(value >= in_low, "{:?} >= {:?}", value, in_low);
assert!(value <= in_high, "{:?} <= {:?}", value, in_high);
let value: M = NumCast::from(value).unwrap();
let in_low: M = NumCast::from(in_low).unwrap();
let in_high: M = NumCast::from(in_high).unwrap();
let dividend = out_high - out_low;
let divisor = in_high - in_low;
assert!(!divisor.is_zero());
let slope = dividend / divisor;
out_low + (slope * (value - in_low))
}
#[derive(Copy, Clone, Debug, Default, PartialOrd, PartialEq, Hash)]
pub struct NoMorePartial<T>(pub T);
impl<T: PartialOrd> cmp::Ord for NoMorePartial<T> {
#[inline]
fn cmp(&self, other: &Self) -> cmp::Ordering {
self.partial_cmp(other).unwrap()
}
}
impl<T: PartialEq> cmp::Eq for NoMorePartial<T> {}