Skip to main content

clt_database/numeric/
nonnan.rs

1#[repr(transparent)]
2#[derive(Debug, Clone, Copy, PartialEq)]
3#[cfg_attr(
4    clt_turso_feature = "serde",
5    derive(serde::Serialize, serde::Deserialize)
6)]
7pub struct NonNan(f64);
8
9impl NonNan {
10    pub const fn new(value: f64) -> Option<Self> {
11        if value.is_nan() {
12            return None;
13        }
14
15        Some(NonNan(value))
16    }
17}
18
19impl PartialEq<NonNan> for f64 {
20    fn eq(&self, other: &NonNan) -> bool {
21        *self == other.0
22    }
23}
24
25impl PartialEq<f64> for NonNan {
26    fn eq(&self, other: &f64) -> bool {
27        self.0 == *other
28    }
29}
30
31impl PartialOrd<f64> for NonNan {
32    fn partial_cmp(&self, other: &f64) -> Option<std::cmp::Ordering> {
33        self.0.partial_cmp(other)
34    }
35}
36
37impl PartialOrd<NonNan> for f64 {
38    fn partial_cmp(&self, other: &NonNan) -> Option<std::cmp::Ordering> {
39        self.partial_cmp(&other.0)
40    }
41}
42
43impl From<i64> for NonNan {
44    fn from(value: i64) -> Self {
45        NonNan(value as f64)
46    }
47}
48
49impl From<NonNan> for f64 {
50    fn from(value: NonNan) -> Self {
51        value.0
52    }
53}
54
55impl std::ops::Deref for NonNan {
56    type Target = f64;
57
58    fn deref(&self) -> &Self::Target {
59        &self.0
60    }
61}
62
63impl std::ops::Add for NonNan {
64    type Output = Option<NonNan>;
65
66    fn add(self, rhs: Self) -> Self::Output {
67        Self::new(self.0 + rhs.0)
68    }
69}
70
71impl std::ops::Sub for NonNan {
72    type Output = Option<NonNan>;
73
74    fn sub(self, rhs: Self) -> Self::Output {
75        Self::new(self.0 - rhs.0)
76    }
77}
78
79impl std::ops::Mul for NonNan {
80    type Output = Option<NonNan>;
81
82    fn mul(self, rhs: Self) -> Self::Output {
83        Self::new(self.0 * rhs.0)
84    }
85}
86
87impl std::ops::Div for NonNan {
88    type Output = Option<NonNan>;
89
90    fn div(self, rhs: Self) -> Self::Output {
91        Self::new(self.0 / rhs.0)
92    }
93}
94
95impl std::ops::Rem for NonNan {
96    type Output = Option<NonNan>;
97
98    fn rem(self, rhs: Self) -> Self::Output {
99        Self::new(self.0 % rhs.0)
100    }
101}
102
103impl std::fmt::Display for NonNan {
104    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105        self.0.fmt(f)
106    }
107}
108
109impl std::ops::Neg for NonNan {
110    type Output = Self;
111
112    fn neg(self) -> Self::Output {
113        Self(-self.0)
114    }
115}