use super::*;
use std::ops::{Add, Range, RangeTo};
use proptest::num::f64;
macro_rules! default {
($type: ty, $val: expr) => {
impl Default for $type {
fn default() -> Self { $val.into() }
}
};
}
default!(Probability, 0.5);
impl From<f64> for Probability {
fn from(prob: f64) -> Self {
Probability::new(prob)
}
}
impl Probability {
pub fn new(prob: f64) -> Self {
assert!(prob >= 0.0 && prob <= 1.0);
Probability(prob)
}
}
impl_arbitrary!(Probability, SFnPtrMap<Range<f64>, Self>, {
static_map((0.0..1.0), Probability::new)
});
#[derive(Clone, Copy, PartialEq, Debug, Into,
Add, Sub, AddAssign, SubAssign, Mul, Div, Rem, Shr, Shl,
MulAssign, DivAssign, RemAssign, ShrAssign, ShlAssign)]
#[cfg_attr(feature = "frunk", derive(Generic))]
pub struct Probability(f64);
default!(SizeBounds, 0..100);
type U2 = (usize, usize);
impl SizeBounds {
pub fn new(range: Range<usize>) -> Self {
SizeBounds(range)
}
pub (crate) fn and<X>(self, and: X) -> (Self, X) {
(self, and)
}
}
pub (crate) fn size_bounds<X>(from: X) -> SizeBounds
where
SizeBounds: From<X> {
SizeBounds::from(from)
}
impl From<U2> for SizeBounds {
fn from(x: U2) -> Self {
(x.0..x.1).into()
}
}
impl From<usize> for SizeBounds {
fn from(high: usize) -> Self {
(high, high + 1).into()
}
}
impl From<RangeTo<usize>> for SizeBounds {
fn from(high: RangeTo<usize>) -> Self {
(0, high.end).into()
}
}
impl Add<usize> for SizeBounds {
type Output = SizeBounds;
fn add(self, rhs: usize) -> Self::Output {
let Range { start, end } = self.into();
Range {
start: start + rhs,
end: end + rhs
}.into()
}
}
impl_arbitrary!(SizeBounds, SMapped<'a, U2, Self>, {
static_map(any::<U2>(), <SizeBounds as From<U2>>::from)
});
#[derive(Clone, PartialEq, Eq, Hash, Debug, From, Into)]
#[cfg_attr(feature = "frunk", derive(Generic))]
pub struct SizeBounds(Range<usize>);