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#[derive(Debug, Serialize, Deserialize)]
64#[serde(tag = "type", content = "value")]
65#[repr(u32)]
66pub enum Value {
67 U32(u32) = 0x0000_0001,
69 V32(u32) = 0x0000_0002,
71 I32(i32) = 0x0000_0004,
73 Z32(i32) = 0x0000_0008,
75 U64(u64) = 0x0000_0010,
77 V64(u64) = 0x0000_0020,
79 I64(i64) = 0x0000_0040,
81 Z64(i64) = 0x0000_0080,
83 F32(f32) = 0x0000_0100,
85 F64(f64) = 0x0000_0200,
87 Bool(bool) = 0x0000_0400,
89 Null = 0x0000_0800,
91 String(ArcStr) = 0x8000_0000,
93 Bytes(PBytes) = 0x4000_0000,
95 Error(Arc<Value>) = 0x2000_0000,
97 Array(ValArray) = 0x1000_0000,
99 Map(Map) = 0x0800_0000,
101 Decimal(Arc<Decimal>) = 0x0400_0000,
103 DateTime(Arc<DateTime<Utc>>) = 0x0200_0000,
105 Duration(Arc<Duration>) = 0x0100_0000,
107}
108
109fn _assert_variants_are_copy(v: &Value) -> Value {
113 let i = match v {
114 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 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 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 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), 18 => {
361 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 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 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 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 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}