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