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 match self.value {
54 f if f == 0.0f64 => {
55 0.0f64.to_bits().hash(h);
59 }
60 f => {
61 f.to_bits().hash(h);
62 }
63 }
64 }
65}
66
67impl Float {
68 #[inline]
69 pub fn is_f64(&self) -> bool {
70 self.value.is_finite()
71 }
72
73 pub(crate) fn as_f64(&self) -> Option<f64> {
74 match self.value {
75 n if n.is_finite() => Some(n),
76 _ => None,
77 }
78 }
79
80 pub(crate) fn as_f32(&self) -> Option<f32> {
81 match self.value {
82 n if n.is_finite() => Some(n as f32),
83 _ => None,
84 }
85 }
86
87 #[inline]
88 pub fn from_f64(f: f64) -> Option<Float> {
89 if f.is_finite() {
90 Some(Float { value: f })
91 } else {
92 None
93 }
94 }
95
96 #[inline]
97 pub(crate) fn from_f32(f: f32) -> Option<Float> {
98 if f.is_finite() {
99 Some(Float { value: f as f64 })
100 } else {
101 None
102 }
103 }
104}
105
106impl From<Float> for Number {
107 fn from(val: Float) -> Self {
108 Number::from_f64(val.value).expect("a finite float")
109 }
110}
111
112impl Debug for Float {
113 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
114 write!(formatter, "Float({})", self)
115 }
116}
117
118impl Display for Float {
119 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
120 {
121 let value = &self.value;
122 formatter.write_str(&value.to_string())
123 }
124 }
125}
126
127impl<'de> Deserialize<'de> for Float {
128 #[inline]
129 fn deserialize<D>(deserializer: D) -> Result<Float, D::Error>
130 where
131 D: Deserializer<'de>,
132 {
133 struct NumberVisitor;
134
135 impl<'de> Visitor<'de> for NumberVisitor {
136 type Value = Float;
137
138 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
139 formatter.write_str("a JSON number")
140 }
141
142 #[inline]
143 fn visit_f64<E>(self, value: f64) -> Result<Float, E>
144 where
145 E: de::Error,
146 {
147 Ok(Float::from(value))
148 }
149
150 #[inline]
151 fn visit_f32<E>(self, value: f32) -> Result<Float, E>
152 where
153 E: de::Error,
154 {
155 Ok(Float::from(value))
156 }
157 }
158
159 deserializer.deserialize_any(NumberVisitor)
160 }
161}
162
163macro_rules! impl_from_float {
164 (
165 $($ty:ty),*
166 ) => {
167 $(
168 impl From<$ty> for Float {
169 #[inline]
170 fn from(i: $ty) -> Self {
171 let n = {
172 {
173 i as f64
174 }
175 };
176 Float { value: n }
177 }
178 }
179 )*
180 };
181}
182
183impl_from_float!(f32, f64, i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);