1use std::{
26 fmt,
27 hash::{Hash, Hasher},
28 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign},
29};
30
31use crate::*;
32
33#[derive(Debug, PartialEq, PartialOrd, Clone, Copy)]
36pub struct NonNegative {
38 val: f64,
39}
40
41impl NonNegative {
42 pub fn new(val: f64) -> Result<NonNegative> {
44 if val >= 0.0 {
45 return Ok(NonNegative { val });
46 }
47 Err(ErrorKind::NumberInWrongRange)
48 }
49 pub fn zero() -> NonNegative {
51 NonNegative { val: 0.0 }
52 }
53 pub fn one() -> NonNegative {
55 NonNegative { val: 1.0 }
56 }
57 pub fn get(&self) -> f64 {
59 self.val
60 }
61 pub fn sqrt(&self) -> NonNegative {
63 NonNegative {
64 val: self.val.sqrt(),
65 }
66 }
67}
68
69impl From<Positive> for NonNegative {
72 fn from(x: Positive) -> Self {
73 NonNegative { val: x.get() }
74 }
75}
76
77impl Eq for NonNegative {}
78
79impl Hash for NonNegative {
80 #[inline(always)]
81 fn hash<H: Hasher>(&self, state: &mut H) {
82 hash_f64(self.val, state);
83 }
84}
85
86impl Add for NonNegative {
87 type Output = NonNegative;
88
89 fn add(self, other: NonNegative) -> NonNegative {
90 NonNegative {
91 val: self.val + other.val,
92 }
93 }
94}
95
96impl Add<Positive> for NonNegative {
97 type Output = NonNegative;
98
99 fn add(self, other: Positive) -> NonNegative {
100 NonNegative {
101 val: self.val + other.get(),
102 }
103 }
104}
105
106impl AddAssign for NonNegative {
107 fn add_assign(&mut self, other: NonNegative) {
108 self.val += other.val;
109 }
110}
111
112impl AddAssign<Positive> for NonNegative {
113 fn add_assign(&mut self, other: Positive) {
114 self.val += other.get();
115 }
116}
117
118impl Mul for NonNegative {
119 type Output = NonNegative;
120
121 fn mul(self, other: NonNegative) -> NonNegative {
122 NonNegative {
123 val: self.val * other.val,
124 }
125 }
126}
127
128impl Mul<Positive> for NonNegative {
129 type Output = NonNegative;
130
131 fn mul(self, other: Positive) -> NonNegative {
132 NonNegative {
133 val: self.val * other.get(),
134 }
135 }
136}
137
138impl MulAssign for NonNegative {
139 fn mul_assign(&mut self, other: NonNegative) {
140 self.val *= other.val;
141 }
142}
143
144impl MulAssign<Positive> for NonNegative {
145 fn mul_assign(&mut self, other: Positive) {
146 self.val *= other.get();
147 }
148}
149
150impl Div for NonNegative {
151 type Output = NonNegative;
152
153 fn div(self, other: NonNegative) -> NonNegative {
154 NonNegative {
155 val: self.val / other.val,
156 }
157 }
158}
159
160impl Div<Positive> for NonNegative {
161 type Output = NonNegative;
162
163 fn div(self, other: Positive) -> NonNegative {
164 NonNegative {
165 val: self.val / other.get(),
166 }
167 }
168}
169
170impl DivAssign for NonNegative {
171 fn div_assign(&mut self, other: NonNegative) {
172 self.val /= other.val;
173 }
174}
175
176impl DivAssign<Positive> for NonNegative {
177 fn div_assign(&mut self, other: Positive) {
178 self.val /= other.get();
179 }
180}
181
182impl Into<f64> for NonNegative {
183 fn into(self) -> f64 {
184 self.val
185 }
186}
187
188impl AsRef<f64> for NonNegative {
189 fn as_ref(&self) -> &f64 {
190 &self.val
191 }
192}
193
194impl Default for NonNegative {
195 fn default() -> Self {
196 Self::zero()
197 }
198}
199
200impl fmt::Display for NonNegative {
201 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
202 write!(f, "{}", self.val)
203 }
204}