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