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