netidx_value/
op.rs

1use crate::{Typ, ValArray, Value};
2use arcstr::literal;
3use compact_str::format_compact;
4use rust_decimal::Decimal;
5use std::{
6    cmp::{Ordering, PartialEq, PartialOrd},
7    hash::Hash,
8    iter,
9    num::Wrapping,
10    ops::{Add, Div, Mul, Not, Rem, Sub},
11    panic::{catch_unwind, AssertUnwindSafe},
12};
13
14impl Hash for Value {
15    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
16        use std::num::FpCategory::*;
17        match self {
18            Value::U32(v) => {
19                0u8.hash(state);
20                v.hash(state)
21            }
22            Value::V32(v) => {
23                1u8.hash(state);
24                v.hash(state)
25            }
26            Value::I32(v) => {
27                2u8.hash(state);
28                v.hash(state)
29            }
30            Value::Z32(v) => {
31                3u8.hash(state);
32                v.hash(state)
33            }
34            Value::U64(v) => {
35                4u8.hash(state);
36                v.hash(state)
37            }
38            Value::V64(v) => {
39                5u8.hash(state);
40                v.hash(state)
41            }
42            Value::I64(v) => {
43                6u8.hash(state);
44                v.hash(state)
45            }
46            Value::Z64(v) => {
47                7u8.hash(state);
48                v.hash(state)
49            }
50            Value::F32(v) => {
51                8u8.hash(state);
52                let bits = v.to_bits();
53                match v.classify() {
54                    Nan => ((bits & 0xFF00_0000) | 0x1).hash(state), // normalize NaN
55                    _ => bits.hash(state),
56                }
57            }
58            Value::F64(v) => {
59                9u8.hash(state);
60                let bits = v.to_bits();
61                match v.classify() {
62                    Nan => ((bits & 0xFFE0_0000_0000_0000) | 0x1).hash(state), // normalize NaN
63                    _ => bits.hash(state),
64                }
65            }
66            Value::DateTime(d) => {
67                10u8.hash(state);
68                d.hash(state)
69            }
70            Value::Duration(d) => {
71                11u8.hash(state);
72                d.hash(state)
73            }
74            Value::String(c) => {
75                12u8.hash(state);
76                c.hash(state)
77            }
78            Value::Bytes(b) => {
79                13u8.hash(state);
80                b.hash(state)
81            }
82            Value::Bool(true) => 14u8.hash(state),
83            Value::Bool(false) => 15u8.hash(state),
84            Value::Null => 16u8.hash(state),
85            Value::Error(c) => {
86                18u8.hash(state);
87                c.hash(state)
88            }
89            Value::Array(a) => {
90                19u8.hash(state);
91                for v in a.iter() {
92                    v.hash(state)
93                }
94            }
95            Value::Decimal(d) => {
96                20u8.hash(state);
97                d.hash(state);
98            }
99        }
100    }
101}
102
103impl PartialEq for Value {
104    fn eq(&self, rhs: &Value) -> bool {
105        use std::num::FpCategory::*;
106        match (self, rhs) {
107            (Value::U32(l) | Value::V32(l), Value::U32(r) | Value::V32(r)) => l == r,
108            (Value::I32(l) | Value::Z32(l), Value::I32(r) | Value::Z32(r)) => l == r,
109            (Value::U64(l) | Value::V64(l), Value::U64(r) | Value::V64(r)) => l == r,
110            (Value::I64(l) | Value::Z64(l), Value::I64(r) | Value::Z64(r)) => l == r,
111            (Value::F32(l), Value::F32(r)) => match (l.classify(), r.classify()) {
112                (Nan, Nan) => true,
113                (Zero, Zero) => true,
114                (_, _) => l == r,
115            },
116            (Value::F64(l), Value::F64(r)) => match (l.classify(), r.classify()) {
117                (Nan, Nan) => true,
118                (Zero, Zero) => true,
119                (_, _) => l == r,
120            },
121            (Value::Decimal(l), Value::Decimal(r)) => l == r,
122            (Value::DateTime(l), Value::DateTime(r)) => l == r,
123            (Value::Duration(l), Value::Duration(r)) => l == r,
124            (Value::String(l), Value::String(r)) => l == r,
125            (Value::Bytes(l), Value::Bytes(r)) => l == r,
126            (Value::Bool(l), Value::Bool(r)) => l == r,
127            (Value::Null, Value::Null) => true,
128            (Value::Error(l), Value::Error(r)) => l == r,
129            (Value::Array(l), Value::Array(r)) => l == r,
130            (Value::Array(_), _) | (_, Value::Array(_)) => false,
131            (l, r) if l.number() || r.number() => {
132                match (l.clone().cast_to::<f64>(), r.clone().cast_to::<f64>()) {
133                    (Ok(l), Ok(r)) => match (l.classify(), r.classify()) {
134                        (Nan, Nan) => true,
135                        (Zero, Zero) => true,
136                        (_, _) => l == r,
137                    },
138                    (_, _) => false,
139                }
140            }
141            (_, _) => false,
142        }
143    }
144}
145
146impl Eq for Value {}
147
148impl PartialOrd for Value {
149    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
150        use std::num::FpCategory::*;
151        match (self, other) {
152            (Value::U32(l) | Value::V32(l), Value::U32(r) | Value::V32(r)) => {
153                l.partial_cmp(r)
154            }
155            (Value::I32(l) | Value::Z32(l), Value::I32(r) | Value::Z32(r)) => {
156                l.partial_cmp(r)
157            }
158            (Value::U64(l) | Value::V64(l), Value::U64(r) | Value::V64(r)) => {
159                l.partial_cmp(r)
160            }
161            (Value::I64(l) | Value::Z64(l), Value::I64(r) | Value::Z64(r)) => {
162                l.partial_cmp(r)
163            }
164            (Value::F32(l), Value::F32(r)) => match (l.classify(), r.classify()) {
165                (Nan, Nan) => Some(Ordering::Equal),
166                (Nan, _) => Some(Ordering::Less),
167                (_, Nan) => Some(Ordering::Greater),
168                (_, _) => l.partial_cmp(r),
169            },
170            (Value::F64(l), Value::F64(r)) => match (l.classify(), r.classify()) {
171                (Nan, Nan) => Some(Ordering::Equal),
172                (Nan, _) => Some(Ordering::Less),
173                (_, Nan) => Some(Ordering::Greater),
174                (_, _) => l.partial_cmp(r),
175            },
176            (Value::Decimal(l), Value::Decimal(r)) => l.partial_cmp(r),
177            (Value::DateTime(l), Value::DateTime(r)) => l.partial_cmp(r),
178            (Value::Duration(l), Value::Duration(r)) => l.partial_cmp(r),
179            (Value::String(l), Value::String(r)) => l.partial_cmp(r),
180            (Value::Bytes(l), Value::Bytes(r)) => l.partial_cmp(r),
181            (Value::Bool(l), Value::Bool(r)) => l.partial_cmp(r),
182            (Value::Null, Value::Null) => Some(Ordering::Equal),
183            (Value::Null, _) => Some(Ordering::Less),
184            (_, Value::Null) => Some(Ordering::Greater),
185            (Value::Error(l), Value::Error(r)) => l.partial_cmp(r),
186            (Value::Error(_), _) => Some(Ordering::Less),
187            (_, Value::Error(_)) => Some(Ordering::Greater),
188            (Value::Array(l), Value::Array(r)) => l.partial_cmp(r),
189            (Value::Array(_), _) => Some(Ordering::Less),
190            (_, Value::Array(_)) => Some(Ordering::Greater),
191            (l, r) if l.number() || r.number() => {
192                match (l.clone().cast_to::<f64>(), r.clone().cast_to::<f64>()) {
193                    (Ok(l), Ok(r)) => match (l.classify(), r.classify()) {
194                        (Nan, Nan) => Some(Ordering::Equal),
195                        (Nan, _) => Some(Ordering::Less),
196                        (_, Nan) => Some(Ordering::Greater),
197                        (_, _) => l.partial_cmp(&r),
198                    },
199                    (_, _) => {
200                        format_compact!("{}", l).partial_cmp(&format_compact!("{}", r))
201                    }
202                }
203            }
204            (l, r) => format_compact!("{}", l).partial_cmp(&format_compact!("{}", r)),
205        }
206    }
207}
208
209impl Ord for Value {
210    fn cmp(&self, other: &Self) -> Ordering {
211        self.partial_cmp(other).unwrap()
212    }
213}
214
215macro_rules! apply_op {
216    ($self:expr, $rhs:expr, $id:expr, $op:tt, $($pat:pat => $blk:block),+) => {
217        match ($self, $rhs) {
218            (Value::U32(l) | Value::V32(l), Value::U32(r) | Value::V32(r)) => {
219                Value::U32((Wrapping(l) $op Wrapping(r)).0)
220            }
221            (Value::I32(l) | Value::Z32(l), Value::I32(r) | Value::Z32(r)) => {
222                Value::I32((Wrapping(l) $op Wrapping(r)).0)
223            }
224            (Value::U64(l) | Value::V64(l), Value::U64(r) | Value::V64(r)) => {
225                Value::U64((Wrapping(l) $op Wrapping(r)).0)
226            }
227            (Value::I64(l) | Value::Z64(l), Value::I64(r) | Value::Z64(r)) => {
228                Value::I64((Wrapping(l) $op Wrapping(r)).0)
229            }
230            (Value::F32(l), Value::F32(r)) => Value::F32(l $op r),
231            (Value::F64(l), Value::F64(r)) => Value::F64(l $op r),
232            (Value::Decimal(l), Value::Decimal(r)) => Value::Decimal(l $op r),
233            (Value::U32(l) | Value::V32(l), Value::U64(r) | Value::V64(r)) => {
234                Value::U64((Wrapping(l as u64) $op Wrapping(r)).0)
235            }
236            (Value::U64(l) | Value::V64(l), Value::U32(r) | Value::V32(r)) => {
237                Value::U64((Wrapping(l) $op Wrapping(r as u64)).0)
238            }
239            (Value::I32(l) | Value::Z32(l), Value::I64(r) | Value::Z64(r)) => {
240                Value::I64((Wrapping(l as i64) $op Wrapping(r)).0)
241            }
242            (Value::I32(l) | Value::Z32(l), Value::U32(r) | Value::V32(r)) => {
243                Value::I64((Wrapping(l as i64) $op Wrapping(r as i64)).0)
244            }
245            (Value::U32(l) | Value::V32(l), Value::I32(r) | Value::Z32(r)) => {
246                Value::I64((Wrapping(l as i64) $op Wrapping(r as i64)).0)
247            }
248            (Value::I64(l) | Value::Z64(l), Value::I32(r) | Value::Z32(r)) => {
249                Value::I64((Wrapping(l) $op Wrapping(r as i64)).0)
250            }
251            (Value::I64(l) | Value::Z64(l), Value::U32(r) | Value::V32(r)) => {
252                Value::I64((Wrapping(l) $op Wrapping(r as i64)).0)
253            }
254            (Value::U32(l) | Value::V32(l), Value::I64(r) | Value::Z64(r)) => {
255                Value::I64((Wrapping(l as i64) $op Wrapping(r)).0)
256            }
257            (Value::I64(l) | Value::Z64(l), Value::U64(r) | Value::V64(r)) => {
258                Value::I64((Wrapping(l) $op Wrapping(r as i64)).0)
259            }
260            (Value::U64(l) | Value::V64(l), Value::I64(r) | Value::Z64(r)) => {
261                Value::I64((Wrapping(l as i64) $op Wrapping(r)).0)
262            }
263            (Value::U64(l) | Value::V64(l), Value::I32(r) | Value::Z32(r)) => {
264                Value::I64((Wrapping(l as i64) $op Wrapping(r as i64)).0)
265            }
266            (Value::I32(l) | Value::Z32(l), Value::U64(r) | Value::V64(r)) => {
267                Value::I64((Wrapping(l as i64) $op Wrapping(r as i64)).0)
268            }
269            (Value::F32(l), Value::U32(r) | Value::V32(r)) => Value::F32(l $op r as f32),
270            (Value::U32(l) | Value::V32(l), Value::F32(r)) => Value::F32(l as f32 $op r),
271            (Value::F32(l), Value::U64(r) | Value::V64(r)) => Value::F32(l $op r as f32),
272            (Value::U64(l) | Value::V64(l), Value::F32(r)) => Value::F32(l as f32 $op r),
273            (Value::F32(l), Value::I32(r) | Value::Z32(r)) => Value::F32(l $op r  as f32),
274            (Value::I32(l) | Value::Z32(l), Value::F32(r)) => Value::F32(l as f32 $op r),
275            (Value::F32(l), Value::I64(r) | Value::Z64(r)) => Value::F32(l $op r as f32),
276            (Value::I64(l) | Value::Z64(l), Value::F32(r)) => Value::F32(l as f32 $op r),
277            (Value::F32(l), Value::F64(r)) => Value::F64(l as f64 $op r),
278            (Value::F64(l), Value::U32(r) | Value::V32(r)) => Value::F64(l $op r as f64),
279            (Value::U32(l) | Value::V32(l), Value::F64(r)) => Value::F64(l as f64 $op r),
280            (Value::F64(l), Value::U64(r) | Value::V64(r)) => Value::F64(l $op r as f64),
281            (Value::U64(l) | Value::V64(l), Value::F64(r)) => Value::F64(l as f64 $op r),
282            (Value::F64(l), Value::I32(r) | Value::Z32(r)) => Value::F64(l $op r as f64),
283            (Value::I32(l) | Value::Z32(l), Value::F64(r)) => Value::F64(l as f64 $op r),
284            (Value::F64(l), Value::I64(r) | Value::Z64(r)) => Value::F64(l $op r as f64),
285            (Value::I64(l) | Value::Z64(l), Value::F64(r)) => Value::F64(l as f64 $op r),
286            (Value::F64(l), Value::F32(r)) => Value::F64(l $op r as f64),
287            (Value::Decimal(l), Value::U32(r) | Value::V32(r)) =>
288                Value::Decimal(l $op Decimal::from(r)),
289            (Value::U32(l) | Value::V32(l), Value::Decimal(r)) =>
290                Value::Decimal(Decimal::from(l) $op r),
291            (Value::Decimal(l), Value::U64(r) | Value::V64(r)) =>
292                Value::Decimal(l $op Decimal::from(r)),
293            (Value::U64(l) | Value::V64(l), Value::Decimal(r)) =>
294                Value::Decimal(Decimal::from(l) $op r),
295            (Value::Decimal(l), Value::I32(r) | Value::Z32(r)) =>
296                Value::Decimal(l $op Decimal::from(r)),
297            (Value::I32(l) | Value::Z32(l), Value::Decimal(r)) =>
298                Value::Decimal(Decimal::from(l) $op r),
299            (Value::Decimal(l), Value::I64(r) | Value::Z64(r)) =>
300                Value::Decimal(l $op Decimal::from(r)),
301            (Value::I64(l) | Value::Z64(l), Value::Decimal(r)) =>
302                Value::Decimal(Decimal::from(l) $op r),
303            (Value::Decimal(l), Value::F32(r)) => match Decimal::try_from(r) {
304                Ok(r) => Value::Decimal(l $op r),
305                Err(_) => {
306                    let e = format_compact!("can't parse {} as a decimal", r);
307                    Value::Error(e.as_str().into())
308                },
309            },
310            (Value::F32(l), Value::Decimal(r)) => match Decimal::try_from(l) {
311                Ok(l) => Value::Decimal(l $op r),
312                Err(_) => {
313                    let e = format_compact!("can't parse {} as a decimal", l);
314                    Value::Error(e.as_str().into())
315                },
316            },
317            (Value::Decimal(l), Value::F64(r)) => match Decimal::try_from(r) {
318                Ok(r) => Value::Decimal(l $op r),
319                Err(_) => {
320                    let e = format_compact!("can't parse {} as a decimal", r);
321                    Value::Error(e.as_str().into())
322                },
323            },
324            (Value::F64(l), Value::Decimal(r)) => match Decimal::try_from(l) {
325                Ok(l) => Value::Decimal(l $op r),
326                Err(_) => {
327                    let e = format_compact!("can't parse {} as a decimal", l);
328                    Value::Error(e.as_str().into())
329                },
330            },
331            (Value::String(s), n) => match s.parse::<Value>() {
332                Err(e) => Value::Error(format_compact!("{}", e).as_str().into()),
333                Ok(s) => s $op n,
334            }
335            (n, Value::String(s)) => match s.parse::<Value>() {
336                Err(e) => Value::Error(format_compact!("{}", e).as_str().into()),
337                Ok(s) => n $op s,
338            },
339            (Value::Array(e0), Value::Array(e1)) => {
340                let (e0, e1) = if e0.len() < e1.len() { (e0, e1) } else { (e1, e0) };
341                let iter = e0
342                    .iter()
343                    .cloned()
344                    .chain(iter::repeat(Value::F64($id)))
345                    .zip(e1.iter().cloned());
346                Value::Array(iter.map(|(v0, v1)| v0 $op v1).collect())
347            }
348            (l @ Value::Array(_), n) => {
349                match n.cast(Typ::Array) {
350                    None => Value::Error(literal!("can't add to array")),
351                    Some(r) => l $op r,
352                }
353            }
354            (n, r @ Value::Array(_)) => {
355                match n.cast(Typ::Array) {
356                    None => Value::Error(literal!("can't add to array")),
357                    Some(l) => l $op r,
358                }
359            }
360            (Value::Bytes(_), _) | (_, Value::Bytes(_)) => {
361                Value::Error(literal!("can't add bytes"))
362            }
363            (Value::Null, _) | (_, Value::Null) => {
364                Value::Error(literal!("can't add null"))
365            }
366            | (Value::Error(_), _)
367            | (_, Value::Error(_)) => Value::Error(literal!("can't add error types")),
368            (Value::Bool(true), n) => Value::U32(1) $op n,
369            (n, Value::Bool(true)) => n $op Value::U32(1),
370            (Value::Bool(false), n) => Value::U32(0) $op n,
371            (n, Value::Bool(false)) => n $op Value::U32(0),
372            $($pat => $blk),+
373        }
374    }
375}
376
377macro_rules! handle_arith_result {
378    ($res:ident, $fallback:literal) => {
379        match $res {
380            Ok(r) => r,
381            Err(e) => match e.downcast_ref::<String>() {
382                Some(s) => Value::Error(s.into()),
383                None => match e.downcast_ref::<&str>() {
384                    Some(s) => Value::Error((*s).into()),
385                    None => Value::Error(literal!($fallback)),
386                },
387            },
388        }
389    };
390}
391
392impl Add for Value {
393    type Output = Value;
394
395    fn add(self, rhs: Self) -> Self {
396        let res = catch_unwind(AssertUnwindSafe(|| {
397            apply_op!(
398                self, rhs, 0., +,
399                (Value::DateTime(dt), Value::Duration(d))
400                    | (Value::Duration(d), Value::DateTime(dt)) => {
401                        match chrono::Duration::from_std(d) {
402                            Ok(d) => Value::DateTime(dt + d),
403                            Err(e) => Value::Error(format_compact!("{}", e).as_str().into()),
404                        }
405                    },
406                (Value::Duration(d0), Value::Duration(d1)) => { Value::Duration(d0 + d1) },
407                (Value::Duration(_), _)
408                    | (_, Value::Duration(_))
409                    | (_, Value::DateTime(_))
410                    | (Value::DateTime(_), _) => {
411                        Value::Error(literal!("can't add to datetime/duration"))
412                    }
413            )
414        }));
415        handle_arith_result!(res, "panic while executing add")
416    }
417}
418
419impl Sub for Value {
420    type Output = Value;
421
422    fn sub(self, rhs: Self) -> Self {
423        let res = catch_unwind(AssertUnwindSafe(|| {
424            apply_op!(
425                self, rhs, 0., -,
426                (Value::DateTime(dt), Value::Duration(d))
427                    | (Value::Duration(d), Value::DateTime(dt)) => {
428                        match chrono::Duration::from_std(d) {
429                            Ok(d) => Value::DateTime(dt - d),
430                            Err(e) => Value::Error(format_compact!("{}", e).as_str().into()),
431                        }
432                    },
433                (Value::Duration(d0), Value::Duration(d1)) => { Value::Duration(d0 - d1) },
434                (Value::Duration(_), _)
435                    | (_, Value::Duration(_))
436                    | (_, Value::DateTime(_))
437                    | (Value::DateTime(_), _) => {
438                        Value::Error(literal!("can't sub datetime/duration"))
439                    }
440            )
441        }));
442        handle_arith_result!(res, "panic while executing sub")
443    }
444}
445
446impl Mul for Value {
447    type Output = Value;
448
449    fn mul(self, rhs: Self) -> Self {
450        let res = catch_unwind(AssertUnwindSafe(|| {
451            apply_op!(
452                self, rhs, 1., *,
453                (Value::Duration(d), Value::U32(n) | Value::V32(n))
454                | (Value::U32(n) | Value::V32(n), Value::Duration(d)) => { Value::Duration(d * n) },
455                (Value::Duration(d), Value::I32(n) | Value::Z32(n))
456                | (Value::I32(n) | Value::Z32(n), Value::Duration(d)) => {
457                    if n < 0 { panic!("can't multiply a duration by a negative number") }
458                    Value::Duration(d * n as u32)
459                },
460                (Value::Duration(d), Value::U64(n) | Value::V64(n))
461                | (Value::U64(n) | Value::V64(n), Value::Duration(d)) => {
462                    Value::Duration(d * n as u32)
463                },
464                (Value::Duration(d), Value::I64(n) | Value::Z64(n))
465                | (Value::I64(n) | Value::Z64(n), Value::Duration(d)) => {
466                    if n < 0 { panic!("can't multiply a duration by a negative number") }
467                    Value::Duration(d * n as u32)
468                },
469                (Value::Duration(d), Value::F32(s)) | (Value::F32(s), Value::Duration(d)) => { Value::Duration(d.mul_f32(s)) },
470                (Value::Duration(d), Value::F64(s)) | (Value::F64(s), Value::Duration(d)) => { Value::Duration(d.mul_f64(s)) },
471                    | (Value::Duration(_), _)
472                    | (_, Value::Duration(_))
473                    | (_, Value::DateTime(_))
474                    | (Value::DateTime(_), _) => {
475                        Value::Error(literal!("can't mul datetime/duration"))
476                    }
477            )
478        }));
479        handle_arith_result!(res, "panic while executing mul")
480    }
481}
482
483impl Div for Value {
484    type Output = Value;
485
486    fn div(self, rhs: Self) -> Self {
487        let res = catch_unwind(AssertUnwindSafe(|| {
488            apply_op!(
489                self, rhs, 1., /,
490                (Value::Duration(d), Value::U32(s) | Value::V32(s)) => { Value::Duration(d / s) },
491                (Value::Duration(d), Value::I32(s) | Value::Z32(s)) => {
492                    if s < 0 { panic!("can't divide duration by a negative number") }
493                    Value::Duration(d / s as u32)
494                },
495                (Value::Duration(d), Value::U64(s) | Value::V64(s)) => {
496                    Value::Duration(d / s as u32)
497                },
498                (Value::Duration(d), Value::I64(s) | Value::Z64(s)) => {
499                    if s < 0 { panic!("can't divide duration by a negative number") }
500                    Value::Duration(d / s as u32)
501                },
502                (Value::Duration(d), Value::F32(s)) => { Value::Duration(d.div_f32(s)) },
503                (Value::Duration(d), Value::F64(s)) => { Value::Duration(d.div_f64(s)) },
504                (Value::Duration(_), _)
505                    | (_, Value::Duration(_))
506                    | (_, Value::DateTime(_))
507                    | (Value::DateTime(_), _) => {
508                        Value::Error(literal!("can't div datetime/duration"))
509                    }
510            )
511        }));
512        handle_arith_result!(res, "panic while executing div")
513    }
514}
515
516impl Rem for Value {
517    type Output = Value;
518
519    fn rem(self, rhs: Self) -> Self::Output {
520        let res = catch_unwind(AssertUnwindSafe(|| {
521            apply_op!(
522                self, rhs, 1., %,
523                (Value::Duration(_), _)
524                    | (_, Value::Duration(_))
525                    | (_, Value::DateTime(_))
526                    | (Value::DateTime(_), _) => {
527                        Value::Error(literal!("can't mod datetime/duration"))
528                    }
529            )
530        }));
531        handle_arith_result!(res, "panic while executing mod")
532    }
533}
534
535impl Not for Value {
536    type Output = Value;
537
538    fn not(self) -> Self {
539        match self {
540            Value::Bool(v) => Value::Bool(!v),
541            Value::Null => Value::Null,
542            Value::U32(v) => Value::U32(!v),
543            Value::V32(v) => Value::V32(!v),
544            Value::I32(v) => Value::I32(!v),
545            Value::Z32(v) => Value::Z32(!v),
546            Value::U64(v) => Value::U64(!v),
547            Value::V64(v) => Value::V64(!v),
548            Value::I64(v) => Value::I64(!v),
549            Value::Z64(v) => Value::Z64(!v),
550            Value::F32(_) => Value::Error(literal!("can't apply not to F32")),
551            Value::F64(_) => Value::Error(literal!("can't apply not to F64")),
552            Value::Decimal(_) => Value::Error(literal!("can't apply not to Decimal")),
553            Value::DateTime(_) => Value::Error(literal!("can't apply not to DateTime")),
554            Value::Duration(_) => Value::Error(literal!("can't apply not to Duration")),
555            Value::String(_) => Value::Error(literal!("can't apply not to String")),
556            Value::Bytes(_) => Value::Error(literal!("can't apply not to Bytes")),
557            Value::Error(_) => Value::Error(literal!("can't apply not to Error")),
558            Value::Array(elts) => {
559                Value::Array(ValArray::from_iter_exact(elts.iter().cloned().map(|v| !v)))
560            }
561        }
562    }
563}