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))]
21pub enum StaticNode {
22 I64(i64),
24 #[cfg(feature = "128bit")]
25 I128(i128),
27 U64(u64),
29 #[cfg(feature = "128bit")]
30 U128(u128),
32 #[cfg(not(feature = "ordered-float"))]
34 F64(f64),
35 #[cfg(feature = "ordered-float")]
36 F64(OrderedFloat<f64>),
38 Bool(bool),
40 Null,
42}
43
44impl Index<&str> for StaticNode {
45 type Output = ();
46 #[inline]
47 fn index(&self, _index: &str) -> &Self::Output {
48 panic!("Not supported")
49 }
50}
51
52impl Index<usize> for StaticNode {
53 type Output = ();
54 #[inline]
55 fn index(&self, _index: usize) -> &Self::Output {
56 panic!("Not supported")
57 }
58}
59
60impl IndexMut<&str> for StaticNode {
61 #[inline]
62 fn index_mut(&mut self, _index: &str) -> &mut Self::Output {
63 panic!("Not supported")
64 }
65}
66
67impl IndexMut<usize> for StaticNode {
68 #[inline]
69 fn index_mut(&mut self, _index: usize) -> &mut Self::Output {
70 panic!("Not supported")
71 }
72}
73
74impl TypedValue for StaticNode {
75 #[cfg(not(feature = "128bit"))]
76 #[inline]
77 fn value_type(&self) -> ValueType {
78 match self {
79 Self::Null => ValueType::Null,
80 Self::Bool(_) => ValueType::Bool,
81 Self::F64(_) => ValueType::F64,
82 Self::I64(_) => ValueType::I64,
83
84 Self::U64(_) => ValueType::U64,
85 }
86 }
87
88 #[cfg(feature = "128bit")]
89 #[inline]
90 fn value_type(&self) -> ValueType {
91 match self {
92 Self::Null => ValueType::Null,
93 Self::Bool(_) => ValueType::Bool,
94 Self::F64(_) => ValueType::F64,
95 Self::I128(_) => ValueType::I128,
96 Self::I64(_) => ValueType::I64,
97 Self::U128(_) => ValueType::U128,
98 Self::U64(_) => ValueType::U64,
99 }
100 }
101}
102
103impl ValueAsScalar for StaticNode {
104 #[inline]
105 fn as_null(&self) -> Option<()> {
106 match self {
107 Self::Null => Some(()),
108 _ => None,
109 }
110 }
111 #[inline]
112 fn as_bool(&self) -> Option<bool> {
113 match self {
114 Self::Bool(b) => Some(*b),
115 _ => None,
116 }
117 }
118
119 #[cfg(not(feature = "128bit"))]
120 #[inline]
121 fn as_i64(&self) -> Option<i64> {
122 match self {
123 Self::I64(i) => Some(*i),
124 Self::U64(i) => i64::try_from(*i).ok(),
125 _ => None,
126 }
127 }
128
129 #[cfg(feature = "128bit")]
130 #[inline]
131 #[must_use]
132 fn as_i64(&self) -> Option<i64> {
133 match self {
134 Self::I64(i) => Some(*i),
135 Self::U64(i) => i64::try_from(*i).ok(),
136 Self::I128(i) => i64::try_from(*i).ok(),
137 Self::U128(i) => i64::try_from(*i).ok(),
138 _ => None,
139 }
140 }
141
142 #[cfg(feature = "128bit")]
143 #[inline]
144 #[must_use]
145 fn as_i128(&self) -> Option<i128> {
146 match self {
147 Self::I128(i) => Some(*i),
148 Self::U128(i) => i128::try_from(*i).ok(),
149 Self::I64(i) => Some(i128::from(*i)),
150 Self::U64(i) => Some(i128::from(*i)),
151 _ => None,
152 }
153 }
154
155 #[cfg(not(feature = "128bit"))]
156 #[inline]
157 fn as_u64(&self) -> Option<u64> {
158 match self {
159 Self::I64(i) => u64::try_from(*i).ok(),
160 Self::U64(i) => Some(*i),
161 _ => None,
162 }
163 }
164
165 #[cfg(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 Self::I128(i) => u64::try_from(*i).ok(),
173 Self::U128(i) => u64::try_from(*i).ok(),
174 _ => None,
175 }
176 }
177 #[cfg(feature = "128bit")]
178 #[inline]
179 #[must_use]
180 fn as_u128(&self) -> Option<u128> {
181 match self {
182 Self::U128(i) => Some(*i),
183 Self::I128(i) => u128::try_from(*i).ok(),
184 Self::I64(i) => u128::try_from(*i).ok(),
185 Self::U64(i) => Some(u128::from(*i)),
186 _ => None,
187 }
188 }
189
190 #[inline]
191 fn as_f64(&self) -> Option<f64> {
192 match self {
193 #[allow(clippy::useless_conversion)] Self::F64(i) => Some((*i).into()),
195 _ => None,
196 }
197 }
198
199 #[cfg(not(feature = "128bit"))]
200 #[inline]
201 #[allow(clippy::cast_precision_loss)]
202 fn cast_f64(&self) -> Option<f64> {
203 match self {
204 #[allow(clippy::useless_conversion)] Self::F64(i) => Some((*i).into()),
206 Self::I64(i) => Some(*i as f64),
207 Self::U64(i) => Some(*i as f64),
208 _ => None,
209 }
210 }
211
212 #[cfg(feature = "128bit")]
213 #[inline]
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 Self::I128(i) => Some(*i as f64),
222 Self::U128(i) => Some(*i as f64),
223 _ => None,
224 }
225 }
226
227 #[inline]
228 fn as_str(&self) -> Option<&str> {
229 None
230 }
231}
232
233impl fmt::Display for StaticNode {
234 #[cfg(not(feature = "128bit"))]
235 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
236 match self {
237 Self::Null => write!(f, "null"),
238 Self::Bool(b) => write!(f, "{b}"),
239 Self::I64(n) => write!(f, "{n}"),
240 Self::U64(n) => write!(f, "{n}"),
241 #[cfg(not(feature = "ordered-float"))]
242 Self::F64(n) => write!(f, "{n}"),
243 #[cfg(feature = "ordered-float")]
244 Self::F64(n) => write!(f, "{}", n.0),
245 }
246 }
247 #[cfg(feature = "128bit")]
248 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
249 match self {
250 Self::Null => write!(f, "null"),
251 Self::Bool(b) => write!(f, "{b}"),
252 Self::I64(n) => write!(f, "{n}"),
253 Self::U64(n) => write!(f, "{n}"),
254 #[cfg(not(feature = "ordered-float"))]
255 Self::F64(n) => write!(f, "{n}"),
256 #[cfg(feature = "ordered-float")]
257 Self::F64(n) => write!(f, "{}", n.0),
258 Self::I128(n) => write!(f, "{n}"),
259 Self::U128(n) => write!(f, "{n}"),
260 }
261 }
262}
263
264#[allow(clippy::cast_sign_loss, clippy::default_trait_access)]
265impl PartialEq for StaticNode {
266 #[cfg(not(feature = "128bit"))]
267 #[inline]
268 fn eq(&self, other: &Self) -> bool {
269 match (self, other) {
270 (Self::Null, Self::Null) => true,
271 (Self::Bool(v1), Self::Bool(v2)) => v1.eq(v2),
272 #[cfg(not(feature = "ordered-float"))]
273 (Self::F64(v1), Self::F64(v2)) => approx_eq!(f64, *v1, *v2),
274 #[cfg(feature = "ordered-float")]
275 (Self::F64(v1), Self::F64(v2)) => v1.eq(v2),
276 (Self::U64(v1), Self::U64(v2)) => v1.eq(v2),
277 (Self::I64(v1), Self::I64(v2)) => v1.eq(v2),
278 (Self::U64(v1), Self::I64(v2)) if *v2 >= 0 => (*v2 as u64).eq(v1),
279 (Self::I64(v1), Self::U64(v2)) if *v1 >= 0 => (*v1 as u64).eq(v2),
280 _ => false,
281 }
282 }
283
284 #[cfg(feature = "128bit")]
285 #[inline]
286 #[must_use]
287 fn eq(&self, other: &Self) -> bool {
288 match (self, other) {
289 (Self::Null, Self::Null) => true,
290 (Self::Bool(v1), Self::Bool(v2)) => v1.eq(v2),
291 #[cfg(not(feature = "ordered-float"))]
292 (Self::F64(v1), Self::F64(v2)) => approx_eq!(f64, *v1, *v2),
293 #[cfg(feature = "ordered-float")]
294 (Self::F64(v1), Self::F64(v2)) => v1.eq(v2),
295 (Self::U64(v1), Self::U64(v2)) => v1.eq(v2),
296 (Self::U128(v1), Self::U128(v2)) => v1.eq(v2),
297 (Self::I64(v1), Self::I64(v2)) => v1.eq(v2),
298 (Self::I128(v1), Self::I128(v2)) => v1.eq(v2),
299
300 (Self::U64(v1), Self::I64(v2)) if *v2 >= 0 => (*v2 as u64).eq(v1),
301 (Self::U64(v1), Self::I128(v2)) if *v2 >= 0 => (*v2 as u128).eq(&u128::from(*v1)),
302 (Self::U64(v1), Self::U128(v2)) => v2.eq(&u128::from(*v1)),
303
304 (Self::I64(v1), Self::U64(v2)) if *v1 >= 0 => (*v1 as u64).eq(v2),
305 (Self::I64(v1), Self::I128(v2)) => (*v2).eq(&i128::from(*v1)),
306 (Self::I64(v1), Self::U128(v2)) if *v1 >= 0 => v2.eq(&(*v1 as u128)),
307
308 (Self::U128(v1), Self::I128(v2)) if *v2 >= 0 => (*v2 as u128).eq(v1),
309 (Self::U128(v1), Self::U64(v2)) => v1.eq(&u128::from(*v2)),
310 (Self::U128(v1), Self::I64(v2)) if *v2 >= 0 => v1.eq(&(*v2 as u128)),
311
312 (Self::I128(v1), Self::U128(v2)) if *v1 >= 0 => (*v1 as u128).eq(v2),
313 (Self::I128(v1), Self::U64(v2)) => v1.eq(&i128::from(*v2)),
314 (Self::I128(v1), Self::I64(v2)) => v1.eq(&i128::from(*v2)),
315 _ => false,
316 }
317 }
318}
319
320impl Default for StaticNode {
321 fn default() -> Self {
322 Self::Null
323 }
324}