netidx_value/
lib.rs

1use anyhow::Result;
2use arcstr::ArcStr;
3use bytes::{Buf, BufMut};
4use chrono::prelude::*;
5use compact_str::{format_compact, CompactString};
6use netidx_core::{
7    pack::{self, Pack, PackError},
8    utils,
9};
10use rust_decimal::Decimal;
11use serde::{Deserialize, Serialize};
12use smallvec::SmallVec;
13use std::{hint::unreachable_unchecked, iter, ptr, result, str::FromStr, time::Duration};
14
15pub mod array;
16mod convert;
17mod op;
18pub mod parser;
19pub mod pbuf;
20mod print;
21#[cfg(test)]
22mod test;
23mod typ;
24
25pub use array::ValArray;
26pub use convert::FromValue;
27pub use pbuf::PBytes;
28pub use print::{printf, NakedValue};
29pub use typ::Typ;
30
31#[macro_export]
32macro_rules! valarray {
33    ($proto:expr; $size:literal) => {{
34        let proto: Value = $proto.into();
35        Value::Array(std::array::from_fn::<_, $size, _>(|_| proto.clone()))
36    }};
37    ($($e:expr),+) => {
38        Value::Array([$($e.into()),+].into())
39    }
40}
41
42fn _test_valarray() {
43    let v: Value = valarray![1, 2, 5.3, 10];
44    let _: Value = valarray![valarray!["elts", v], valarray!["foo", ["bar"]]];
45}
46
47const COPY_MAX: u32 = 0x0000_4000;
48
49// this type is divided into two subtypes, the copy part and the clone
50// part. If the tag word is <= COPY_MAX then the type is copy,
51// otherwise it must be cloned. Additionally, the tag word values are
52// THE SAME as the values of the cases of Typ. Getting the Typ of a
53// value is therefore a simply copy of the discriminant of Value.
54//
55// It is essential that when adding variants you update COPY_MAX and
56// Typ correctly. If adding a non copy type, you will also need to
57// update the implementation of clone to match and delegate the clone
58// operation
59#[derive(Debug, Serialize, Deserialize)]
60#[serde(tag = "type", content = "value")]
61#[repr(u32)]
62pub enum Value {
63    /// full 4 byte u32
64    U32(u32) = 0x0000_0001,
65    /// LEB128 varint, 1 - 5 bytes depending on value
66    V32(u32) = 0x0000_0002,
67    /// full 4 byte i32
68    I32(i32) = 0x0000_0004,
69    /// LEB128 varint zigzag encoded, 1 - 5 bytes depending on abs(value)
70    Z32(i32) = 0x0000_0008,
71    /// full 8 byte u64
72    U64(u64) = 0x0000_0010,
73    /// LEB128 varint, 1 - 10 bytes depending on value
74    V64(u64) = 0x0000_0020,
75    /// full 8 byte i64
76    I64(i64) = 0x0000_0040,
77    /// LEB128 varint zigzag encoded, 1 - 10 bytes depending on abs(value)
78    Z64(i64) = 0x0000_0080,
79    /// 4 byte ieee754 single precision float
80    F32(f32) = 0x0000_0100,
81    /// 8 byte ieee754 double precision float
82    F64(f64) = 0x0000_0200,
83    /// fixed point decimal type
84    Decimal(Decimal) = 0x0000_0400,
85    /// UTC timestamp
86    DateTime(DateTime<Utc>) = 0x0000_0800,
87    /// Duration
88    Duration(Duration) = 0x0000_1000,
89    /// boolean true
90    Bool(bool) = 0x0000_2000,
91    /// Empty value
92    Null = 0x0000_4000,
93    /// unicode string
94    String(ArcStr) = 0x8000_0000,
95    /// byte array
96    Bytes(PBytes) = 0x4000_0000,
97    /// An explicit error
98    Error(ArcStr) = 0x2000_0000,
99    /// An array of values
100    Array(ValArray) = 0x1000_0000,
101}
102
103// This will fail to compile if any variant that is supposed to be
104// Copy changes to not Copy. It is never intended to be called, and it
105// will panic if it ever is.
106fn _assert_variants_are_copy(v: &Value) -> Value {
107    let i = match v {
108        // copy types
109        Value::U32(i) | Value::V32(i) => Value::U32(*i),
110        Value::I32(i) | Value::Z32(i) => Value::I32(*i),
111        Value::U64(i) | Value::V64(i) => Value::U64(*i),
112        Value::I64(i) | Value::Z64(i) => Value::I64(*i),
113        Value::F32(i) => Value::F32(*i),
114        Value::F64(i) => Value::F64(*i),
115        Value::Decimal(i) => Value::Decimal(*i),
116        Value::DateTime(i) => Value::DateTime(*i),
117        Value::Duration(i) => Value::Duration(*i),
118        Value::Bool(b) => Value::Bool(*b),
119        Value::Null => Value::Null,
120
121        // not copy types
122        Value::String(i) => Value::String(i.clone()),
123        Value::Bytes(i) => Value::Bytes(i.clone()),
124        Value::Error(i) => Value::Error(i.clone()),
125        Value::Array(i) => Value::Array(i.clone()),
126    };
127    panic!("{i}")
128}
129
130impl Clone for Value {
131    fn clone(&self) -> Self {
132        if self.is_copy() {
133            unsafe { ptr::read(self) }
134        } else {
135            match self {
136                Self::String(c) => Self::String(c.clone()),
137                Self::Bytes(b) => Self::Bytes(b.clone()),
138                Self::Error(e) => Self::Error(e.clone()),
139                Self::Array(a) => Self::Array(a.clone()),
140                Value::U32(_)
141                | Value::V32(_)
142                | Value::I32(_)
143                | Value::Z32(_)
144                | Value::U64(_)
145                | Value::V64(_)
146                | Value::I64(_)
147                | Value::Z64(_)
148                | Value::F32(_)
149                | Value::F64(_)
150                | Value::Decimal(_)
151                | Value::DateTime(_)
152                | Value::Duration(_)
153                | Value::Bool(_)
154                | Value::Null => unsafe { unreachable_unchecked() },
155            }
156        }
157    }
158
159    fn clone_from(&mut self, source: &Self) {
160        if self.is_copy() {
161            unsafe { ptr::copy_nonoverlapping(source, self, 1) };
162        } else {
163            match source {
164                Self::String(c) => {
165                    *self = Self::String(c.clone());
166                }
167                Self::Bytes(b) => {
168                    *self = Self::Bytes(b.clone());
169                }
170                Self::Error(e) => {
171                    *self = Self::Error(e.clone());
172                }
173                Self::Array(a) => {
174                    *self = Self::Array(a.clone());
175                }
176                Value::U32(_)
177                | Value::V32(_)
178                | Value::I32(_)
179                | Value::Z32(_)
180                | Value::U64(_)
181                | Value::V64(_)
182                | Value::I64(_)
183                | Value::Z64(_)
184                | Value::F32(_)
185                | Value::F64(_)
186                | Value::Decimal(_)
187                | Value::DateTime(_)
188                | Value::Duration(_)
189                | Value::Bool(_)
190                | Value::Null => unsafe { unreachable_unchecked() },
191            }
192        }
193    }
194}
195
196impl FromStr for Value {
197    type Err = anyhow::Error;
198
199    fn from_str(s: &str) -> result::Result<Self, Self::Err> {
200        parser::parse_value(s)
201    }
202}
203
204impl Pack for Value {
205    fn encoded_len(&self) -> usize {
206        1 + match self {
207            Value::U32(v) => Pack::encoded_len(v),
208            Value::V32(v) => pack::varint_len(*v as u64),
209            Value::I32(v) => Pack::encoded_len(v),
210            Value::Z32(v) => pack::varint_len(pack::i32_zz(*v) as u64),
211            Value::U64(v) => Pack::encoded_len(v),
212            Value::V64(v) => pack::varint_len(*v),
213            Value::I64(v) => Pack::encoded_len(v),
214            Value::Z64(v) => pack::varint_len(pack::i64_zz(*v) as u64),
215            Value::F32(v) => Pack::encoded_len(v),
216            Value::F64(v) => Pack::encoded_len(v),
217            Value::DateTime(d) => Pack::encoded_len(d),
218            Value::Duration(d) => Pack::encoded_len(d),
219            Value::String(c) => Pack::encoded_len(c),
220            Value::Bytes(b) => Pack::encoded_len(b),
221            Value::Bool(_) | Value::Null => 0,
222            Value::Error(c) => Pack::encoded_len(c),
223            Value::Array(elts) => Pack::encoded_len(elts),
224            Value::Decimal(d) => Pack::encoded_len(d),
225        }
226    }
227
228    // the high two bits of the tag are reserved for wrapper types,
229    // max tag is therefore 0x3F
230    fn encode(&self, buf: &mut impl BufMut) -> result::Result<(), PackError> {
231        match self {
232            Value::U32(i) => {
233                buf.put_u8(0);
234                Pack::encode(i, buf)
235            }
236            Value::V32(i) => {
237                buf.put_u8(1);
238                Ok(pack::encode_varint(*i as u64, buf))
239            }
240            Value::I32(i) => {
241                buf.put_u8(2);
242                Pack::encode(i, buf)
243            }
244            Value::Z32(i) => {
245                buf.put_u8(3);
246                Ok(pack::encode_varint(pack::i32_zz(*i) as u64, buf))
247            }
248            Value::U64(i) => {
249                buf.put_u8(4);
250                Pack::encode(i, buf)
251            }
252            Value::V64(i) => {
253                buf.put_u8(5);
254                Ok(pack::encode_varint(*i, buf))
255            }
256            Value::I64(i) => {
257                buf.put_u8(6);
258                Pack::encode(i, buf)
259            }
260            Value::Z64(i) => {
261                buf.put_u8(7);
262                Ok(pack::encode_varint(pack::i64_zz(*i), buf))
263            }
264            Value::F32(i) => {
265                buf.put_u8(8);
266                Pack::encode(i, buf)
267            }
268            Value::F64(i) => {
269                buf.put_u8(9);
270                Pack::encode(i, buf)
271            }
272            Value::DateTime(dt) => {
273                buf.put_u8(10);
274                Pack::encode(dt, buf)
275            }
276            Value::Duration(d) => {
277                buf.put_u8(11);
278                Pack::encode(d, buf)
279            }
280            Value::String(s) => {
281                buf.put_u8(12);
282                Pack::encode(s, buf)
283            }
284            Value::Bytes(b) => {
285                buf.put_u8(13);
286                Pack::encode(b, buf)
287            }
288            Value::Bool(true) => Ok(buf.put_u8(14)),
289            Value::Bool(false) => Ok(buf.put_u8(15)),
290            Value::Null => Ok(buf.put_u8(16)),
291            //          OK is deprecated, but we reserve 17 for backwards compatibility
292            //          Value::Ok => Ok(buf.put_u8(17))
293            Value::Error(e) => {
294                buf.put_u8(18);
295                Pack::encode(e, buf)
296            }
297            Value::Array(elts) => {
298                buf.put_u8(19);
299                Pack::encode(elts, buf)
300            }
301            Value::Decimal(d) => {
302                buf.put_u8(20);
303                Pack::encode(d, buf)
304            }
305        }
306    }
307
308    fn decode(buf: &mut impl Buf) -> result::Result<Self, PackError> {
309        match <u8 as Pack>::decode(buf)? {
310            0 => Ok(Value::U32(Pack::decode(buf)?)),
311            1 => Ok(Value::V32(pack::decode_varint(buf)? as u32)),
312            2 => Ok(Value::I32(Pack::decode(buf)?)),
313            3 => Ok(Value::Z32(pack::i32_uzz(pack::decode_varint(buf)? as u32))),
314            4 => Ok(Value::U64(Pack::decode(buf)?)),
315            5 => Ok(Value::V64(pack::decode_varint(buf)?)),
316            6 => Ok(Value::I64(Pack::decode(buf)?)),
317            7 => Ok(Value::Z64(pack::i64_uzz(pack::decode_varint(buf)?))),
318            8 => Ok(Value::F32(Pack::decode(buf)?)),
319            9 => Ok(Value::F64(Pack::decode(buf)?)),
320            10 => Ok(Value::DateTime(Pack::decode(buf)?)),
321            11 => Ok(Value::Duration(Pack::decode(buf)?)),
322            12 => Ok(Value::String(Pack::decode(buf)?)),
323            13 => Ok(Value::Bytes(Pack::decode(buf)?)),
324            14 => Ok(Value::Bool(true)),
325            15 => Ok(Value::Bool(false)),
326            16 => Ok(Value::Null),
327            17 => Ok(Value::Null), // 17 used to be Ok
328            18 => Ok(Value::Error(Pack::decode(buf)?)),
329            19 => Ok(Value::Array(Pack::decode(buf)?)),
330            20 => Ok(Value::Decimal(Pack::decode(buf)?)),
331            _ => Err(PackError::UnknownTag),
332        }
333    }
334}
335
336impl Value {
337    pub fn approx_eq(&self, v: &Self) -> bool {
338        use std::num::FpCategory::*;
339        match (self, v) {
340            (Value::U32(l) | Value::V32(l), Value::U32(r) | Value::V32(r)) => l == r,
341            (Value::I32(l) | Value::Z32(l), Value::I32(r) | Value::Z32(r)) => l == r,
342            (Value::U64(l) | Value::V64(l), Value::U64(r) | Value::V64(r)) => l == r,
343            (Value::I64(l) | Value::Z64(l), Value::I64(r) | Value::Z64(r)) => l == r,
344            (Value::F32(l), Value::F32(r)) => match (l.classify(), r.classify()) {
345                (Nan, Nan) => true,
346                (Zero, Zero) => true,
347                (_, _) => (l - r).abs() <= f32::EPSILON,
348            },
349            (Value::F64(l), Value::F64(r)) => match (l.classify(), r.classify()) {
350                (Nan, Nan) => true,
351                (Zero, Zero) => true,
352                (_, _) => (l - r).abs() <= f64::EPSILON,
353            },
354            (Value::Decimal(l), Value::Decimal(r)) => l == r,
355            (Value::DateTime(l), Value::DateTime(r)) => l == r,
356            (Value::Duration(l), Value::Duration(r)) => {
357                (l.as_secs_f64() - r.as_secs_f64()).abs() <= f64::EPSILON
358            }
359            (Value::String(l), Value::String(r)) => l == r,
360            (Value::Bytes(l), Value::Bytes(r)) => l == r,
361            (Value::Bool(l), Value::Bool(r)) => l == r,
362            (Value::Null, Value::Null) => true,
363            (Value::Error(l), Value::Error(r)) => l == r,
364            (Value::Array(l), Value::Array(r)) => {
365                l.len() == r.len()
366                    && l.iter().zip(r.iter()).all(|(v0, v1)| v0.approx_eq(v1))
367            }
368            (Value::Array(_), _) | (_, Value::Array(_)) => false,
369            (l, r) if l.number() || r.number() => {
370                match (l.clone().cast_to::<f64>(), r.clone().cast_to::<f64>()) {
371                    (Ok(l), Ok(r)) => match (l.classify(), r.classify()) {
372                        (Nan, Nan) => true,
373                        (Zero, Zero) => true,
374                        (_, _) => (l - r).abs() <= f64::EPSILON,
375                    },
376                    (_, _) => false,
377                }
378            }
379            (_, _) => false,
380        }
381    }
382
383    pub fn discriminant(&self) -> u32 {
384        unsafe { *<*const _>::from(self).cast::<u32>() }
385    }
386
387    pub fn is_copy(&self) -> bool {
388        self.discriminant() <= COPY_MAX
389    }
390
391    /// Whatever value is attempt to turn it into the type specified
392    pub fn cast(self, typ: Typ) -> Option<Value> {
393        macro_rules! cast_number {
394            ($v:expr, $typ:expr) => {
395                match typ {
396                    Typ::U32 => Some(Value::U32($v as u32)),
397                    Typ::V32 => Some(Value::V32($v as u32)),
398                    Typ::I32 => Some(Value::I32($v as i32)),
399                    Typ::Z32 => Some(Value::Z32($v as i32)),
400                    Typ::U64 => Some(Value::U64($v as u64)),
401                    Typ::V64 => Some(Value::V64($v as u64)),
402                    Typ::I64 => Some(Value::I64($v as i64)),
403                    Typ::Z64 => Some(Value::Z64($v as i64)),
404                    Typ::F32 => Some(Value::F32($v as f32)),
405                    Typ::F64 => Some(Value::F64($v as f64)),
406                    Typ::Decimal => match Decimal::try_from($v) {
407                        Ok(d) => Some(Value::Decimal(d)),
408                        Err(_) => None,
409                    },
410                    Typ::DateTime => {
411                        Some(Value::DateTime(DateTime::from_timestamp($v as i64, 0)?))
412                    }
413                    Typ::Duration => {
414                        Some(Value::Duration(Duration::from_secs($v as u64)))
415                    }
416                    Typ::Bool => Some(if $v as i64 > 0 {
417                        Value::Bool(true)
418                    } else {
419                        Value::Bool(false)
420                    }),
421                    Typ::String => {
422                        Some(Value::String(format_compact!("{}", self).as_str().into()))
423                    }
424                    Typ::Bytes => None,
425                    Typ::Error => None,
426                    Typ::Array => Some(Value::Array([self.clone()].into())),
427                    Typ::Null => Some(Value::Null),
428                }
429            };
430        }
431        match self {
432            Value::String(s) => match typ {
433                Typ::String => Some(Value::String(s)),
434                Typ::Error => Some(Value::Error(s)),
435                Typ::Array => Some(Value::Array([Value::String(s)].into())),
436                _ => s.parse::<Value>().ok().and_then(|v| v.cast(typ)),
437            },
438            v if typ == Typ::String => {
439                Some(Value::String(format_compact!("{}", v).as_str().into()))
440            }
441            Value::Array(elts) if typ != Typ::Array => {
442                elts.first().and_then(|v| v.clone().cast(typ))
443            }
444            v @ Value::Array(_) => Some(v),
445            Value::U32(v) | Value::V32(v) => cast_number!(v, typ),
446            Value::I32(v) | Value::Z32(v) => cast_number!(v, typ),
447            Value::U64(v) | Value::V64(v) => cast_number!(v, typ),
448            Value::I64(v) | Value::Z64(v) => cast_number!(v, typ),
449            Value::F32(v) => cast_number!(v, typ),
450            Value::F64(v) => cast_number!(v, typ),
451            Value::Decimal(v) => match typ {
452                Typ::Decimal => Some(Value::Decimal(v)),
453                Typ::U32 => v.try_into().ok().map(Value::U32),
454                Typ::V32 => v.try_into().ok().map(Value::V32),
455                Typ::I32 => v.try_into().ok().map(Value::I32),
456                Typ::Z32 => v.try_into().ok().map(Value::Z32),
457                Typ::U64 => v.try_into().ok().map(Value::U64),
458                Typ::V64 => v.try_into().ok().map(Value::V64),
459                Typ::I64 => v.try_into().ok().map(Value::I64),
460                Typ::Z64 => v.try_into().ok().map(Value::Z64),
461                Typ::F32 => v.try_into().ok().map(Value::F32),
462                Typ::F64 => v.try_into().ok().map(Value::F64),
463                Typ::String => {
464                    Some(Value::String(format_compact!("{}", v).as_str().into()))
465                }
466                Typ::Bool
467                | Typ::Array
468                | Typ::Bytes
469                | Typ::DateTime
470                | Typ::Duration
471                | Typ::Null
472                | Typ::Error => None,
473            },
474            Value::DateTime(v) => match typ {
475                Typ::U32 | Typ::V32 => {
476                    let ts = v.timestamp();
477                    if ts < 0 && ts > u32::MAX as i64 {
478                        None
479                    } else {
480                        if typ == Typ::U32 {
481                            Some(Value::U32(ts as u32))
482                        } else {
483                            Some(Value::V32(ts as u32))
484                        }
485                    }
486                }
487                Typ::I32 | Typ::Z32 => {
488                    let ts = v.timestamp();
489                    if ts < i32::MIN as i64 || ts > i32::MAX as i64 {
490                        None
491                    } else {
492                        if typ == Typ::I32 {
493                            Some(Value::I32(ts as i32))
494                        } else {
495                            Some(Value::Z32(ts as i32))
496                        }
497                    }
498                }
499                Typ::U64 | Typ::V64 => {
500                    let ts = v.timestamp();
501                    if ts < 0 {
502                        None
503                    } else {
504                        if typ == Typ::U64 {
505                            Some(Value::U64(ts as u64))
506                        } else {
507                            Some(Value::V64(ts as u64))
508                        }
509                    }
510                }
511                Typ::I64 => Some(Value::I64(v.timestamp())),
512                Typ::Z64 => Some(Value::Z64(v.timestamp())),
513                Typ::F32 | Typ::F64 => {
514                    let dur = v.timestamp() as f64;
515                    let dur = dur
516                        + (v.timestamp_nanos_opt()
517                            .expect("cannot represent as timestamp with ns precision")
518                            / 1_000_000_000) as f64;
519                    if typ == Typ::F32 {
520                        Some(Value::F32(dur as f32))
521                    } else {
522                        Some(Value::F64(dur))
523                    }
524                }
525                Typ::DateTime => Some(Value::DateTime(v)),
526                Typ::Decimal => None,
527                Typ::Duration => None,
528                Typ::Bool => None,
529                Typ::Bytes => None,
530                Typ::Error => None,
531                Typ::Array => Some(Value::Array([self].into())),
532                Typ::Null => Some(Value::Null),
533                Typ::String => unreachable!(),
534            },
535            Value::Duration(d) => match typ {
536                Typ::U32 => Some(Value::U32(d.as_secs() as u32)),
537                Typ::V32 => Some(Value::V32(d.as_secs() as u32)),
538                Typ::I32 => Some(Value::I32(d.as_secs() as i32)),
539                Typ::Z32 => Some(Value::Z32(d.as_secs() as i32)),
540                Typ::U64 => Some(Value::U64(d.as_secs() as u64)),
541                Typ::V64 => Some(Value::V64(d.as_secs() as u64)),
542                Typ::I64 => Some(Value::I64(d.as_secs() as i64)),
543                Typ::Z64 => Some(Value::Z64(d.as_secs() as i64)),
544                Typ::F32 => Some(Value::F32(d.as_secs_f32())),
545                Typ::F64 => Some(Value::F64(d.as_secs_f64())),
546                Typ::Decimal => None,
547                Typ::DateTime => None,
548                Typ::Duration => Some(Value::Duration(d)),
549                Typ::Bool => None,
550                Typ::Bytes => None,
551                Typ::Error => None,
552                Typ::Array => Some(Value::Array([self].into())),
553                Typ::Null => Some(Value::Null),
554                Typ::String => unreachable!(),
555            },
556            Value::Bool(b) => match typ {
557                Typ::U32 => Some(Value::U32(b as u32)),
558                Typ::V32 => Some(Value::V32(b as u32)),
559                Typ::I32 => Some(Value::I32(b as i32)),
560                Typ::Z32 => Some(Value::Z32(b as i32)),
561                Typ::U64 => Some(Value::U64(b as u64)),
562                Typ::V64 => Some(Value::V64(b as u64)),
563                Typ::I64 => Some(Value::I64(b as i64)),
564                Typ::Z64 => Some(Value::Z64(b as i64)),
565                Typ::F32 => Some(Value::F32(b as u32 as f32)),
566                Typ::F64 => Some(Value::F64(b as u64 as f64)),
567                Typ::Decimal => None,
568                Typ::DateTime => None,
569                Typ::Duration => None,
570                Typ::Bool => Some(self),
571                Typ::Bytes => None,
572                Typ::Error => None,
573                Typ::Array => Some(Value::Array([self].into())),
574                Typ::Null => Some(Value::Null),
575                Typ::String => unreachable!(),
576            },
577            Value::Bytes(_) if typ == Typ::Bytes => Some(self),
578            Value::Bytes(_) => None,
579            Value::Error(_) => Value::Bool(false).cast(typ),
580            Value::Null if typ == Typ::Null => Some(self),
581            Value::Null => None,
582        }
583    }
584
585    /// cast value directly to any type implementing `FromValue`
586    pub fn cast_to<T: FromValue + Sized>(self) -> Result<T> {
587        <T as FromValue>::from_value(self)
588    }
589
590    pub fn get_as<T: FromValue + Sized>(self) -> Option<T> {
591        <T as FromValue>::get(self)
592    }
593
594    pub fn err<T: std::error::Error>(e: T) -> Value {
595        use std::fmt::Write;
596        let mut tmp = CompactString::new("");
597        write!(tmp, "{e}").unwrap();
598        Value::Error(tmp.as_str().into())
599    }
600
601    /// return true if the value is some kind of number, otherwise
602    /// false.
603    pub fn number(&self) -> bool {
604        match self {
605            Value::U32(_)
606            | Value::V32(_)
607            | Value::I32(_)
608            | Value::Z32(_)
609            | Value::U64(_)
610            | Value::V64(_)
611            | Value::I64(_)
612            | Value::Z64(_)
613            | Value::F32(_)
614            | Value::F64(_)
615            | Value::Decimal(_) => true,
616            Value::DateTime(_)
617            | Value::Duration(_)
618            | Value::String(_)
619            | Value::Bytes(_)
620            | Value::Bool(_)
621            | Value::Null
622            | Value::Error(_)
623            | Value::Array(_) => false,
624        }
625    }
626
627    /// return an iterator that will perform a depth first traversal
628    /// of the specified value. All array elements will be flattened
629    /// into non array values.
630    pub fn flatten(self) -> impl Iterator<Item = Value> {
631        use utils::Either;
632        match self {
633            Value::Array(elts) => {
634                let mut stack: SmallVec<[(ValArray, usize); 8]> = SmallVec::new();
635                stack.push((elts, 0));
636                Either::Left(iter::from_fn(move || loop {
637                    match stack.last_mut() {
638                        None => break None,
639                        Some((elts, pos)) => {
640                            if *pos >= elts.len() {
641                                stack.pop();
642                            } else {
643                                match &elts[*pos] {
644                                    Value::Array(elts) => {
645                                        *pos += 1;
646                                        let elts = elts.clone();
647                                        stack.push((elts, 0));
648                                    }
649                                    val => {
650                                        *pos += 1;
651                                        break Some(val.clone());
652                                    }
653                                }
654                            }
655                        }
656                    }
657                }))
658            }
659            val => Either::Right(iter::once(val)),
660        }
661    }
662}