hoomd_utility/valid/
positive_real.rs1use serde::{Deserialize, Serialize};
7use std::{
8 fmt,
9 ops::{Div, DivAssign, Mul, MulAssign},
10};
11
12use super::Error;
13
14#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
27pub struct PositiveReal(f64);
28
29impl PositiveReal {
30 #[must_use]
44 #[inline]
45 pub fn get(&self) -> f64 {
46 self.0
47 }
48}
49
50impl TryFrom<f64> for PositiveReal {
51 type Error = Error;
52
53 #[inline]
83 fn try_from(v: f64) -> Result<PositiveReal, Error> {
84 if !v.is_finite() {
85 Err(Error::NotFinite(v))
86 } else if v <= 0.0 {
87 Err(Error::NotPositive(v))
88 } else {
89 Ok(PositiveReal(v))
90 }
91 }
92}
93
94impl Default for PositiveReal {
95 #[inline]
97 fn default() -> Self {
98 PositiveReal(1.0)
99 }
100}
101
102impl fmt::Display for PositiveReal {
103 #[inline]
104 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105 self.0.fmt(f)
106 }
107}
108
109impl Mul for PositiveReal {
110 type Output = Self;
111
112 #[inline]
113 fn mul(self, rhs: Self) -> Self {
114 Self(self.0 * rhs.0)
115 }
116}
117
118impl MulAssign<PositiveReal> for PositiveReal {
119 #[inline]
120 fn mul_assign(&mut self, rhs: PositiveReal) {
121 self.0 *= rhs.0;
122 }
123}
124
125impl Div for PositiveReal {
126 type Output = Self;
127
128 #[inline]
129 fn div(self, rhs: Self) -> Self {
130 Self(self.0 / rhs.0)
131 }
132}
133
134impl DivAssign<PositiveReal> for PositiveReal {
135 #[inline]
136 fn div_assign(&mut self, rhs: PositiveReal) {
137 self.0 /= rhs.0;
138 }
139}
140
141#[cfg(test)]
142mod tests {
143 use super::*;
144 use assert2::check;
145
146 #[test]
147 fn positive_real_validation() {
148 let result = PositiveReal::try_from(f64::INFINITY);
149 check!(result == Err(Error::NotFinite(f64::INFINITY)));
150
151 let result = PositiveReal::try_from(-f64::INFINITY);
152 check!(result == Err(Error::NotFinite(-f64::INFINITY)));
153
154 let result = PositiveReal::try_from(f64::NAN);
155 check!(matches!(result, Err(Error::NotFinite(_))));
156
157 let result = PositiveReal::try_from(0.0);
158 check!(result == Err(Error::NotPositive(0.0)));
159
160 let result = PositiveReal::try_from(-1.0);
161 check!(result == Err(Error::NotPositive(-1.0)));
162 }
163}