drasi_core/evaluation/variable_value/
float.rs1use crate::evaluation::variable_value::integer::Integer;
16use core::fmt::{self, Debug, Display};
17use core::hash::{Hash, Hasher};
18use serde::de::{self, Deserialize, Deserializer, Visitor};
19use serde_json::Number;
20
21#[derive(Clone, Default)]
22pub struct Float {
23 value: f64,
24}
25
26impl PartialEq for Float {
27 fn eq(&self, other: &Self) -> bool {
28 let (a, b) = (self.value, other.value);
29 a == b
30 }
31}
32
33impl PartialEq<f64> for Float {
34 fn eq(&self, other: &f64) -> bool {
35 let (a, b) = (self.value, *other);
36 a == b
37 }
38}
39
40impl PartialEq<Integer> for Float {
41 fn eq(&self, other: &Integer) -> bool {
42 match (self.value, other.as_i64()) {
43 (a, Some(b)) => a == b as f64,
44 _ => false,
45 }
46 }
47}
48
49impl Eq for Float {}
50
51impl Hash for Float {
52 fn hash<H: Hasher>(&self, h: &mut H) {
53 if self.value == 0.0f64 {
57 0.0f64.to_bits().hash(h);
58 } else {
59 self.value.to_bits().hash(h);
60 }
61 }
62}
63
64impl Float {
65 #[inline]
66 pub fn is_f64(&self) -> bool {
67 self.value.is_finite()
68 }
69
70 pub(crate) fn as_f64(&self) -> Option<f64> {
71 match self.value {
72 n if n.is_finite() => Some(n),
73 _ => None,
74 }
75 }
76
77 pub(crate) fn as_f32(&self) -> Option<f32> {
78 match self.value {
79 n if n.is_finite() => Some(n as f32),
80 _ => None,
81 }
82 }
83
84 #[inline]
85 pub fn from_f64(f: f64) -> Option<Float> {
86 if f.is_finite() {
87 Some(Float { value: f })
88 } else {
89 None
90 }
91 }
92
93 #[inline]
94 pub(crate) fn from_f32(f: f32) -> Option<Float> {
95 if f.is_finite() {
96 Some(Float { value: f as f64 })
97 } else {
98 None
99 }
100 }
101}
102
103impl From<Float> for Number {
104 fn from(val: Float) -> Self {
105 Number::from_f64(val.value).expect("a finite float")
106 }
107}
108
109impl Debug for Float {
110 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
111 write!(formatter, "Float({self})")
112 }
113}
114
115impl Display for Float {
116 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
117 {
118 let value = &self.value;
119 formatter.write_str(&value.to_string())
120 }
121 }
122}
123
124impl<'de> Deserialize<'de> for Float {
125 #[inline]
126 fn deserialize<D>(deserializer: D) -> Result<Float, D::Error>
127 where
128 D: Deserializer<'de>,
129 {
130 struct NumberVisitor;
131
132 impl Visitor<'_> for NumberVisitor {
133 type Value = Float;
134
135 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
136 formatter.write_str("a JSON number")
137 }
138
139 #[inline]
140 fn visit_f64<E>(self, value: f64) -> Result<Float, E>
141 where
142 E: de::Error,
143 {
144 Ok(Float::from(value))
145 }
146
147 #[inline]
148 fn visit_f32<E>(self, value: f32) -> Result<Float, E>
149 where
150 E: de::Error,
151 {
152 Ok(Float::from(value))
153 }
154 }
155
156 deserializer.deserialize_any(NumberVisitor)
157 }
158}
159
160macro_rules! impl_from_float {
161 (
162 $($ty:ty),*
163 ) => {
164 $(
165 impl From<$ty> for Float {
166 #[inline]
167 fn from(i: $ty) -> Self {
168 let n = {
169 {
170 i as f64
171 }
172 };
173 Float { value: n }
174 }
175 }
176 )*
177 };
178}
179
180impl_from_float!(f32, f64, i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);