1use anyhow::Result;
69use arcstr::ArcStr;
70use bytes::{Buf, BufMut};
71use chrono::prelude::*;
72use compact_str::{format_compact, CompactString};
73use immutable_chunkmap::map;
74use netidx_core::{
75 pack::{self, Pack, PackError},
76 utils,
77};
78use rust_decimal::Decimal;
79use serde::{Deserialize, Serialize};
80use smallvec::SmallVec;
81use std::{
82 any::Any, hint::unreachable_unchecked, iter, ptr, result, str::FromStr,
83 time::Duration,
84};
85use triomphe::Arc;
86
87pub mod abstract_type;
88pub mod array;
89mod convert;
90mod op;
91pub mod parser;
92pub mod pbuf;
93mod print;
94#[cfg(test)]
95mod test;
96mod typ;
97
98pub use abstract_type::Abstract;
99pub use array::ValArray;
100pub use convert::FromValue;
101pub use pbuf::PBytes;
102pub use print::{printf, NakedValue};
103pub use typ::Typ;
104
105#[macro_export]
106macro_rules! valarray {
107 ($proto:expr; $size:literal) => {{
108 let proto: Value = $proto.into();
109 Value::Array(std::array::from_fn::<_, $size, _>(|_| proto.clone()))
110 }};
111 ($($e:expr),+) => {
112 Value::Array([$($e.into()),+].into())
113 }
114}
115
116fn _test_valarray() {
117 let v: Value = valarray![1, 2, 5.3, 10];
118 let _: Value = valarray![valarray!["elts", v], valarray!["foo", ["bar"]]];
119}
120
121pub type Map = map::Map<Value, Value, 32>;
122
123const COPY_MAX: u64 = 0x0000_8000;
124
125#[derive(Debug, Serialize, Deserialize)]
138#[serde(tag = "type", content = "value")]
139#[repr(u64)]
140pub enum Value {
141 U8(u8) = 0x0000_0001,
143 I8(i8) = 0x0000_0002,
145 U16(u16) = 0x0000_0004,
147 I16(i16) = 0x0000_0008,
149 U32(u32) = 0x0000_0010,
151 V32(u32) = 0x0000_0020,
153 I32(i32) = 0x0000_0040,
155 Z32(i32) = 0x0000_0080,
157 U64(u64) = 0x0000_0100,
159 V64(u64) = 0x0000_0200,
161 I64(i64) = 0x0000_0400,
163 Z64(i64) = 0x0000_0800,
165 F32(f32) = 0x0000_1000,
167 F64(f64) = 0x0000_2000,
169 Bool(bool) = 0x0000_4000,
171 Null = 0x0000_8000,
173 String(ArcStr) = 0x8000_0000,
175 Bytes(PBytes) = 0x4000_0000,
177 Error(Arc<Value>) = 0x2000_0000,
179 Array(ValArray) = 0x1000_0000,
181 Map(Map) = 0x0800_0000,
183 Decimal(Arc<Decimal>) = 0x0400_0000,
185 DateTime(Arc<DateTime<Utc>>) = 0x0200_0000,
187 Duration(Arc<Duration>) = 0x0100_0000,
189 Abstract(Abstract) = 0x0080_0000,
191}
192
193fn _assert_variants_are_copy(v: &Value) -> Value {
197 let i = match v {
198 Value::U8(i) => Value::U8(*i),
200 Value::I8(i) => Value::I8(*i),
201 Value::U16(i) => Value::U16(*i),
202 Value::I16(i) => Value::I16(*i),
203 Value::U32(i) | Value::V32(i) => Value::U32(*i),
204 Value::I32(i) | Value::Z32(i) => Value::I32(*i),
205 Value::U64(i) | Value::V64(i) => Value::U64(*i),
206 Value::I64(i) | Value::Z64(i) => Value::I64(*i),
207 Value::F32(i) => Value::F32(*i),
208 Value::F64(i) => Value::F64(*i),
209 Value::Bool(b) => Value::Bool(*b),
210 Value::Null => Value::Null,
211
212 Value::String(i) => Value::String(i.clone()),
214 Value::Bytes(i) => Value::Bytes(i.clone()),
215 Value::Error(i) => Value::Error(i.clone()),
216 Value::Array(i) => Value::Array(i.clone()),
217 Value::Map(i) => Value::Map(i.clone()),
218 Value::Decimal(i) => Value::Decimal(i.clone()),
219 Value::DateTime(i) => Value::DateTime(i.clone()),
220 Value::Duration(i) => Value::Duration(i.clone()),
221 Value::Abstract(i) => Value::Abstract(i.clone()),
222 };
223 panic!("{i}")
224}
225
226impl Clone for Value {
227 fn clone(&self) -> Self {
228 if self.is_copy() {
229 unsafe { ptr::read(self) }
230 } else {
231 match self {
232 Self::String(c) => Self::String(c.clone()),
233 Self::Bytes(b) => Self::Bytes(b.clone()),
234 Self::Error(e) => Self::Error(e.clone()),
235 Self::Array(a) => Self::Array(a.clone()),
236 Self::Map(m) => Self::Map(m.clone()),
237 Self::Decimal(d) => Self::Decimal(d.clone()),
238 Self::DateTime(d) => Self::DateTime(d.clone()),
239 Self::Duration(d) => Self::Duration(d.clone()),
240 Self::Abstract(v) => Self::Abstract(v.clone()),
241 Self::U8(_)
242 | Self::I8(_)
243 | Self::U16(_)
244 | Self::I16(_)
245 | Self::U32(_)
246 | Self::V32(_)
247 | Self::I32(_)
248 | Self::Z32(_)
249 | Self::U64(_)
250 | Self::V64(_)
251 | Self::I64(_)
252 | Self::Z64(_)
253 | Self::F32(_)
254 | Self::F64(_)
255 | Self::Bool(_)
256 | Self::Null => unsafe { unreachable_unchecked() },
257 }
258 }
259 }
260
261 fn clone_from(&mut self, source: &Self) {
262 if source.is_copy() {
263 unsafe { ptr::copy_nonoverlapping(source, self, 1) };
264 } else {
265 match source {
266 Self::String(c) => {
267 *self = Self::String(c.clone());
268 }
269 Self::Bytes(b) => {
270 *self = Self::Bytes(b.clone());
271 }
272 Self::Error(e) => {
273 *self = Self::Error(e.clone());
274 }
275 Self::Array(a) => {
276 *self = Self::Array(a.clone());
277 }
278 Self::Map(m) => {
279 *self = Self::Map(m.clone());
280 }
281 Value::Decimal(d) => {
282 *self = Self::Decimal(d.clone());
283 }
284 Value::DateTime(d) => {
285 *self = Self::DateTime(d.clone());
286 }
287 Value::Duration(d) => {
288 *self = Self::Duration(d.clone());
289 }
290 Value::Abstract(v) => {
291 *self = Self::Abstract(v.clone());
292 }
293 Value::I8(_)
294 | Value::U8(_)
295 | Value::U16(_)
296 | Value::I16(_)
297 | Value::U32(_)
298 | Value::V32(_)
299 | Value::I32(_)
300 | Value::Z32(_)
301 | Value::U64(_)
302 | Value::V64(_)
303 | Value::I64(_)
304 | Value::Z64(_)
305 | Value::F32(_)
306 | Value::F64(_)
307 | Value::Bool(_)
308 | Value::Null => unsafe { unreachable_unchecked() },
309 }
310 }
311 }
312}
313
314impl FromStr for Value {
315 type Err = anyhow::Error;
316
317 fn from_str(s: &str) -> result::Result<Self, Self::Err> {
318 parser::parse_value(s)
319 }
320}
321
322impl Pack for Value {
323 fn encoded_len(&self) -> usize {
324 1 + match self {
325 Value::U8(v) => Pack::encoded_len(v),
326 Value::I8(v) => Pack::encoded_len(v),
327 Value::U16(v) => Pack::encoded_len(v),
328 Value::I16(v) => Pack::encoded_len(v),
329 Value::U32(v) => Pack::encoded_len(v),
330 Value::V32(v) => pack::varint_len(*v as u64),
331 Value::I32(v) => Pack::encoded_len(v),
332 Value::Z32(v) => pack::varint_len(pack::i32_zz(*v) as u64),
333 Value::U64(v) => Pack::encoded_len(v),
334 Value::V64(v) => pack::varint_len(*v),
335 Value::I64(v) => Pack::encoded_len(v),
336 Value::Z64(v) => pack::varint_len(pack::i64_zz(*v) as u64),
337 Value::F32(v) => Pack::encoded_len(v),
338 Value::F64(v) => Pack::encoded_len(v),
339 Value::DateTime(d) => Pack::encoded_len(d),
340 Value::Duration(d) => Pack::encoded_len(d),
341 Value::String(c) => Pack::encoded_len(c),
342 Value::Bytes(b) => Pack::encoded_len(b),
343 Value::Bool(_) | Value::Null => 0,
344 Value::Error(c) => match &**c {
345 Value::String(s) => Pack::encoded_len(s),
346 v => Pack::encoded_len(v),
347 },
348 Value::Array(elts) => Pack::encoded_len(elts),
349 Value::Decimal(d) => Pack::encoded_len(d),
350 Value::Map(m) => Pack::encoded_len(m),
351 Value::Abstract(v) => Pack::encoded_len(v),
352 }
353 }
354
355 fn encode(&self, buf: &mut impl BufMut) -> result::Result<(), PackError> {
358 match self {
359 Value::U32(i) => {
360 buf.put_u8(0);
361 Pack::encode(i, buf)
362 }
363 Value::V32(i) => {
364 buf.put_u8(1);
365 Ok(pack::encode_varint(*i as u64, buf))
366 }
367 Value::I32(i) => {
368 buf.put_u8(2);
369 Pack::encode(i, buf)
370 }
371 Value::Z32(i) => {
372 buf.put_u8(3);
373 Ok(pack::encode_varint(pack::i32_zz(*i) as u64, buf))
374 }
375 Value::U64(i) => {
376 buf.put_u8(4);
377 Pack::encode(i, buf)
378 }
379 Value::V64(i) => {
380 buf.put_u8(5);
381 Ok(pack::encode_varint(*i, buf))
382 }
383 Value::I64(i) => {
384 buf.put_u8(6);
385 Pack::encode(i, buf)
386 }
387 Value::Z64(i) => {
388 buf.put_u8(7);
389 Ok(pack::encode_varint(pack::i64_zz(*i), buf))
390 }
391 Value::F32(i) => {
392 buf.put_u8(8);
393 Pack::encode(i, buf)
394 }
395 Value::F64(i) => {
396 buf.put_u8(9);
397 Pack::encode(i, buf)
398 }
399 Value::DateTime(dt) => {
400 buf.put_u8(10);
401 Pack::encode(dt, buf)
402 }
403 Value::Duration(d) => {
404 buf.put_u8(11);
405 Pack::encode(d, buf)
406 }
407 Value::String(s) => {
408 buf.put_u8(12);
409 Pack::encode(s, buf)
410 }
411 Value::Bytes(b) => {
412 buf.put_u8(13);
413 Pack::encode(b, buf)
414 }
415 Value::Bool(true) => Ok(buf.put_u8(14)),
416 Value::Bool(false) => Ok(buf.put_u8(15)),
417 Value::Null => Ok(buf.put_u8(16)),
418 Value::Array(elts) => {
422 buf.put_u8(19);
423 Pack::encode(elts, buf)
424 }
425 Value::Decimal(d) => {
426 buf.put_u8(20);
427 Pack::encode(d, buf)
428 }
429 Value::Map(m) => {
430 buf.put_u8(21);
431 Pack::encode(m, buf)
432 }
433 Value::Error(e) => match &**e {
434 Value::String(s) => {
435 buf.put_u8(18);
436 Pack::encode(s, buf)
437 }
438 v => {
439 buf.put_u8(22);
440 Pack::encode(v, buf)
441 }
442 },
443 Value::U8(i) => {
444 buf.put_u8(23);
445 Pack::encode(i, buf)
446 }
447 Value::I8(i) => {
448 buf.put_u8(24);
449 Pack::encode(i, buf)
450 }
451 Value::U16(i) => {
452 buf.put_u8(25);
453 Pack::encode(i, buf)
454 }
455 Value::I16(i) => {
456 buf.put_u8(26);
457 Pack::encode(i, buf)
458 }
459 Value::Abstract(v) => {
460 buf.put_u8(27);
461 Pack::encode(v, buf)
462 }
463 }
464 }
465
466 fn decode(buf: &mut impl Buf) -> result::Result<Self, PackError> {
467 match <u8 as Pack>::decode(buf)? {
468 0 => Ok(Value::U32(Pack::decode(buf)?)),
469 1 => Ok(Value::V32(pack::decode_varint(buf)? as u32)),
470 2 => Ok(Value::I32(Pack::decode(buf)?)),
471 3 => Ok(Value::Z32(pack::i32_uzz(pack::decode_varint(buf)? as u32))),
472 4 => Ok(Value::U64(Pack::decode(buf)?)),
473 5 => Ok(Value::V64(pack::decode_varint(buf)?)),
474 6 => Ok(Value::I64(Pack::decode(buf)?)),
475 7 => Ok(Value::Z64(pack::i64_uzz(pack::decode_varint(buf)?))),
476 8 => Ok(Value::F32(Pack::decode(buf)?)),
477 9 => Ok(Value::F64(Pack::decode(buf)?)),
478 10 => Ok(Value::DateTime(Pack::decode(buf)?)),
479 11 => Ok(Value::Duration(Pack::decode(buf)?)),
480 12 => Ok(Value::String(Pack::decode(buf)?)),
481 13 => Ok(Value::Bytes(Pack::decode(buf)?)),
482 14 => Ok(Value::Bool(true)),
483 15 => Ok(Value::Bool(false)),
484 16 => Ok(Value::Null),
485 17 => Ok(Value::Null), 18 => {
487 Ok(Value::Error(Arc::new(Value::String(<ArcStr as Pack>::decode(buf)?))))
490 }
491 19 => Ok(Value::Array(Pack::decode(buf)?)),
492 20 => Ok(Value::Decimal(Pack::decode(buf)?)),
493 21 => Ok(Value::Map(Pack::decode(buf)?)),
494 22 => Ok(Value::Error(Arc::new(Pack::decode(buf)?))),
495 23 => Ok(Value::U8(Pack::decode(buf)?)),
496 24 => Ok(Value::I8(Pack::decode(buf)?)),
497 25 => Ok(Value::U16(Pack::decode(buf)?)),
498 26 => Ok(Value::I16(Pack::decode(buf)?)),
499 27 => Ok(Value::Abstract(Pack::decode(buf)?)),
500 _ => Err(PackError::UnknownTag),
501 }
502 }
503}
504
505impl Value {
506 pub fn approx_eq(&self, v: &Self) -> bool {
507 use std::num::FpCategory::*;
508 match (self, v) {
509 (Value::U32(l) | Value::V32(l), Value::U32(r) | Value::V32(r)) => l == r,
510 (Value::I32(l) | Value::Z32(l), Value::I32(r) | Value::Z32(r)) => l == r,
511 (Value::U64(l) | Value::V64(l), Value::U64(r) | Value::V64(r)) => l == r,
512 (Value::I64(l) | Value::Z64(l), Value::I64(r) | Value::Z64(r)) => l == r,
513 (Value::F32(l), Value::F32(r)) => match (l.classify(), r.classify()) {
514 (Nan, Nan) => true,
515 (Zero, Zero) => true,
516 (_, _) => (l - r).abs() <= f32::EPSILON,
517 },
518 (Value::F64(l), Value::F64(r)) => match (l.classify(), r.classify()) {
519 (Nan, Nan) => true,
520 (Zero, Zero) => true,
521 (_, _) => (l - r).abs() <= f64::EPSILON,
522 },
523 (Value::Decimal(l), Value::Decimal(r)) => l == r,
524 (Value::DateTime(l), Value::DateTime(r)) => l == r,
525 (Value::Duration(l), Value::Duration(r)) => {
526 (l.as_secs_f64() - r.as_secs_f64()).abs() <= f64::EPSILON
527 }
528 (Value::String(l), Value::String(r)) => l == r,
529 (Value::Bytes(l), Value::Bytes(r)) => l == r,
530 (Value::Bool(l), Value::Bool(r)) => l == r,
531 (Value::Null, Value::Null) => true,
532 (Value::Error(l), Value::Error(r)) => l.approx_eq(r),
533 (Value::Array(l), Value::Array(r)) => {
534 l.len() == r.len()
535 && l.iter().zip(r.iter()).all(|(v0, v1)| v0.approx_eq(v1))
536 }
537 (Value::Map(l), Value::Map(r)) => {
538 l.len() == r.len()
539 && l.into_iter()
540 .zip(r.into_iter())
541 .all(|((k0, v0), (k1, v1))| k0.approx_eq(k1) && v0.approx_eq(v1))
542 }
543 (Value::Array(_), _) | (_, Value::Array(_)) => false,
544 (l, r) if l.number() || r.number() => {
545 match (l.clone().cast_to::<f64>(), r.clone().cast_to::<f64>()) {
546 (Ok(l), Ok(r)) => match (l.classify(), r.classify()) {
547 (Nan, Nan) => true,
548 (Zero, Zero) => true,
549 (_, _) => (l - r).abs() <= f64::EPSILON,
550 },
551 (_, _) => false,
552 }
553 }
554 (_, _) => false,
555 }
556 }
557
558 pub fn discriminant(&self) -> u64 {
560 unsafe { *<*const _>::from(self).cast::<u64>() }
561 }
562
563 pub fn is_copy(&self) -> bool {
565 self.discriminant() <= COPY_MAX
566 }
567
568 pub fn cast(self, typ: Typ) -> Option<Value> {
570 macro_rules! cast_number {
571 ($v:expr, $typ:expr) => {
572 match typ {
573 Typ::U8 => Some(Value::U8($v as u8)),
574 Typ::I8 => Some(Value::I8($v as i8)),
575 Typ::U16 => Some(Value::U16($v as u16)),
576 Typ::I16 => Some(Value::I16($v as i16)),
577 Typ::U32 => Some(Value::U32($v as u32)),
578 Typ::V32 => Some(Value::V32($v as u32)),
579 Typ::I32 => Some(Value::I32($v as i32)),
580 Typ::Z32 => Some(Value::Z32($v as i32)),
581 Typ::U64 => Some(Value::U64($v as u64)),
582 Typ::V64 => Some(Value::V64($v as u64)),
583 Typ::I64 => Some(Value::I64($v as i64)),
584 Typ::Z64 => Some(Value::Z64($v as i64)),
585 Typ::F32 => Some(Value::F32($v as f32)),
586 Typ::F64 => Some(Value::F64($v as f64)),
587 Typ::Decimal => match Decimal::try_from($v) {
588 Ok(d) => Some(Value::Decimal(Arc::new(d))),
589 Err(_) => None,
590 },
591 Typ::DateTime => Some(Value::DateTime(Arc::new(
592 DateTime::from_timestamp($v as i64, 0)?,
593 ))),
594 Typ::Duration => {
595 Some(Value::Duration(Arc::new(Duration::from_secs($v as u64))))
596 }
597 Typ::Bool => Some(if $v as i64 > 0 {
598 Value::Bool(true)
599 } else {
600 Value::Bool(false)
601 }),
602 Typ::String => {
603 Some(Value::String(format_compact!("{}", self).as_str().into()))
604 }
605 Typ::Array => Some(Value::Array([self.clone()].into())),
606 Typ::Null => Some(Value::Null),
607 Typ::Bytes | Typ::Error | Typ::Map | Typ::Abstract => None,
608 }
609 };
610 }
611 match self {
612 Value::String(s) => match typ {
613 Typ::String => Some(Value::String(s)),
614 Typ::Error => Some(Value::Error(Arc::new(Value::String(s)))),
615 Typ::Array => Some(Value::Array([Value::String(s)].into())),
616 _ => s.parse::<Value>().ok().and_then(|v| v.cast(typ)),
617 },
618 v if typ == Typ::String => {
619 Some(Value::String(format_compact!("{}", v).as_str().into()))
620 }
621 Value::Map(m) => match typ {
622 Typ::Map => Some(Value::Map(m)),
623 Typ::Array => Some(Value::Array(ValArray::from_iter(m.into_iter().map(
624 |(k, v)| {
625 Value::Array(ValArray::from_iter_exact(
626 [k.clone(), v.clone()].into_iter(),
627 ))
628 },
629 )))),
630 _ => None,
631 },
632 Value::Array(elts) => match typ {
633 Typ::Array => Some(Value::Array(elts)),
634 Typ::Map => {
635 match Value::Array(elts).cast_to::<SmallVec<[(Value, Value); 8]>>() {
636 Err(_) => None,
637 Ok(vals) => Some(Value::Map(Map::from_iter(vals))),
638 }
639 }
640 typ => elts.first().and_then(|v| v.clone().cast(typ)),
641 },
642 Value::U8(v) => cast_number!(v, typ),
643 Value::I8(v) => cast_number!(v, typ),
644 Value::U16(v) => cast_number!(v, typ),
645 Value::I16(v) => cast_number!(v, typ),
646 Value::U32(v) | Value::V32(v) => cast_number!(v, typ),
647 Value::I32(v) | Value::Z32(v) => cast_number!(v, typ),
648 Value::U64(v) | Value::V64(v) => cast_number!(v, typ),
649 Value::I64(v) | Value::Z64(v) => cast_number!(v, typ),
650 Value::F32(v) => cast_number!(v, typ),
651 Value::F64(v) => cast_number!(v, typ),
652 Value::Decimal(v) => match typ {
653 Typ::Decimal => Some(Value::Decimal(v)),
654 Typ::U8 => (*v).try_into().ok().map(Value::U8),
655 Typ::I8 => (*v).try_into().ok().map(Value::I8),
656 Typ::U16 => (*v).try_into().ok().map(Value::U16),
657 Typ::I16 => (*v).try_into().ok().map(Value::I16),
658 Typ::U32 => (*v).try_into().ok().map(Value::U32),
659 Typ::V32 => (*v).try_into().ok().map(Value::V32),
660 Typ::I32 => (*v).try_into().ok().map(Value::I32),
661 Typ::Z32 => (*v).try_into().ok().map(Value::Z32),
662 Typ::U64 => (*v).try_into().ok().map(Value::U64),
663 Typ::V64 => (*v).try_into().ok().map(Value::V64),
664 Typ::I64 => (*v).try_into().ok().map(Value::I64),
665 Typ::Z64 => (*v).try_into().ok().map(Value::Z64),
666 Typ::F32 => (*v).try_into().ok().map(Value::F32),
667 Typ::F64 => (*v).try_into().ok().map(Value::F64),
668 Typ::String => {
669 Some(Value::String(format_compact!("{}", v).as_str().into()))
670 }
671 Typ::Bool
672 | Typ::Array
673 | Typ::Map
674 | Typ::Abstract
675 | Typ::Bytes
676 | Typ::DateTime
677 | Typ::Duration
678 | Typ::Null
679 | Typ::Error => None,
680 },
681 Value::DateTime(ref v) => match typ {
682 Typ::U8 | Typ::I8 | Typ::U16 | Typ::I16 => None,
683 Typ::U32 | Typ::V32 => {
684 let ts = v.timestamp();
685 if ts < 0 || ts > u32::MAX as i64 {
686 None
687 } else {
688 if typ == Typ::U32 {
689 Some(Value::U32(ts as u32))
690 } else {
691 Some(Value::V32(ts as u32))
692 }
693 }
694 }
695 Typ::I32 | Typ::Z32 => {
696 let ts = v.timestamp();
697 if ts < i32::MIN as i64 || ts > i32::MAX as i64 {
698 None
699 } else {
700 if typ == Typ::I32 {
701 Some(Value::I32(ts as i32))
702 } else {
703 Some(Value::Z32(ts as i32))
704 }
705 }
706 }
707 Typ::U64 | Typ::V64 => {
708 let ts = v.timestamp();
709 if ts < 0 {
710 None
711 } else {
712 if typ == Typ::U64 {
713 Some(Value::U64(ts as u64))
714 } else {
715 Some(Value::V64(ts as u64))
716 }
717 }
718 }
719 Typ::I64 => Some(Value::I64(v.timestamp())),
720 Typ::Z64 => Some(Value::Z64(v.timestamp())),
721 Typ::F32 | Typ::F64 => {
722 let dur = v.timestamp() as f64;
723 let dur = dur + (v.timestamp_nanos_opt()? / 1_000_000_000) as f64;
724 if typ == Typ::F32 {
725 Some(Value::F32(dur as f32))
726 } else {
727 Some(Value::F64(dur))
728 }
729 }
730 Typ::DateTime => Some(Value::DateTime(v.clone())),
731 Typ::Array => Some(Value::Array([self].into())),
732 Typ::Null => Some(Value::Null),
733 Typ::String => unreachable!(),
734 Typ::Decimal
735 | Typ::Duration
736 | Typ::Bool
737 | Typ::Bytes
738 | Typ::Error
739 | Typ::Map
740 | Typ::Abstract => None,
741 },
742 Value::Duration(ref d) => match typ {
743 Typ::U8 | Typ::I8 | Typ::U16 | Typ::I16 => None,
744 Typ::U32 => Some(Value::U32(d.as_secs() as u32)),
745 Typ::V32 => Some(Value::V32(d.as_secs() as u32)),
746 Typ::I32 => Some(Value::I32(d.as_secs() as i32)),
747 Typ::Z32 => Some(Value::Z32(d.as_secs() as i32)),
748 Typ::U64 => Some(Value::U64(d.as_secs() as u64)),
749 Typ::V64 => Some(Value::V64(d.as_secs() as u64)),
750 Typ::I64 => Some(Value::I64(d.as_secs() as i64)),
751 Typ::Z64 => Some(Value::Z64(d.as_secs() as i64)),
752 Typ::F32 => Some(Value::F32(d.as_secs_f32())),
753 Typ::F64 => Some(Value::F64(d.as_secs_f64())),
754 Typ::Array => Some(Value::Array([self].into())),
755 Typ::Duration => Some(Value::Duration(d.clone())),
756 Typ::Null => Some(Value::Null),
757 Typ::String => unreachable!(),
758 Typ::Decimal
759 | Typ::DateTime
760 | Typ::Bool
761 | Typ::Bytes
762 | Typ::Error
763 | Typ::Map
764 | Typ::Abstract => None,
765 },
766 Value::Bool(b) => match typ {
767 Typ::U8 => Some(Value::U8(b as u8)),
768 Typ::I8 => Some(Value::I8(b as i8)),
769 Typ::U16 => Some(Value::U16(b as u16)),
770 Typ::I16 => Some(Value::I16(b as i16)),
771 Typ::U32 => Some(Value::U32(b as u32)),
772 Typ::V32 => Some(Value::V32(b as u32)),
773 Typ::I32 => Some(Value::I32(b as i32)),
774 Typ::Z32 => Some(Value::Z32(b as i32)),
775 Typ::U64 => Some(Value::U64(b as u64)),
776 Typ::V64 => Some(Value::V64(b as u64)),
777 Typ::I64 => Some(Value::I64(b as i64)),
778 Typ::Z64 => Some(Value::Z64(b as i64)),
779 Typ::F32 => Some(Value::F32(b as u32 as f32)),
780 Typ::F64 => Some(Value::F64(b as u64 as f64)),
781 Typ::Bool => Some(self),
782 Typ::Array => Some(Value::Array([self].into())),
783 Typ::Null => Some(Value::Null),
784 Typ::String => unreachable!(),
785 Typ::Decimal
786 | Typ::DateTime
787 | Typ::Duration
788 | Typ::Bytes
789 | Typ::Error
790 | Typ::Map
791 | Typ::Abstract => None,
792 },
793 Value::Bytes(_) if typ == Typ::Bytes => Some(self),
794 Value::Bytes(_) => None,
795 Value::Error(_) => Value::Bool(false).cast(typ),
796 Value::Null if typ == Typ::Null => Some(self),
797 Value::Null => None,
798 Value::Abstract(_) if typ == Typ::Abstract => Some(self),
799 Value::Abstract(_) => None,
800 }
801 }
802
803 pub fn cast_to<T: FromValue + Sized>(self) -> Result<T> {
805 <T as FromValue>::from_value(self)
806 }
807
808 pub fn get_as<T: FromValue + Sized>(self) -> Option<T> {
812 <T as FromValue>::get(self)
813 }
814
815 pub fn downcast_ref<T: Any + Send + Sync>(&self) -> Option<&T> {
820 match self {
821 Value::Abstract(a) => a.downcast_ref::<T>(),
822 _ => None,
823 }
824 }
825
826 pub unsafe fn get_as_unchecked<T>(&self) -> &T {
831 unsafe {
835 let ptr = (self as *const _ as *const u64).add(1);
836 &*(ptr as *const T)
837 }
838 }
839
840 pub fn err<T: std::error::Error>(e: T) -> Value {
842 use std::fmt::Write;
843 let mut tmp = CompactString::new("");
844 write!(tmp, "{e}").unwrap();
845 Value::Error(Arc::new(Value::String(tmp.as_str().into())))
846 }
847
848 pub fn error<S: Into<ArcStr>>(e: S) -> Value {
850 Value::Error(Arc::new(Value::String(e.into())))
851 }
852
853 pub fn number(&self) -> bool {
856 match self {
857 Value::U8(_)
858 | Value::I8(_)
859 | Value::U16(_)
860 | Value::I16(_)
861 | Value::U32(_)
862 | Value::V32(_)
863 | Value::I32(_)
864 | Value::Z32(_)
865 | Value::U64(_)
866 | Value::V64(_)
867 | Value::I64(_)
868 | Value::Z64(_)
869 | Value::F32(_)
870 | Value::F64(_)
871 | Value::Decimal(_) => true,
872 Value::DateTime(_)
873 | Value::Duration(_)
874 | Value::String(_)
875 | Value::Bytes(_)
876 | Value::Bool(_)
877 | Value::Null
878 | Value::Error(_)
879 | Value::Array(_)
880 | Value::Map(_)
881 | Value::Abstract(_) => false,
882 }
883 }
884
885 pub fn integer(&self) -> bool {
888 match self {
889 Value::U8(_)
890 | Value::I8(_)
891 | Value::U16(_)
892 | Value::I16(_)
893 | Value::U32(_)
894 | Value::V32(_)
895 | Value::I32(_)
896 | Value::Z32(_)
897 | Value::U64(_)
898 | Value::V64(_)
899 | Value::I64(_)
900 | Value::Z64(_) => true,
901 Value::F32(_)
902 | Value::F64(_)
903 | Value::Decimal(_)
904 | Value::DateTime(_)
905 | Value::Duration(_)
906 | Value::String(_)
907 | Value::Bytes(_)
908 | Value::Bool(_)
909 | Value::Null
910 | Value::Error(_)
911 | Value::Array(_)
912 | Value::Map(_)
913 | Value::Abstract(_) => false,
914 }
915 }
916
917 pub fn flatten(self) -> impl Iterator<Item = Value> {
921 use utils::Either;
922 match self {
923 Value::Array(elts) => {
924 let mut stack: SmallVec<[(ValArray, usize); 8]> = SmallVec::new();
925 stack.push((elts, 0));
926 Either::Left(iter::from_fn(move || loop {
927 match stack.last_mut() {
928 None => break None,
929 Some((elts, pos)) => {
930 if *pos >= elts.len() {
931 stack.pop();
932 } else {
933 match &elts[*pos] {
934 Value::Array(elts) => {
935 *pos += 1;
936 let elts = elts.clone();
937 stack.push((elts, 0));
938 }
939 val => {
940 *pos += 1;
941 break Some(val.clone());
942 }
943 }
944 }
945 }
946 }
947 }))
948 }
949 val => Either::Right(iter::once(val)),
950 }
951 }
952}