use std::fmt;
use std::ops::{Add, AddAssign, Mul, MulAssign, Div, DivAssign};
use std::hash::{Hash, Hasher};
use prelude::*;
#[derive (Debug, PartialEq, PartialOrd, Clone, Copy)]
pub struct NonNegative {
val: f64
}
impl NonNegative {
pub fn new(val: f64) -> Result<NonNegative> {
if val >= 0.0 {
return Ok(NonNegative {val});
}
Err(ErrorKind::NumberInWrongRange)
}
pub fn zero() -> NonNegative {
NonNegative {val: 0.0}
}
pub fn one() -> NonNegative {
NonNegative {val : 1.0}
}
pub fn get(&self) -> f64 {
self.val
}
pub fn sqrt(&self) -> NonNegative {
NonNegative{val: self.val.sqrt()}
}
}
impl From<Positive> for NonNegative {
fn from(x: Positive) -> Self {
NonNegative {val: x.get() }
}
}
impl Eq for NonNegative {}
impl Hash for NonNegative {
fn hash<H: Hasher>(&self, state: &mut H) {
(self.val as u64).hash(state);
}
}
impl Add for NonNegative {
type Output = NonNegative;
fn add(self, other: NonNegative) -> NonNegative {
NonNegative {val: self.val + other.val}
}
}
impl Add<Positive> for NonNegative {
type Output = NonNegative;
fn add(self, other: Positive) -> NonNegative {
NonNegative {val: self.val + other.get()}
}
}
impl AddAssign for NonNegative {
fn add_assign(&mut self, other: NonNegative) {
self.val += other.val;
}
}
impl AddAssign<Positive> for NonNegative {
fn add_assign(&mut self, other: Positive) {
self.val += other.get();
}
}
impl Mul for NonNegative {
type Output = NonNegative;
fn mul(self, other: NonNegative) -> NonNegative {
NonNegative {val: self.val * other.val}
}
}
impl Mul<Positive> for NonNegative {
type Output = NonNegative;
fn mul(self, other: Positive) -> NonNegative {
NonNegative {val: self.val * other.get()}
}
}
impl MulAssign for NonNegative {
fn mul_assign(&mut self, other: NonNegative) {
self.val *= other.val;
}
}
impl MulAssign<Positive> for NonNegative {
fn mul_assign(&mut self, other: Positive) {
self.val *= other.get();
}
}
impl Div for NonNegative {
type Output = NonNegative;
fn div(self, other: NonNegative) -> NonNegative {
NonNegative {val: self.val / other.val}
}
}
impl Div<Positive> for NonNegative {
type Output = NonNegative;
fn div(self, other: Positive) -> NonNegative {
NonNegative {val: self.val / other.get()}
}
}
impl DivAssign for NonNegative {
fn div_assign(&mut self, other: NonNegative) {
self.val /= other.val;
}
}
impl DivAssign<Positive> for NonNegative {
fn div_assign(&mut self, other: Positive) {
self.val /= other.get();
}
}
impl Default for NonNegative {
fn default() -> Self {
Self::zero()
}
}
impl fmt::Display for NonNegative {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.val)
}
}