1use crate::base::{TypedValue, ValueAsScalar};
2
3use super::{ValueType, fmt};
4use std::convert::TryFrom;
5use std::ops::{Index, IndexMut};
6
7#[cfg(feature = "ordered-float")]
8use ordered_float::OrderedFloat;
9
10#[cfg(not(feature = "ordered-float"))]
11use float_cmp::approx_eq;
12
13mod cmp;
14mod from;
15
16#[derive(Debug, Clone, Copy)]
18#[cfg_attr(feature = "ordered-float", derive(Eq))]
19#[cfg_attr(feature = "c-abi", repr(C))]
20#[cfg_attr(feature = "c-abi", derive(abi_stable::StableAbi))]
21
22pub enum StaticNode {
23 I64(i64),
25 #[cfg(feature = "128bit")]
26 I128(i128),
28 U64(u64),
30 #[cfg(feature = "128bit")]
31 U128(u128),
33 #[cfg(not(feature = "ordered-float"))]
35 F64(f64),
36 #[cfg(feature = "ordered-float")]
37 F64(OrderedFloat<f64>),
39 Bool(bool),
41 Null,
43}
44
45impl Index<&str> for StaticNode {
46 type Output = ();
47 #[inline]
48 #[must_use]
49 fn index(&self, _index: &str) -> &Self::Output {
50 panic!("Not supported")
51 }
52}
53
54impl Index<usize> for StaticNode {
55 type Output = ();
56 #[inline]
57 #[must_use]
58 fn index(&self, _index: usize) -> &Self::Output {
59 panic!("Not supported")
60 }
61}
62
63impl IndexMut<&str> for StaticNode {
64 #[inline]
65 #[must_use]
66 fn index_mut(&mut self, _index: &str) -> &mut Self::Output {
67 panic!("Not supported")
68 }
69}
70
71impl IndexMut<usize> for StaticNode {
72 #[inline]
73 #[must_use]
74 fn index_mut(&mut self, _index: usize) -> &mut Self::Output {
75 panic!("Not supported")
76 }
77}
78
79impl TypedValue for StaticNode {
80 #[cfg(not(feature = "128bit"))]
81 #[inline]
82 #[must_use]
83 fn value_type(&self) -> ValueType {
84 match self {
85 Self::Null => ValueType::Null,
86 Self::Bool(_) => ValueType::Bool,
87 Self::F64(_) => ValueType::F64,
88 Self::I64(_) => ValueType::I64,
89
90 Self::U64(_) => ValueType::U64,
91 }
92 }
93
94 #[cfg(feature = "128bit")]
95 #[inline]
96 #[must_use]
97 fn value_type(&self) -> ValueType {
98 match self {
99 Self::Null => ValueType::Null,
100 Self::Bool(_) => ValueType::Bool,
101 Self::F64(_) => ValueType::F64,
102 Self::I128(_) => ValueType::I128,
103 Self::I64(_) => ValueType::I64,
104 Self::U128(_) => ValueType::U128,
105 Self::U64(_) => ValueType::U64,
106 }
107 }
108}
109
110impl ValueAsScalar for StaticNode {
111 #[inline]
112 #[must_use]
113 fn as_null(&self) -> Option<()> {
114 match self {
115 Self::Null => Some(()),
116 _ => None,
117 }
118 }
119 #[inline]
120 #[must_use]
121 fn as_bool(&self) -> Option<bool> {
122 match self {
123 Self::Bool(b) => Some(*b),
124 _ => None,
125 }
126 }
127
128 #[cfg(not(feature = "128bit"))]
129 #[inline]
130 #[must_use]
131 fn as_i64(&self) -> Option<i64> {
132 match self {
133 Self::I64(i) => Some(*i),
134 Self::U64(i) => i64::try_from(*i).ok(),
135 _ => None,
136 }
137 }
138
139 #[cfg(feature = "128bit")]
140 #[inline]
141 #[must_use]
142 fn as_i64(&self) -> Option<i64> {
143 match self {
144 Self::I64(i) => Some(*i),
145 Self::U64(i) => i64::try_from(*i).ok(),
146 Self::I128(i) => i64::try_from(*i).ok(),
147 Self::U128(i) => i64::try_from(*i).ok(),
148 _ => None,
149 }
150 }
151
152 #[cfg(feature = "128bit")]
153 #[inline]
154 #[must_use]
155 fn as_i128(&self) -> Option<i128> {
156 match self {
157 Self::I128(i) => Some(*i),
158 Self::U128(i) => i128::try_from(*i).ok(),
159 Self::I64(i) => Some(i128::from(*i)),
160 Self::U64(i) => Some(i128::from(*i)),
161 _ => None,
162 }
163 }
164
165 #[cfg(not(feature = "128bit"))]
166 #[inline]
167 #[must_use]
168 fn as_u64(&self) -> Option<u64> {
169 match self {
170 Self::I64(i) => u64::try_from(*i).ok(),
171 Self::U64(i) => Some(*i),
172 _ => None,
173 }
174 }
175
176 #[cfg(feature = "128bit")]
177 #[inline]
178 #[must_use]
179 fn as_u64(&self) -> Option<u64> {
180 match self {
181 Self::I64(i) => u64::try_from(*i).ok(),
182 Self::U64(i) => Some(*i),
183 Self::I128(i) => u64::try_from(*i).ok(),
184 Self::U128(i) => u64::try_from(*i).ok(),
185 _ => None,
186 }
187 }
188 #[cfg(feature = "128bit")]
189 #[inline]
190 #[must_use]
191 fn as_u128(&self) -> Option<u128> {
192 match self {
193 Self::U128(i) => Some(*i),
194 Self::I128(i) => u128::try_from(*i).ok(),
195 Self::I64(i) => u128::try_from(*i).ok(),
196 Self::U64(i) => Some(u128::from(*i)),
197 _ => None,
198 }
199 }
200
201 #[inline]
202 #[must_use]
203 fn as_f64(&self) -> Option<f64> {
204 match self {
205 #[allow(clippy::useless_conversion)] Self::F64(i) => Some((*i).into()),
207 _ => None,
208 }
209 }
210
211 #[cfg(not(feature = "128bit"))]
212 #[inline]
213 #[must_use]
214 #[allow(clippy::cast_precision_loss)]
215 fn cast_f64(&self) -> Option<f64> {
216 match self {
217 #[allow(clippy::useless_conversion)] Self::F64(i) => Some((*i).into()),
219 Self::I64(i) => Some(*i as f64),
220 Self::U64(i) => Some(*i as f64),
221 _ => None,
222 }
223 }
224
225 #[cfg(feature = "128bit")]
226 #[inline]
227 #[allow(clippy::cast_precision_loss)]
228 fn cast_f64(&self) -> Option<f64> {
229 match self {
230 #[allow(clippy::useless_conversion)] Self::F64(i) => Some((*i).into()),
232 Self::I64(i) => Some(*i as f64),
233 Self::U64(i) => Some(*i as f64),
234 Self::I128(i) => Some(*i as f64),
235 Self::U128(i) => Some(*i as f64),
236 _ => None,
237 }
238 }
239
240 #[inline]
241 #[must_use]
242 fn as_str(&self) -> Option<&str> {
243 None
244 }
245}
246
247impl fmt::Display for StaticNode {
248 #[cfg(not(feature = "128bit"))]
249 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
250 match self {
251 Self::Null => write!(f, "null"),
252 Self::Bool(b) => write!(f, "{b}"),
253 Self::I64(n) => write!(f, "{n}"),
254 Self::U64(n) => write!(f, "{n}"),
255 #[cfg(not(feature = "ordered-float"))]
256 Self::F64(n) => write!(f, "{n}"),
257 #[cfg(feature = "ordered-float")]
258 Self::F64(n) => write!(f, "{}", n.0),
259 }
260 }
261 #[cfg(feature = "128bit")]
262 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
263 match self {
264 Self::Null => write!(f, "null"),
265 Self::Bool(b) => write!(f, "{b}"),
266 Self::I64(n) => write!(f, "{n}"),
267 Self::U64(n) => write!(f, "{n}"),
268 #[cfg(not(feature = "ordered-float"))]
269 Self::F64(n) => write!(f, "{n}"),
270 #[cfg(feature = "ordered-float")]
271 Self::F64(n) => write!(f, "{}", n.0),
272 Self::I128(n) => write!(f, "{n}"),
273 Self::U128(n) => write!(f, "{n}"),
274 }
275 }
276}
277
278#[allow(clippy::cast_sign_loss, clippy::default_trait_access)]
279impl PartialEq for StaticNode {
280 #[cfg(not(feature = "128bit"))]
281 #[inline]
282 #[must_use]
283 fn eq(&self, other: &Self) -> bool {
284 match (self, other) {
285 (Self::Null, Self::Null) => true,
286 (Self::Bool(v1), Self::Bool(v2)) => v1.eq(v2),
287 #[cfg(not(feature = "ordered-float"))]
288 (Self::F64(v1), Self::F64(v2)) => approx_eq!(f64, *v1, *v2),
289 #[cfg(feature = "ordered-float")]
290 (Self::F64(v1), Self::F64(v2)) => v1.eq(v2),
291 (Self::U64(v1), Self::U64(v2)) => v1.eq(v2),
292 (Self::I64(v1), Self::I64(v2)) => v1.eq(v2),
293 (Self::U64(v1), Self::I64(v2)) if *v2 >= 0 => (*v2 as u64).eq(v1),
294 (Self::I64(v1), Self::U64(v2)) if *v1 >= 0 => (*v1 as u64).eq(v2),
295 _ => false,
296 }
297 }
298
299 #[cfg(feature = "128bit")]
300 #[inline]
301 #[must_use]
302 fn eq(&self, other: &Self) -> bool {
303 match (self, other) {
304 (Self::Null, Self::Null) => true,
305 (Self::Bool(v1), Self::Bool(v2)) => v1.eq(v2),
306 #[cfg(not(feature = "ordered-float"))]
307 (Self::F64(v1), Self::F64(v2)) => approx_eq!(f64, *v1, *v2),
308 #[cfg(feature = "ordered-float")]
309 (Self::F64(v1), Self::F64(v2)) => v1.eq(v2),
310 (Self::U64(v1), Self::U64(v2)) => v1.eq(v2),
311 (Self::U128(v1), Self::U128(v2)) => v1.eq(v2),
312 (Self::I64(v1), Self::I64(v2)) => v1.eq(v2),
313 (Self::I128(v1), Self::I128(v2)) => v1.eq(v2),
314
315 (Self::U64(v1), Self::I64(v2)) if *v2 >= 0 => (*v2 as u64).eq(v1),
316 (Self::U64(v1), Self::I128(v2)) if *v2 >= 0 => (*v2 as u128).eq(&u128::from(*v1)),
317 (Self::U64(v1), Self::U128(v2)) => v2.eq(&u128::from(*v1)),
318
319 (Self::I64(v1), Self::U64(v2)) if *v1 >= 0 => (*v1 as u64).eq(v2),
320 (Self::I64(v1), Self::I128(v2)) => (*v2).eq(&i128::from(*v1)),
321 (Self::I64(v1), Self::U128(v2)) if *v1 >= 0 => v2.eq(&(*v1 as u128)),
322
323 (Self::U128(v1), Self::I128(v2)) if *v2 >= 0 => (*v2 as u128).eq(v1),
324 (Self::U128(v1), Self::U64(v2)) => v1.eq(&u128::from(*v2)),
325 (Self::U128(v1), Self::I64(v2)) if *v2 >= 0 => v1.eq(&(*v2 as u128)),
326
327 (Self::I128(v1), Self::U128(v2)) if *v1 >= 0 => (*v1 as u128).eq(v2),
328 (Self::I128(v1), Self::U64(v2)) => v1.eq(&i128::from(*v2)),
329 (Self::I128(v1), Self::I64(v2)) => v1.eq(&i128::from(*v2)),
330 _ => false,
331 }
332 }
333}
334
335impl Default for StaticNode {
336 #[must_use]
337 fn default() -> Self {
338 Self::Null
339 }
340}