use std::cmp::Ordering;
use num_traits::Zero;
use super::{Constrained, Constraint, ConstraintError};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct NonZero;
impl NonZero {
pub fn new<T: PartialOrd + Zero>(value: T) -> Result<Constrained<T, NonZero>, ConstraintError> {
Constrained::<T, NonZero>::new(value)
}
}
impl<T: PartialOrd + Zero> Constraint<T> for NonZero {
fn check(value: &T) -> Result<(), ConstraintError> {
match value.partial_cmp(&T::zero()) {
Some(Ordering::Greater | Ordering::Less) => Ok(()),
Some(Ordering::Equal) => Err(ConstraintError::Zero),
None => Err(ConstraintError::NotANumber),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn integers() {
let one = Constrained::<_, NonZero>::new(1).unwrap();
assert_eq!(one.into_inner(), 1);
let neg_one = NonZero::new(-1).unwrap();
assert_eq!(neg_one.as_ref(), &-1);
assert!(NonZero::new(0).is_err());
}
#[test]
fn floats() {
assert!(Constrained::<f64, NonZero>::new(2.0).is_ok());
assert!(NonZero::new(-3.5).is_ok());
assert!(NonZero::new(0.0).is_err());
assert!(NonZero::new(f64::NAN).is_err());
}
}