netidx_value/
lib.rs

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