use anyhow::{bail, Result as Res};
use arcstr::ArcStr;
use base64::{engine::general_purpose::STANDARD as BASE64, Engine};
use bytes::{Buf, BufMut, Bytes};
use chrono::{naive::NaiveDateTime, prelude::*};
use fxhash::FxHashMap;
use indexmap::{IndexMap, IndexSet};
use netidx_core::{
    chars::Chars,
    pack::{self, Pack, PackError},
    path::Path,
    pool::{Pool, Pooled},
    utils,
};
use rust_decimal::Decimal;
use smallvec::SmallVec;
use std::{
    any::{Any, TypeId},
    cell::RefCell,
    cmp::{Ordering, PartialEq, PartialOrd},
    collections::{BTreeMap, BTreeSet, HashMap, HashSet},
    convert, fmt,
    hash::{BuildHasher, Hash},
    iter, mem,
    num::Wrapping,
    ops::{Add, Div, Mul, Not, Sub},
    panic::{catch_unwind, AssertUnwindSafe},
    result,
    str::FromStr,
    sync::Arc,
    time::Duration,
};
use crate::value_parser;
type Result<T> = result::Result<T, PackError>;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum Typ {
    U32,
    V32,
    I32,
    Z32,
    U64,
    V64,
    I64,
    Z64,
    F32,
    F64,
    Decimal,
    DateTime,
    Duration,
    Bool,
    String,
    Bytes,
    Result,
    Array,
    Null,
}
static TYPES: [Typ; 19] = [
    Typ::U32,
    Typ::V32,
    Typ::I32,
    Typ::Z32,
    Typ::U64,
    Typ::V64,
    Typ::I64,
    Typ::Z64,
    Typ::F32,
    Typ::F64,
    Typ::Decimal,
    Typ::DateTime,
    Typ::Duration,
    Typ::Bool,
    Typ::String,
    Typ::Bytes,
    Typ::Result,
    Typ::Array,
    Typ::Null,
];
impl Typ {
    pub fn parse(&self, s: &str) -> anyhow::Result<Value> {
        match self {
            Typ::U32 => Ok(Value::U32(s.parse::<u32>()?)),
            Typ::V32 => Ok(Value::V32(s.parse::<u32>()?)),
            Typ::I32 => Ok(Value::I32(s.parse::<i32>()?)),
            Typ::Z32 => Ok(Value::Z32(s.parse::<i32>()?)),
            Typ::U64 => Ok(Value::U64(s.parse::<u64>()?)),
            Typ::V64 => Ok(Value::V64(s.parse::<u64>()?)),
            Typ::I64 => Ok(Value::I64(s.parse::<i64>()?)),
            Typ::Z64 => Ok(Value::Z64(s.parse::<i64>()?)),
            Typ::F32 => Ok(Value::F32(s.parse::<f32>()?)),
            Typ::F64 => Ok(Value::F64(s.parse::<f64>()?)),
            Typ::Decimal => Ok(Value::Decimal(s.parse::<Decimal>()?)),
            Typ::DateTime => Ok(Value::DateTime(DateTime::from_str(s)?)),
            Typ::Duration => {
                let mut tmp = String::from("duration:");
                tmp.push_str(s);
                Ok(tmp.parse::<Value>()?)
            }
            Typ::Bool => match s.parse::<bool>()? {
                true => Ok(Value::True),
                false => Ok(Value::False),
            },
            Typ::String => Ok(Value::String(Chars::from(String::from(s)))),
            Typ::Bytes => {
                let mut tmp = String::from("bytes:");
                tmp.push_str(s);
                Ok(tmp.parse::<Value>()?)
            }
            Typ::Result => Ok(s.parse::<Value>()?),
            Typ::Array => Ok(s.parse::<Value>()?),
            Typ::Null => {
                if s.trim() == "null" {
                    Ok(Value::Null)
                } else {
                    bail!("expected null")
                }
            }
        }
    }
    pub fn name(&self) -> &'static str {
        match self {
            Typ::U32 => "u32",
            Typ::V32 => "v32",
            Typ::I32 => "i32",
            Typ::Z32 => "z32",
            Typ::U64 => "u64",
            Typ::I64 => "i64",
            Typ::V64 => "v64",
            Typ::Z64 => "z64",
            Typ::F32 => "f32",
            Typ::F64 => "f64",
            Typ::Decimal => "decimal",
            Typ::DateTime => "datetime",
            Typ::Duration => "duration",
            Typ::Bool => "bool",
            Typ::String => "string",
            Typ::Bytes => "bytes",
            Typ::Result => "result",
            Typ::Array => "array",
            Typ::Null => "null",
        }
    }
    pub fn get(v: &Value) -> Self {
        match v {
            Value::U32(_) => Typ::U32,
            Value::V32(_) => Typ::V32,
            Value::I32(_) => Typ::I32,
            Value::Z32(_) => Typ::Z32,
            Value::U64(_) => Typ::U64,
            Value::V64(_) => Typ::V64,
            Value::I64(_) => Typ::I64,
            Value::Z64(_) => Typ::Z64,
            Value::F32(_) => Typ::F32,
            Value::F64(_) => Typ::F64,
            Value::Decimal(_) => Typ::Decimal,
            Value::DateTime(_) => Typ::DateTime,
            Value::Duration(_) => Typ::Duration,
            Value::String(_) => Typ::String,
            Value::Bytes(_) => Typ::Bytes,
            Value::True | Value::False => Typ::Bool,
            Value::Null => Typ::Null,
            Value::Ok | Value::Error(_) => Typ::Result,
            Value::Array(_) => Typ::Array,
        }
    }
    pub fn all() -> &'static [Self] {
        &TYPES
    }
    pub fn number(&self) -> bool {
        match self {
            Typ::U32
            | Typ::V32
            | Typ::I32
            | Typ::Z32
            | Typ::U64
            | Typ::V64
            | Typ::I64
            | Typ::Z64
            | Typ::F32
            | Typ::F64
            | Typ::Decimal => true,
            Typ::DateTime
            | Typ::Duration
            | Typ::Bool
            | Typ::String
            | Typ::Bytes
            | Typ::Result
            | Typ::Array
            | Typ::Null => false,
        }
    }
    pub fn integer(&self) -> bool {
        match self {
            Typ::U32
            | Typ::V32
            | Typ::I32
            | Typ::Z32
            | Typ::U64
            | Typ::V64
            | Typ::I64
            | Typ::Z64 => true,
            Typ::F32
            | Typ::F64
            | Typ::Decimal
            | Typ::DateTime
            | Typ::Duration
            | Typ::Bool
            | Typ::String
            | Typ::Bytes
            | Typ::Result
            | Typ::Array
            | Typ::Null => false,
        }
    }
    pub fn signed_integer(&self) -> bool {
        match self {
            Typ::I32 | Typ::Z32 | Typ::I64 | Typ::Z64 => true,
            Typ::U32
            | Typ::V32
            | Typ::U64
            | Typ::V64
            | Typ::F32
            | Typ::F64
            | Typ::Decimal
            | Typ::DateTime
            | Typ::Duration
            | Typ::Bool
            | Typ::String
            | Typ::Bytes
            | Typ::Result
            | Typ::Array
            | Typ::Null => false,
        }
    }
    pub fn unsigned_integer(&self) -> bool {
        match self {
            Typ::U32 | Typ::V32 | Typ::U64 | Typ::V64 => true,
            Typ::I32
            | Typ::Z32
            | Typ::I64
            | Typ::Z64
            | Typ::F32
            | Typ::F64
            | Typ::Decimal
            | Typ::DateTime
            | Typ::Duration
            | Typ::Bool
            | Typ::String
            | Typ::Bytes
            | Typ::Result
            | Typ::Array
            | Typ::Null => false,
        }
    }
    pub fn float(&self) -> bool {
        match self {
            Typ::F32 | Typ::F64 | Typ::Decimal => true,
            Typ::U32
            | Typ::V32
            | Typ::U64
            | Typ::V64
            | Typ::I32
            | Typ::Z32
            | Typ::I64
            | Typ::Z64
            | Typ::DateTime
            | Typ::Duration
            | Typ::Bool
            | Typ::String
            | Typ::Bytes
            | Typ::Result
            | Typ::Array
            | Typ::Null => false,
        }
    }
}
impl FromStr for Typ {
    type Err = anyhow::Error;
    fn from_str(s: &str) -> result::Result<Self, Self::Err> {
        match s {
            "u32" => Ok(Typ::U32),
            "v32" => Ok(Typ::V32),
            "i32" => Ok(Typ::I32),
            "z32" => Ok(Typ::Z32),
            "u64" => Ok(Typ::U64),
            "v64" => Ok(Typ::V64),
            "i64" => Ok(Typ::I64),
            "z64" => Ok(Typ::Z64),
            "f32" => Ok(Typ::F32),
            "f64" => Ok(Typ::F64),
            "decimal" => Ok(Typ::Decimal),
            "datetime" => Ok(Typ::DateTime),
            "duration" => Ok(Typ::Duration),
            "bool" => Ok(Typ::Bool),
            "string" => Ok(Typ::String),
            "bytes" => Ok(Typ::Bytes),
            "result" => Ok(Typ::Result),
            "array" => Ok(Typ::Array),
            "null" => Ok(Typ::Null),
            s => Err(anyhow!(
                "invalid type, {}, valid types: u32, i32, u64, i64, f32, f64, bool, string, bytes, result, array, null", s))
        }
    }
}
impl fmt::Display for Typ {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.name())
    }
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", content = "value")]
pub enum Value {
    U32(u32),
    V32(u32),
    I32(i32),
    Z32(i32),
    U64(u64),
    V64(u64),
    I64(i64),
    Z64(i64),
    F32(f32),
    F64(f64),
    DateTime(DateTime<Utc>),
    Duration(Duration),
    String(Chars),
    Bytes(Bytes),
    True,
    False,
    Null,
    Ok,
    Error(Chars),
    Array(Arc<[Value]>),
    Decimal(Decimal),
}
impl Hash for Value {
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
        use std::num::FpCategory::*;
        match self {
            Value::U32(v) => {
                0u8.hash(state);
                v.hash(state)
            }
            Value::V32(v) => {
                1u8.hash(state);
                v.hash(state)
            }
            Value::I32(v) => {
                2u8.hash(state);
                v.hash(state)
            }
            Value::Z32(v) => {
                3u8.hash(state);
                v.hash(state)
            }
            Value::U64(v) => {
                4u8.hash(state);
                v.hash(state)
            }
            Value::V64(v) => {
                5u8.hash(state);
                v.hash(state)
            }
            Value::I64(v) => {
                6u8.hash(state);
                v.hash(state)
            }
            Value::Z64(v) => {
                7u8.hash(state);
                v.hash(state)
            }
            Value::F32(v) => {
                8u8.hash(state);
                let bits = v.to_bits();
                match v.classify() {
                    Nan => ((bits & 0xFF00_0000) | 0x1).hash(state), _ => bits.hash(state),
                }
            }
            Value::F64(v) => {
                9u8.hash(state);
                let bits = v.to_bits();
                match v.classify() {
                    Nan => ((bits & 0xFFE0_0000_0000_0000) | 0x1).hash(state), _ => bits.hash(state),
                }
            }
            Value::DateTime(d) => {
                10u8.hash(state);
                d.hash(state)
            }
            Value::Duration(d) => {
                11u8.hash(state);
                d.hash(state)
            }
            Value::String(c) => {
                12u8.hash(state);
                c.hash(state)
            }
            Value::Bytes(b) => {
                13u8.hash(state);
                b.hash(state)
            }
            Value::True => 14u8.hash(state),
            Value::False => 15u8.hash(state),
            Value::Null => 16u8.hash(state),
            Value::Ok => 17u8.hash(state),
            Value::Error(c) => {
                18u8.hash(state);
                c.hash(state)
            }
            Value::Array(a) => {
                19u8.hash(state);
                for v in a.iter() {
                    v.hash(state)
                }
            }
            Value::Decimal(d) => {
                20u8.hash(state);
                d.hash(state);
            }
        }
    }
}
impl PartialEq for Value {
    fn eq(&self, rhs: &Value) -> bool {
        use std::num::FpCategory::*;
        match (self, rhs) {
            (Value::U32(l) | Value::V32(l), Value::U32(r) | Value::V32(r)) => l == r,
            (Value::I32(l) | Value::Z32(l), Value::I32(r) | Value::Z32(r)) => l == r,
            (Value::U64(l) | Value::V64(l), Value::U64(r) | Value::V64(r)) => l == r,
            (Value::I64(l) | Value::Z64(l), Value::I64(r) | Value::Z64(r)) => l == r,
            (Value::F32(l), Value::F32(r)) => match (l.classify(), r.classify()) {
                (Nan, Nan) => true,
                (Zero, Zero) => true,
                (_, _) => l == r,
            },
            (Value::F64(l), Value::F64(r)) => match (l.classify(), r.classify()) {
                (Nan, Nan) => true,
                (Zero, Zero) => true,
                (_, _) => l == r,
            },
            (Value::Decimal(l), Value::Decimal(r)) => l == r,
            (Value::DateTime(l), Value::DateTime(r)) => l == r,
            (Value::Duration(l), Value::Duration(r)) => l == r,
            (Value::String(l), Value::String(r)) => l == r,
            (Value::Bytes(l), Value::Bytes(r)) => l == r,
            (Value::True, Value::True) => true,
            (Value::False, Value::False) => true,
            (Value::True | Value::False, Value::True | Value::False) => false,
            (Value::Null, Value::Null) => true,
            (Value::Ok, Value::Ok) => true,
            (Value::Error(l), Value::Error(r)) => l == r,
            (Value::Ok | Value::Error(_), Value::Ok | Value::Error(_)) => false,
            (Value::Array(l), Value::Array(r)) => l == r,
            (Value::Array(_), _) | (_, Value::Array(_)) => false,
            (l, r) if l.number() || r.number() => {
                match (l.clone().cast_to::<f64>(), r.clone().cast_to::<f64>()) {
                    (Ok(l), Ok(r)) => match (l.classify(), r.classify()) {
                        (Nan, Nan) => true,
                        (Zero, Zero) => true,
                        (_, _) => l == r,
                    },
                    (_, _) => false,
                }
            }
            (_, _) => false,
        }
    }
}
impl Eq for Value {}
impl PartialOrd for Value {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        use std::num::FpCategory::*;
        match (self, other) {
            (Value::U32(l) | Value::V32(l), Value::U32(r) | Value::V32(r)) => {
                l.partial_cmp(r)
            }
            (Value::I32(l) | Value::Z32(l), Value::I32(r) | Value::Z32(r)) => {
                l.partial_cmp(r)
            }
            (Value::U64(l) | Value::V64(l), Value::U64(r) | Value::V64(r)) => {
                l.partial_cmp(r)
            }
            (Value::I64(l) | Value::Z64(l), Value::I64(r) | Value::Z64(r)) => {
                l.partial_cmp(r)
            }
            (Value::F32(l), Value::F32(r)) => match (l.classify(), r.classify()) {
                (Nan, Nan) => Some(Ordering::Equal),
                (Nan, _) => Some(Ordering::Less),
                (_, Nan) => Some(Ordering::Greater),
                (_, _) => l.partial_cmp(r),
            },
            (Value::F64(l), Value::F64(r)) => match (l.classify(), r.classify()) {
                (Nan, Nan) => Some(Ordering::Equal),
                (Nan, _) => Some(Ordering::Less),
                (_, Nan) => Some(Ordering::Greater),
                (_, _) => l.partial_cmp(r),
            },
            (Value::Decimal(l), Value::Decimal(r)) => l.partial_cmp(r),
            (Value::DateTime(l), Value::DateTime(r)) => l.partial_cmp(r),
            (Value::Duration(l), Value::Duration(r)) => l.partial_cmp(r),
            (Value::String(l), Value::String(r)) => l.partial_cmp(r),
            (Value::Bytes(l), Value::Bytes(r)) => l.partial_cmp(r),
            (Value::True, Value::True) => Some(Ordering::Equal),
            (Value::False, Value::False) => Some(Ordering::Equal),
            (Value::False, Value::True) => Some(Ordering::Less),
            (Value::True, Value::False) => Some(Ordering::Greater),
            (Value::Null, Value::Null) => Some(Ordering::Equal),
            (Value::Null, _) => Some(Ordering::Less),
            (_, Value::Null) => Some(Ordering::Greater),
            (Value::Ok, Value::Ok) => Some(Ordering::Equal),
            (Value::Error(l), Value::Error(r)) => l.partial_cmp(r),
            (Value::Error(_), _) => Some(Ordering::Less),
            (_, Value::Error(_)) => Some(Ordering::Greater),
            (Value::Array(l), Value::Array(r)) => l.partial_cmp(r),
            (Value::Array(_), _) => Some(Ordering::Less),
            (_, Value::Array(_)) => Some(Ordering::Greater),
            (l, r) if l.number() || r.number() => {
                match (l.clone().cast_to::<f64>(), r.clone().cast_to::<f64>()) {
                    (Ok(l), Ok(r)) => match (l.classify(), r.classify()) {
                        (Nan, Nan) => Some(Ordering::Equal),
                        (Nan, _) => Some(Ordering::Less),
                        (_, Nan) => Some(Ordering::Greater),
                        (_, _) => l.partial_cmp(&r),
                    },
                    (_, _) => format!("{}", l).partial_cmp(&format!("{}", r)),
                }
            }
            (l, r) => format!("{}", l).partial_cmp(&format!("{}", r)),
        }
    }
}
impl Ord for Value {
    fn cmp(&self, other: &Self) -> Ordering {
        self.partial_cmp(other).unwrap()
    }
}
impl fmt::Display for Value {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.fmt_ext(f, &value_parser::VAL_ESC, true)
    }
}
impl FromStr for Value {
    type Err = anyhow::Error;
    fn from_str(s: &str) -> result::Result<Self, Self::Err> {
        value_parser::parse_value(s)
    }
}
macro_rules! apply_op {
    ($self:expr, $rhs:expr, $id:expr, $op:tt, $($pat:pat => $blk:block),+) => {
        match ($self, $rhs) {
            (Value::U32(l) | Value::V32(l), Value::U32(r) | Value::V32(r)) => {
                Value::U32((Wrapping(l) $op Wrapping(r)).0)
            }
            (Value::I32(l) | Value::Z32(l), Value::I32(r) | Value::Z32(r)) => {
                Value::I32((Wrapping(l) $op Wrapping(r)).0)
            }
            (Value::U64(l) | Value::V64(l), Value::U64(r) | Value::V64(r)) => {
                Value::U64((Wrapping(l) $op Wrapping(r)).0)
            }
            (Value::I64(l) | Value::Z64(l), Value::I64(r) | Value::Z64(r)) => {
                Value::I64((Wrapping(l) $op Wrapping(r)).0)
            }
            (Value::F32(l), Value::F32(r)) => Value::F32(l $op r),
            (Value::F64(l), Value::F64(r)) => Value::F64(l $op r),
            (Value::Decimal(l), Value::Decimal(r)) => Value::Decimal(l $op r),
            (Value::U32(l) | Value::V32(l), Value::U64(r) | Value::V64(r)) => {
                Value::U64((Wrapping(l as u64) $op Wrapping(r)).0)
            }
            (Value::U64(l) | Value::V64(l), Value::U32(r) | Value::V32(r)) => {
                Value::U64((Wrapping(l) $op Wrapping(r as u64)).0)
            }
            (Value::I32(l) | Value::Z32(l), Value::I64(r) | Value::Z64(r)) => {
                Value::I64((Wrapping(l as i64) $op Wrapping(r)).0)
            }
            (Value::I32(l) | Value::Z32(l), Value::U32(r) | Value::V32(r)) => {
                Value::I64((Wrapping(l as i64) $op Wrapping(r as i64)).0)
            }
            (Value::U32(l) | Value::V32(l), Value::I32(r) | Value::Z32(r)) => {
                Value::I64((Wrapping(l as i64) $op Wrapping(r as i64)).0)
            }
            (Value::I64(l) | Value::Z64(l), Value::I32(r) | Value::Z32(r)) => {
                Value::I64((Wrapping(l) $op Wrapping(r as i64)).0)
            }
            (Value::I64(l) | Value::Z64(l), Value::U32(r) | Value::V32(r)) => {
                Value::I64((Wrapping(l) $op Wrapping(r as i64)).0)
            }
            (Value::U32(l) | Value::V32(l), Value::I64(r) | Value::Z64(r)) => {
                Value::I64((Wrapping(l as i64) $op Wrapping(r)).0)
            }
            (Value::I64(l) | Value::Z64(l), Value::U64(r) | Value::V64(r)) => {
                Value::I64((Wrapping(l) $op Wrapping(r as i64)).0)
            }
            (Value::U64(l) | Value::V64(l), Value::I64(r) | Value::Z64(r)) => {
                Value::I64((Wrapping(l as i64) $op Wrapping(r)).0)
            }
            (Value::U64(l) | Value::V64(l), Value::I32(r) | Value::Z32(r)) => {
                Value::I64((Wrapping(l as i64) $op Wrapping(r as i64)).0)
            }
            (Value::I32(l) | Value::Z32(l), Value::U64(r) | Value::V64(r)) => {
                Value::I64((Wrapping(l as i64) $op Wrapping(r as i64)).0)
            }
            (Value::F32(l), Value::U32(r) | Value::V32(r)) => Value::F32(l $op r as f32),
            (Value::U32(l) | Value::V32(l), Value::F32(r)) => Value::F32(l as f32 $op r),
            (Value::F32(l), Value::U64(r) | Value::V64(r)) => Value::F32(l $op r as f32),
            (Value::U64(l) | Value::V64(l), Value::F32(r)) => Value::F32(l as f32 $op r),
            (Value::F32(l), Value::I32(r) | Value::Z32(r)) => Value::F32(l $op r  as f32),
            (Value::I32(l) | Value::Z32(l), Value::F32(r)) => Value::F32(l as f32 $op r),
            (Value::F32(l), Value::I64(r) | Value::Z64(r)) => Value::F32(l $op r as f32),
            (Value::I64(l) | Value::Z64(l), Value::F32(r)) => Value::F32(l as f32 $op r),
            (Value::F32(l), Value::F64(r)) => Value::F64(l as f64 $op r),
            (Value::F64(l), Value::U32(r) | Value::V32(r)) => Value::F64(l $op r as f64),
            (Value::U32(l) | Value::V32(l), Value::F64(r)) => Value::F64(l as f64 $op r),
            (Value::F64(l), Value::U64(r) | Value::V64(r)) => Value::F64(l $op r as f64),
            (Value::U64(l) | Value::V64(l), Value::F64(r)) => Value::F64(l as f64 $op r),
            (Value::F64(l), Value::I32(r) | Value::Z32(r)) => Value::F64(l $op r as f64),
            (Value::I32(l) | Value::Z32(l), Value::F64(r)) => Value::F64(l as f64 $op r),
            (Value::F64(l), Value::I64(r) | Value::Z64(r)) => Value::F64(l $op r as f64),
            (Value::I64(l) | Value::Z64(l), Value::F64(r)) => Value::F64(l as f64 $op r),
            (Value::F64(l), Value::F32(r)) => Value::F64(l $op r as f64),
            (Value::Decimal(l), Value::U32(r) | Value::V32(r)) =>
                Value::Decimal(l $op Decimal::from(r)),
            (Value::U32(l) | Value::V32(l), Value::Decimal(r)) =>
                Value::Decimal(Decimal::from(l) $op r),
            (Value::Decimal(l), Value::U64(r) | Value::V64(r)) =>
                Value::Decimal(l $op Decimal::from(r)),
            (Value::U64(l) | Value::V64(l), Value::Decimal(r)) =>
                Value::Decimal(Decimal::from(l) $op r),
            (Value::Decimal(l), Value::I32(r) | Value::Z32(r)) =>
                Value::Decimal(l $op Decimal::from(r)),
            (Value::I32(l) | Value::Z32(l), Value::Decimal(r)) =>
                Value::Decimal(Decimal::from(l) $op r),
            (Value::Decimal(l), Value::I64(r) | Value::Z64(r)) =>
                Value::Decimal(l $op Decimal::from(r)),
            (Value::I64(l) | Value::Z64(l), Value::Decimal(r)) =>
                Value::Decimal(Decimal::from(l) $op r),
            (Value::Decimal(l), Value::F32(r)) => match Decimal::try_from(r) {
                Ok(r) => Value::Decimal(l $op r),
                Err(_) => {
                    let e = format!("can't parse {} as a decimal", r);
                    Value::Error(Chars::from(e))
                },
            },
            (Value::F32(l), Value::Decimal(r)) => match Decimal::try_from(l) {
                Ok(l) => Value::Decimal(l $op r),
                Err(_) => {
                    let e = format!("can't parse {} as a decimal", l);
                    Value::Error(Chars::from(e))
                },
            },
            (Value::Decimal(l), Value::F64(r)) => match Decimal::try_from(r) {
                Ok(r) => Value::Decimal(l $op r),
                Err(_) => {
                    let e = format!("can't parse {} as a decimal", r);
                    Value::Error(Chars::from(e))
                },
            },
            (Value::F64(l), Value::Decimal(r)) => match Decimal::try_from(l) {
                Ok(l) => Value::Decimal(l $op r),
                Err(_) => {
                    let e = format!("can't parse {} as a decimal", l);
                    Value::Error(Chars::from(e))
                },
            },
            (Value::String(s), n) => match s.parse::<Value>() {
                Err(e) => Value::Error(Chars::from(format!("{}", e))),
                Ok(s) => s $op n,
            }
            (n, Value::String(s)) => match s.parse::<Value>() {
                Err(e) => Value::Error(Chars::from(format!("{}", e))),
                Ok(s) => n $op s,
            },
            (Value::Array(e0), Value::Array(e1)) => {
                let (e0, e1) = if e0.len() < e1.len() { (e0, e1) } else { (e1, e0) };
                let iter = e0
                    .iter()
                    .cloned()
                    .chain(iter::repeat(Value::F64($id)))
                    .zip(e1.iter().cloned());
                Value::Array(iter.map(|(v0, v1)| v0 $op v1).collect())
            }
            (l @ Value::Array(_), n) => {
                match n.cast(Typ::Array) {
                    None => Value::Error(Chars::from("can't add to array")),
                    Some(r) => l $op r,
                }
            }
            (n, r @ Value::Array(_)) => {
                match n.cast(Typ::Array) {
                    None => Value::Error(Chars::from("can't add to array")),
                    Some(l) => l $op r,
                }
            }
            (Value::Bytes(_), _) | (_, Value::Bytes(_)) => {
                Value::Error(Chars::from("can't add bytes"))
            }
            (Value::Null, _) | (_, Value::Null) => {
                Value::Error(Chars::from("can't add null"))
            }
            (Value::Ok, _)
            | (_, Value::Ok)
            | (Value::Error(_), _)
            | (_, Value::Error(_)) => Value::Error(Chars::from("can't add result types")),
            (Value::True, n) => Value::U32(1) $op n,
            (n, Value::True) => n $op Value::U32(1),
            (Value::False, n) => Value::U32(0) $op n,
            (n, Value::False) => n $op Value::U32(0),
            $($pat => $blk),+
        }
    }
}
impl Add for Value {
    type Output = Value;
    fn add(self, rhs: Self) -> Self {
        apply_op!(
            self, rhs, 0., +,
            (Value::DateTime(dt), Value::Duration(d))
                | (Value::Duration(d), Value::DateTime(dt)) => {
                    match chrono::Duration::from_std(d) {
                        Ok(d) => Value::DateTime(dt + d),
                        Err(e) => Value::Error(Chars::from(format!("{}", e))),
                    }
                },
            (Value::Duration(d0), Value::Duration(d1)) => { Value::Duration(d0 + d1) },
            (Value::Duration(_), _)
                | (_, Value::Duration(_))
                | (_, Value::DateTime(_))
                | (Value::DateTime(_), _) => {
                    Value::Error(Chars::from("can't add to datetime/duration"))
                }
        )
    }
}
impl Sub for Value {
    type Output = Value;
    fn sub(self, rhs: Self) -> Self {
        apply_op!(
            self, rhs, 0., -,
            (Value::DateTime(dt), Value::Duration(d))
                | (Value::Duration(d), Value::DateTime(dt)) => {
                    match chrono::Duration::from_std(d) {
                        Ok(d) => Value::DateTime(dt - d),
                        Err(e) => Value::Error(Chars::from(format!("{}", e))),
                    }
                },
            (Value::Duration(d0), Value::Duration(d1)) => { Value::Duration(d0 - d1) },
            (Value::Duration(_), _)
                | (_, Value::Duration(_))
                | (_, Value::DateTime(_))
                | (Value::DateTime(_), _) => {
                    Value::Error(Chars::from("can't add to datetime/duration"))
                }
        )
    }
}
impl Mul for Value {
    type Output = Value;
    fn mul(self, rhs: Self) -> Self {
        apply_op!(
            self, rhs, 1., *,
            (Value::Duration(_), _)
                | (_, Value::Duration(_))
                | (_, Value::DateTime(_))
                | (Value::DateTime(_), _) => {
                    Value::Error(Chars::from("can't add to datetime/duration"))
                }
        )
    }
}
impl Div for Value {
    type Output = Value;
    fn div(self, rhs: Self) -> Self {
        let res = catch_unwind(AssertUnwindSafe(|| {
            apply_op!(
                self, rhs, 1., /,
                (Value::Duration(d), Value::U32(s)) => { Value::Duration(d / s) },
                (Value::Duration(d), Value::V32(s)) => { Value::Duration(d / s) },
                (Value::Duration(d), Value::F32(s)) => { Value::Duration(d.div_f32(s)) },
                (Value::Duration(d), Value::F64(s)) => { Value::Duration(d.div_f64(s)) },
                (Value::Duration(_), _)
                    | (_, Value::Duration(_))
                    | (_, Value::DateTime(_))
                    | (Value::DateTime(_), _) => {
                        Value::Error(Chars::from("can't add to datetime/duration"))
                    }
            )
        }));
        match res {
            Ok(r) => r,
            Err(_) => Value::Error(Chars::from("can't divide by zero")),
        }
    }
}
impl Not for Value {
    type Output = Value;
    fn not(self) -> Self {
        match self {
            Value::U32(v) => {
                Value::Error(Chars::from(format!("can't apply not to U32({})", v)))
            }
            Value::V32(v) => {
                Value::Error(Chars::from(format!("can't apply not to V32({})", v)))
            }
            Value::I32(v) => {
                Value::Error(Chars::from(format!("can't apply not to I32({})", v)))
            }
            Value::Z32(v) => {
                Value::Error(Chars::from(format!("can't apply not to Z32({})", v)))
            }
            Value::U64(v) => {
                Value::Error(Chars::from(format!("can't apply not to U64({})", v)))
            }
            Value::V64(v) => {
                Value::Error(Chars::from(format!("can't apply not to V64({})", v)))
            }
            Value::I64(v) => {
                Value::Error(Chars::from(format!("can't apply not to I64({})", v)))
            }
            Value::Z64(v) => {
                Value::Error(Chars::from(format!("can't apply not to Z64({})", v)))
            }
            Value::F32(v) => {
                Value::Error(Chars::from(format!("can't apply not to F32({})", v)))
            }
            Value::F64(v) => {
                Value::Error(Chars::from(format!("can't apply not to F64({})", v)))
            }
            Value::Decimal(v) => {
                Value::Error(Chars::from(format!("can't apply not to Decimal({})", v)))
            }
            Value::DateTime(v) => {
                Value::Error(Chars::from(format!("can't apply not to DateTime({})", v)))
            }
            Value::Duration(v) => Value::Error(Chars::from(format!(
                "can't apply not to Duration({}s)",
                v.as_secs_f64()
            ))),
            Value::String(v) => {
                Value::Error(Chars::from(format!("can't apply not to String({})", v)))
            }
            Value::Bytes(_) => {
                Value::Error(Chars::from(format!("can't apply not to Bytes")))
            }
            Value::True => Value::False,
            Value::False => Value::True,
            Value::Null => Value::Null,
            Value::Ok => Value::Error(Chars::from(format!("can't apply not to Ok"))),
            Value::Error(v) => {
                Value::Error(Chars::from(format!("can't apply not to Error({})", v)))
            }
            Value::Array(elts) => {
                Value::Array(elts.iter().cloned().map(|v| !v).collect())
            }
        }
    }
}
impl Pack for Value {
    fn encoded_len(&self) -> usize {
        1 + match self {
            Value::U32(_) => mem::size_of::<u32>(),
            Value::V32(v) => pack::varint_len(*v as u64),
            Value::I32(_) => mem::size_of::<i32>(),
            Value::Z32(v) => pack::varint_len(pack::i32_zz(*v) as u64),
            Value::U64(_) => mem::size_of::<u64>(),
            Value::V64(v) => pack::varint_len(*v),
            Value::I64(_) => mem::size_of::<i64>(),
            Value::Z64(v) => pack::varint_len(pack::i64_zz(*v) as u64),
            Value::F32(_) => mem::size_of::<f32>(),
            Value::F64(_) => mem::size_of::<f64>(),
            Value::DateTime(_) => 12,
            Value::Duration(_) => 12,
            Value::String(c) => <Chars as Pack>::encoded_len(c),
            Value::Bytes(b) => <Bytes as Pack>::encoded_len(b),
            Value::True | Value::False | Value::Null => 0,
            Value::Ok => 0,
            Value::Error(c) => <Chars as Pack>::encoded_len(c),
            Value::Array(elts) => {
                pack::varint_len(elts.len() as u64)
                    + elts.iter().fold(0, |sum, v| sum + Pack::encoded_len(v))
            }
            Value::Decimal(d) => <Decimal as Pack>::encoded_len(d),
        }
    }
    fn encode(&self, buf: &mut impl BufMut) -> Result<()> {
        match self {
            Value::U32(i) => {
                buf.put_u8(0);
                Ok(buf.put_u32(*i))
            }
            Value::V32(i) => {
                buf.put_u8(1);
                Ok(pack::encode_varint(*i as u64, buf))
            }
            Value::I32(i) => {
                buf.put_u8(2);
                Ok(buf.put_i32(*i))
            }
            Value::Z32(i) => {
                buf.put_u8(3);
                Ok(pack::encode_varint(pack::i32_zz(*i) as u64, buf))
            }
            Value::U64(i) => {
                buf.put_u8(4);
                Ok(buf.put_u64(*i))
            }
            Value::V64(i) => {
                buf.put_u8(5);
                Ok(pack::encode_varint(*i, buf))
            }
            Value::I64(i) => {
                buf.put_u8(6);
                Ok(buf.put_i64(*i))
            }
            Value::Z64(i) => {
                buf.put_u8(7);
                Ok(pack::encode_varint(pack::i64_zz(*i), buf))
            }
            Value::F32(i) => {
                buf.put_u8(8);
                Ok(buf.put_f32(*i))
            }
            Value::F64(i) => {
                buf.put_u8(9);
                Ok(buf.put_f64(*i))
            }
            Value::DateTime(dt) => {
                buf.put_u8(10);
                Ok(<DateTime<Utc> as Pack>::encode(dt, buf)?)
            }
            Value::Duration(d) => {
                buf.put_u8(11);
                Ok(<Duration as Pack>::encode(d, buf)?)
            }
            Value::String(s) => {
                buf.put_u8(12);
                <Chars as Pack>::encode(s, buf)
            }
            Value::Bytes(b) => {
                buf.put_u8(13);
                <Bytes as Pack>::encode(b, buf)
            }
            Value::True => Ok(buf.put_u8(14)),
            Value::False => Ok(buf.put_u8(15)),
            Value::Null => Ok(buf.put_u8(16)),
            Value::Ok => Ok(buf.put_u8(17)),
            Value::Error(e) => {
                buf.put_u8(18);
                <Chars as Pack>::encode(e, buf)
            }
            Value::Array(elts) => {
                buf.put_u8(19);
                pack::encode_varint(elts.len() as u64, buf);
                for elt in &**elts {
                    <Value as Pack>::encode(elt, buf)?
                }
                Ok(())
            }
            Value::Decimal(d) => {
                buf.put_u8(20);
                <Decimal as Pack>::encode(d, buf)
            }
        }
    }
    fn decode(buf: &mut impl Buf) -> Result<Self> {
        match <u8 as Pack>::decode(buf)? {
            0 => Ok(Value::U32(Pack::decode(buf)?)),
            1 => Ok(Value::V32(pack::decode_varint(buf)? as u32)),
            2 => Ok(Value::I32(Pack::decode(buf)?)),
            3 => Ok(Value::Z32(pack::i32_uzz(pack::decode_varint(buf)? as u32))),
            4 => Ok(Value::U64(Pack::decode(buf)?)),
            5 => Ok(Value::V64(pack::decode_varint(buf)?)),
            6 => Ok(Value::I64(Pack::decode(buf)?)),
            7 => Ok(Value::Z64(pack::i64_uzz(pack::decode_varint(buf)?))),
            8 => Ok(Value::F32(Pack::decode(buf)?)),
            9 => Ok(Value::F64(Pack::decode(buf)?)),
            10 => Ok(Value::DateTime(Pack::decode(buf)?)),
            11 => Ok(Value::Duration(Pack::decode(buf)?)),
            12 => Ok(Value::String(Pack::decode(buf)?)),
            13 => Ok(Value::Bytes(Pack::decode(buf)?)),
            14 => Ok(Value::True),
            15 => Ok(Value::False),
            16 => Ok(Value::Null),
            17 => Ok(Value::Ok),
            18 => Ok(Value::Error(<Chars as Pack>::decode(buf)?)),
            19 => {
                let len = pack::decode_varint(buf)? as usize;
                let mut elts = Vec::with_capacity(len);
                while elts.len() < len {
                    elts.push(<Value as Pack>::decode(buf)?);
                }
                Ok(Value::Array(Arc::from(elts)))
            }
            20 => Ok(Value::Decimal(<Decimal as Pack>::decode(buf)?)),
            _ => Err(PackError::UnknownTag),
        }
    }
}
pub trait FromValue {
    fn from_value(v: Value) -> Res<Self>
    where
        Self: Sized;
    fn get(v: Value) -> Option<Self>
    where
        Self: Sized,
    {
        FromValue::from_value(v).ok()
    }
}
impl Value {
    pub fn to_string_naked(&self) -> String {
        struct WVal<'a>(&'a Value);
        impl<'a> fmt::Display for WVal<'a> {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                self.0.fmt_naked(f)
            }
        }
        format!("{}", WVal(self))
    }
    pub fn fmt_naked(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Value::U32(v) | Value::V32(v) => write!(f, "{}", v),
            Value::I32(v) | Value::Z32(v) => write!(f, "{}", v),
            Value::U64(v) | Value::V64(v) => write!(f, "{}", v),
            Value::I64(v) | Value::Z64(v) => write!(f, "{}", v),
            Value::F32(v) => write!(f, "{}", v),
            Value::F64(v) => write!(f, "{}", v),
            Value::Decimal(v) => write!(f, "{}", v),
            Value::DateTime(v) => write!(f, "{}", v),
            Value::Duration(v) => {
                let v = v.as_secs_f64();
                if v.fract() == 0. {
                    write!(f, "{}.s", v)
                } else {
                    write!(f, "{}s", v)
                }
            }
            Value::String(s) => write!(f, "{}", s),
            Value::Bytes(b) => write!(f, "{}", BASE64.encode(&*b)),
            Value::True => write!(f, "true"),
            Value::False => write!(f, "false"),
            Value::Null => write!(f, "null"),
            Value::Ok => write!(f, "ok"),
            v @ Value::Error(_) => write!(f, "{}", v),
            v @ Value::Array(_) => write!(f, "{}", v),
        }
    }
    pub fn fmt_notyp(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.fmt_ext(f, &value_parser::VAL_ESC, false)
    }
    pub fn fmt_ext(
        &self,
        f: &mut fmt::Formatter<'_>,
        esc: &[char],
        types: bool,
    ) -> fmt::Result {
        match self {
            Value::U32(v) => {
                if types {
                    write!(f, "u32:{}", v)
                } else {
                    write!(f, "{}", v)
                }
            }
            Value::V32(v) => {
                if types {
                    write!(f, "v32:{}", v)
                } else {
                    write!(f, "{}", v)
                }
            }
            Value::I32(v) => {
                if types {
                    write!(f, "i32:{}", v)
                } else {
                    write!(f, "{}", v)
                }
            }
            Value::Z32(v) => {
                if types {
                    write!(f, "z32:{}", v)
                } else {
                    write!(f, "{}", v)
                }
            }
            Value::U64(v) => {
                if types {
                    write!(f, "u64:{}", v)
                } else {
                    write!(f, "{}", v)
                }
            }
            Value::V64(v) => {
                if types {
                    write!(f, "v64:{}", v)
                } else {
                    write!(f, "{}", v)
                }
            }
            Value::I64(v) => {
                if types {
                    write!(f, "i64:{}", v)
                } else {
                    write!(f, "{}", v)
                }
            }
            Value::Z64(v) => {
                if types {
                    write!(f, "z64:{}", v)
                } else {
                    write!(f, "{}", v)
                }
            }
            Value::F32(v) => {
                let pfx = if types { "f32:" } else { "" };
                if v.fract() == 0. {
                    write!(f, "{}{}.", pfx, v)
                } else {
                    write!(f, "{}{}", pfx, v)
                }
            }
            Value::F64(v) => {
                let pfx = if types { "f64:" } else { "" };
                if v.fract() == 0. {
                    write!(f, "{}{}.", pfx, v)
                } else {
                    write!(f, "{}{}", pfx, v)
                }
            }
            Value::Decimal(v) => {
                if types {
                    write!(f, "decimal:{}", v)
                } else {
                    write!(f, "{}", v)
                }
            }
            Value::DateTime(v) => {
                if types {
                    write!(f, r#"datetime:"{}""#, v)
                } else {
                    write!(f, r#""{}""#, v)
                }
            }
            Value::Duration(v) => {
                let pfx = if types { "duration:" } else { "" };
                let v = v.as_secs_f64();
                if v.fract() == 0. {
                    write!(f, r#"{}{}.s"#, pfx, v)
                } else {
                    write!(f, r#"{}{}s"#, pfx, v)
                }
            }
            Value::String(s) => {
                write!(f, r#""{}""#, utils::escape(&*s, '\\', esc))
            }
            Value::Bytes(b) => {
                let pfx = if types { "bytes:" } else { "" };
                write!(f, "{}{}", pfx, BASE64.encode(&*b))
            }
            Value::True => write!(f, "true"),
            Value::False => write!(f, "false"),
            Value::Null => write!(f, "null"),
            Value::Ok => write!(f, "ok"),
            Value::Error(v) => {
                write!(f, r#"error:"{}""#, utils::escape(&*v, '\\', esc))
            }
            Value::Array(elts) => {
                write!(f, "[")?;
                for (i, v) in elts.iter().enumerate() {
                    if i < elts.len() - 1 {
                        v.fmt_ext(f, esc, types)?;
                        write!(f, ", ")?
                    } else {
                        v.fmt_ext(f, esc, types)?
                    }
                }
                write!(f, "]")
            }
        }
    }
    pub fn cast(self, typ: Typ) -> Option<Value> {
        macro_rules! cast_number {
            ($v:expr, $typ:expr) => {
                match typ {
                    Typ::U32 => Some(Value::U32($v as u32)),
                    Typ::V32 => Some(Value::V32($v as u32)),
                    Typ::I32 => Some(Value::I32($v as i32)),
                    Typ::Z32 => Some(Value::Z32($v as i32)),
                    Typ::U64 => Some(Value::U64($v as u64)),
                    Typ::V64 => Some(Value::V64($v as u64)),
                    Typ::I64 => Some(Value::I64($v as i64)),
                    Typ::Z64 => Some(Value::Z64($v as i64)),
                    Typ::F32 => Some(Value::F32($v as f32)),
                    Typ::F64 => Some(Value::F64($v as f64)),
                    Typ::Decimal => match Decimal::try_from($v) {
                        Ok(d) => Some(Value::Decimal(d)),
                        Err(_) => None,
                    },
                    Typ::DateTime => Some(Value::DateTime(Utc.from_utc_datetime(
                        &NaiveDateTime::from_timestamp_opt($v as i64, 0)?,
                    ))),
                    Typ::Duration => {
                        Some(Value::Duration(Duration::from_secs($v as u64)))
                    }
                    Typ::Bool => {
                        Some(if $v as i64 > 0 { Value::True } else { Value::False })
                    }
                    Typ::String => Some(Value::String(Chars::from(format!("{}", self)))),
                    Typ::Bytes => None,
                    Typ::Result => Some(Value::Ok),
                    Typ::Array => {
                        Some(Value::Array(Arc::from(Vec::from([self.clone()]))))
                    }
                    Typ::Null => Some(Value::Null),
                }
            };
        }
        match self {
            Value::String(s) if typ != Typ::String => {
                s.parse::<Value>().ok().and_then(|v| v.cast(typ))
            }
            v @ Value::String(_) => Some(v),
            v if typ == Typ::String => Some(Value::String(Chars::from(format!("{}", v)))),
            Value::Array(elts) if typ != Typ::Array => {
                elts.first().and_then(|v| v.clone().cast(typ))
            }
            v @ Value::Array(_) => Some(v),
            Value::U32(v) | Value::V32(v) => cast_number!(v, typ),
            Value::I32(v) | Value::Z32(v) => cast_number!(v, typ),
            Value::U64(v) | Value::V64(v) => cast_number!(v, typ),
            Value::I64(v) | Value::Z64(v) => cast_number!(v, typ),
            Value::F32(v) => cast_number!(v, typ),
            Value::F64(v) => cast_number!(v, typ),
            Value::Decimal(v) => match typ {
                Typ::Decimal => Some(Value::Decimal(v)),
                Typ::U32 => v.try_into().ok().map(Value::U32),
                Typ::V32 => v.try_into().ok().map(Value::V32),
                Typ::I32 => v.try_into().ok().map(Value::I32),
                Typ::Z32 => v.try_into().ok().map(Value::Z32),
                Typ::U64 => v.try_into().ok().map(Value::U64),
                Typ::V64 => v.try_into().ok().map(Value::V64),
                Typ::I64 => v.try_into().ok().map(Value::I64),
                Typ::Z64 => v.try_into().ok().map(Value::Z64),
                Typ::F32 => v.try_into().ok().map(Value::F32),
                Typ::F64 => v.try_into().ok().map(Value::F64),
                Typ::String => Some(Value::String(Chars::from(format!("{}", v)))),
                Typ::Bool
                | Typ::Array
                | Typ::Bytes
                | Typ::DateTime
                | Typ::Duration
                | Typ::Null
                | Typ::Result => None,
            },
            Value::DateTime(v) => match typ {
                Typ::U32 | Typ::V32 => {
                    let ts = v.timestamp();
                    if ts < 0 && ts > u32::MAX as i64 {
                        None
                    } else {
                        if typ == Typ::U32 {
                            Some(Value::U32(ts as u32))
                        } else {
                            Some(Value::V32(ts as u32))
                        }
                    }
                }
                Typ::I32 | Typ::Z32 => {
                    let ts = v.timestamp();
                    if ts < i32::MIN as i64 || ts > i32::MAX as i64 {
                        None
                    } else {
                        if typ == Typ::I32 {
                            Some(Value::I32(ts as i32))
                        } else {
                            Some(Value::Z32(ts as i32))
                        }
                    }
                }
                Typ::U64 | Typ::V64 => {
                    let ts = v.timestamp();
                    if ts < 0 {
                        None
                    } else {
                        if typ == Typ::U64 {
                            Some(Value::U64(ts as u64))
                        } else {
                            Some(Value::V64(ts as u64))
                        }
                    }
                }
                Typ::I64 => Some(Value::I64(v.timestamp())),
                Typ::Z64 => Some(Value::Z64(v.timestamp())),
                Typ::F32 | Typ::F64 => {
                    let dur = v.timestamp() as f64;
                    let dur = dur + (v.timestamp_nanos_opt().expect("cannot represent as timestamp with ns precision") / 1_000_000_000) as f64;
                    if typ == Typ::F32 {
                        Some(Value::F32(dur as f32))
                    } else {
                        Some(Value::F64(dur))
                    }
                }
                Typ::DateTime => Some(Value::DateTime(v)),
                Typ::Decimal => None,
                Typ::Duration => None,
                Typ::Bool => None,
                Typ::Bytes => None,
                Typ::Result => Some(Value::Ok),
                Typ::Array => Some(Value::Array(Arc::from(Vec::from([self])))),
                Typ::Null => Some(Value::Null),
                Typ::String => unreachable!(),
            },
            Value::Duration(d) => match typ {
                Typ::U32 => Some(Value::U32(d.as_secs() as u32)),
                Typ::V32 => Some(Value::V32(d.as_secs() as u32)),
                Typ::I32 => Some(Value::I32(d.as_secs() as i32)),
                Typ::Z32 => Some(Value::Z32(d.as_secs() as i32)),
                Typ::U64 => Some(Value::U64(d.as_secs() as u64)),
                Typ::V64 => Some(Value::V64(d.as_secs() as u64)),
                Typ::I64 => Some(Value::I64(d.as_secs() as i64)),
                Typ::Z64 => Some(Value::Z64(d.as_secs() as i64)),
                Typ::F32 => Some(Value::F32(d.as_secs_f32())),
                Typ::F64 => Some(Value::F64(d.as_secs_f64())),
                Typ::Decimal => None,
                Typ::DateTime => None,
                Typ::Duration => Some(Value::Duration(d)),
                Typ::Bool => None,
                Typ::Bytes => None,
                Typ::Result => Some(Value::Ok),
                Typ::Array => Some(Value::Array(Arc::from(Vec::from([self])))),
                Typ::Null => Some(Value::Null),
                Typ::String => unreachable!(),
            },
            Value::True | Value::False => {
                let b = self == Value::True;
                match typ {
                    Typ::U32 => Some(Value::U32(b as u32)),
                    Typ::V32 => Some(Value::V32(b as u32)),
                    Typ::I32 => Some(Value::I32(b as i32)),
                    Typ::Z32 => Some(Value::Z32(b as i32)),
                    Typ::U64 => Some(Value::U64(b as u64)),
                    Typ::V64 => Some(Value::V64(b as u64)),
                    Typ::I64 => Some(Value::I64(b as i64)),
                    Typ::Z64 => Some(Value::Z64(b as i64)),
                    Typ::F32 => Some(Value::F32(b as u32 as f32)),
                    Typ::F64 => Some(Value::F64(b as u64 as f64)),
                    Typ::Decimal => None,
                    Typ::DateTime => None,
                    Typ::Duration => None,
                    Typ::Bool => Some(self),
                    Typ::Bytes => None,
                    Typ::Result => Some(Value::Ok),
                    Typ::Array => Some(Value::Array(Arc::from(Vec::from([self])))),
                    Typ::Null => Some(Value::Null),
                    Typ::String => unreachable!(),
                }
            }
            Value::Bytes(_) if typ == Typ::Bytes => Some(self),
            Value::Bytes(_) => None,
            Value::Ok => Value::True.cast(typ),
            Value::Error(_) => Value::False.cast(typ),
            Value::Null if typ == Typ::Null => Some(self),
            Value::Null => None,
        }
    }
    pub fn cast_to<T: FromValue + Sized>(self) -> Res<T> {
        <T as FromValue>::from_value(self)
    }
    pub fn get_as<T: FromValue + Sized>(self) -> Option<T> {
        <T as FromValue>::get(self)
    }
    pub fn err<T: std::error::Error>(e: T) -> Value {
        Value::Error(Chars::from(e.to_string()))
    }
    pub fn number(&self) -> bool {
        match self {
            Value::U32(_)
            | Value::V32(_)
            | Value::I32(_)
            | Value::Z32(_)
            | Value::U64(_)
            | Value::V64(_)
            | Value::I64(_)
            | Value::Z64(_)
            | Value::F32(_)
            | Value::F64(_)
            | Value::Decimal(_) => true,
            Value::DateTime(_)
            | Value::Duration(_)
            | Value::String(_)
            | Value::Bytes(_)
            | Value::True
            | Value::False
            | Value::Null
            | Value::Ok
            | Value::Error(_)
            | Value::Array(_) => false,
        }
    }
    pub fn flatten(self) -> impl Iterator<Item = Value> {
        use utils::Either;
        match self {
            Value::Array(elts) => {
                let mut stack: SmallVec<[(Arc<[Value]>, usize); 8]> = SmallVec::new();
                stack.push((elts, 0));
                Either::Left(iter::from_fn(move || loop {
                    match stack.last_mut() {
                        None => break None,
                        Some((elts, pos)) => {
                            if *pos >= elts.len() {
                                stack.pop();
                            } else {
                                match &elts[*pos] {
                                    Value::Array(elts) => {
                                        *pos += 1;
                                        let elts = elts.clone();
                                        stack.push((elts, 0));
                                    }
                                    val => {
                                        *pos += 1;
                                        break Some(val.clone());
                                    }
                                }
                            }
                        }
                    }
                }))
            }
            val => Either::Right(iter::once(val)),
        }
    }
}
impl FromValue for Value {
    fn from_value(v: Value) -> Res<Self> {
        Ok(v)
    }
    fn get(v: Value) -> Option<Self> {
        Some(v)
    }
}
impl<T: Into<Value> + Copy> convert::From<&T> for Value {
    fn from(v: &T) -> Value {
        (*v).into()
    }
}
impl FromValue for u8 {
    fn from_value(v: Value) -> Res<Self> {
        let v = v.cast_to::<u32>()?;
        if v <= u8::MAX as u32 {
            Ok(v as u8)
        } else {
            bail!("can't cast")
        }
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::U32(v) | Value::V32(v) => Some(v as u8),
            Value::U64(v) | Value::V64(v) => Some(v as u8),
            Value::I32(v) | Value::Z32(v) => Some(v as u8),
            Value::I64(v) | Value::Z64(v) => Some(v as u8),
            _ => None,
        }
    }
}
impl convert::From<u8> for Value {
    fn from(v: u8) -> Value {
        Value::U32(v as u32)
    }
}
impl FromValue for i8 {
    fn from_value(v: Value) -> Res<Self> {
        let v = v.cast_to::<i32>()?;
        if v <= i8::MAX as i32 && v >= i8::MIN as i32 {
            Ok(v as i8)
        } else {
            bail!("can't cast")
        }
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::U32(v) | Value::V32(v) => Some(v as i8),
            Value::U64(v) | Value::V64(v) => Some(v as i8),
            Value::I32(v) | Value::Z32(v) => Some(v as i8),
            Value::I64(v) | Value::Z64(v) => Some(v as i8),
            _ => None,
        }
    }
}
impl convert::From<i8> for Value {
    fn from(v: i8) -> Value {
        Value::I32(v as i32)
    }
}
impl FromValue for u16 {
    fn from_value(v: Value) -> Res<Self> {
        let v = v.cast_to::<u32>()?;
        if v <= u16::MAX as u32 {
            Ok(v as u16)
        } else {
            bail!("can't cast")
        }
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::U32(v) | Value::V32(v) => Some(v as u16),
            Value::U64(v) | Value::V64(v) => Some(v as u16),
            Value::I32(v) | Value::Z32(v) => Some(v as u16),
            Value::I64(v) | Value::Z64(v) => Some(v as u16),
            _ => None,
        }
    }
}
impl convert::From<u16> for Value {
    fn from(v: u16) -> Value {
        Value::U32(v as u32)
    }
}
impl FromValue for i16 {
    fn from_value(v: Value) -> Res<Self> {
        let v = v.cast_to::<i32>()?;
        if v <= i16::MAX as i32 && v >= i16::MIN as i32 {
            Ok(v as i16)
        } else {
            bail!("can't cast")
        }
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::U32(v) | Value::V32(v) => Some(v as i16),
            Value::U64(v) | Value::V64(v) => Some(v as i16),
            Value::I32(v) | Value::Z32(v) => Some(v as i16),
            Value::I64(v) | Value::Z64(v) => Some(v as i16),
            _ => None,
        }
    }
}
impl convert::From<i16> for Value {
    fn from(v: i16) -> Value {
        Value::I32(v as i32)
    }
}
impl FromValue for u32 {
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::U32).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::U32(v) => Ok(v),
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::U32(v) | Value::V32(v) => Some(v as u32),
            Value::U64(v) | Value::V64(v) => Some(v as u32),
            Value::I32(v) | Value::Z32(v) => Some(v as u32),
            Value::I64(v) | Value::Z64(v) => Some(v as u32),
            _ => None,
        }
    }
}
impl convert::From<u32> for Value {
    fn from(v: u32) -> Value {
        Value::U32(v)
    }
}
impl FromValue for i32 {
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::I32).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::I32(v) => Ok(v),
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::U32(v) | Value::V32(v) => Some(v as i32),
            Value::U64(v) | Value::V64(v) => Some(v as i32),
            Value::I32(v) | Value::Z32(v) => Some(v as i32),
            Value::I64(v) | Value::Z64(v) => Some(v as i32),
            _ => None,
        }
    }
}
impl convert::From<i32> for Value {
    fn from(v: i32) -> Value {
        Value::I32(v)
    }
}
impl FromValue for u64 {
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::U64).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::U64(v) => Ok(v),
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::U32(v) | Value::V32(v) => Some(v as u64),
            Value::U64(v) | Value::V64(v) => Some(v as u64),
            Value::I32(v) | Value::Z32(v) => Some(v as u64),
            Value::I64(v) | Value::Z64(v) => Some(v as u64),
            _ => None,
        }
    }
}
impl convert::From<u64> for Value {
    fn from(v: u64) -> Value {
        Value::U64(v)
    }
}
impl convert::From<usize> for Value {
    fn from(v: usize) -> Value {
        Value::U64(v as u64)
    }
}
impl FromValue for usize {
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::U64).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::U64(v) => Ok(v as usize),
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::U32(v) | Value::V32(v) => Some(v as usize),
            Value::U64(v) | Value::V64(v) => Some(v as usize),
            Value::I32(v) | Value::Z32(v) => Some(v as usize),
            Value::I64(v) | Value::Z64(v) => Some(v as usize),
            _ => None,
        }
    }
}
impl FromValue for i64 {
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::I64).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::I64(v) => Ok(v),
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::U32(v) | Value::V32(v) => Some(v as i64),
            Value::U64(v) | Value::V64(v) => Some(v as i64),
            Value::I32(v) | Value::Z32(v) => Some(v as i64),
            Value::I64(v) | Value::Z64(v) => Some(v as i64),
            _ => None,
        }
    }
}
impl convert::From<i64> for Value {
    fn from(v: i64) -> Value {
        Value::I64(v)
    }
}
impl FromValue for f32 {
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::F32).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::F32(v) => Ok(v),
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::F32(v) => Some(v as f32),
            Value::F64(v) => Some(v as f32),
            _ => None,
        }
    }
}
impl convert::From<f32> for Value {
    fn from(v: f32) -> Value {
        Value::F32(v)
    }
}
impl FromValue for f64 {
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::F64).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::F64(v) => Ok(v),
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::F32(v) => Some(v as f64),
            Value::F64(v) => Some(v as f64),
            _ => None,
        }
    }
}
impl convert::From<f64> for Value {
    fn from(v: f64) -> Value {
        Value::F64(v)
    }
}
impl FromValue for Decimal {
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::Decimal).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::Decimal(v) => Ok(v),
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::Decimal(v) => Some(v),
            _ => None,
        }
    }
}
impl convert::From<Decimal> for Value {
    fn from(value: Decimal) -> Self {
        Value::Decimal(value)
    }
}
impl FromValue for Bytes {
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::Bytes).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::Bytes(b) => Ok(b),
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::Bytes(b) => Some(b),
            _ => None,
        }
    }
}
impl convert::From<Bytes> for Value {
    fn from(v: Bytes) -> Value {
        Value::Bytes(v)
    }
}
impl FromValue for Chars {
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::String).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::String(v) => Ok(v),
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::String(c) => Some(c),
            _ => None,
        }
    }
}
impl convert::From<Chars> for Value {
    fn from(v: Chars) -> Value {
        Value::String(v)
    }
}
impl FromValue for Path {
    fn from_value(v: Value) -> Res<Self> {
        v.cast_to::<String>().map(Path::from)
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::String(c) => Some(Path::from(String::from(&*c))),
            _ => None,
        }
    }
}
impl convert::From<Path> for Value {
    fn from(v: Path) -> Value {
        Value::String(Chars::from(String::from(&*v)))
    }
}
impl FromValue for String {
    fn from_value(v: Value) -> Res<Self> {
        v.cast_to::<Chars>().map(|c| c.into())
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::String(c) => Some(c.into()),
            _ => None,
        }
    }
}
impl convert::From<String> for Value {
    fn from(v: String) -> Value {
        Value::String(Chars::from(v))
    }
}
impl convert::From<&'static str> for Value {
    fn from(v: &'static str) -> Value {
        Value::String(Chars::from(v))
    }
}
impl FromValue for ArcStr {
    fn from_value(v: Value) -> Res<Self> {
        v.cast_to::<Chars>().map(|c| ArcStr::from(&*c))
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::String(c) => Some(ArcStr::from(&*c)),
            _ => None,
        }
    }
}
impl convert::From<ArcStr> for Value {
    fn from(v: ArcStr) -> Value {
        Value::String(Chars::from(v))
    }
}
impl FromValue for DateTime<Utc> {
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::DateTime).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::DateTime(d) => Ok(d),
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::DateTime(d) => Some(d),
            _ => None,
        }
    }
}
impl convert::From<DateTime<Utc>> for Value {
    fn from(v: DateTime<Utc>) -> Value {
        Value::DateTime(v)
    }
}
impl FromValue for Duration {
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::Duration).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::Duration(d) => Ok(d),
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::Duration(d) => Some(d),
            _ => None,
        }
    }
}
impl convert::From<Duration> for Value {
    fn from(v: Duration) -> Value {
        Value::Duration(v)
    }
}
impl FromValue for bool {
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::Bool).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::True => Ok(true),
            Value::False => Ok(false),
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::True => Some(true),
            Value::False => Some(false),
            _ => None,
        }
    }
}
impl convert::From<bool> for Value {
    fn from(v: bool) -> Value {
        if v {
            Value::True
        } else {
            Value::False
        }
    }
}
impl FromValue for Arc<[Value]> {
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::Array).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::Array(elts) => Ok(elts),
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::Array(elts) => Some(elts),
            _ => None,
        }
    }
}
impl convert::From<Arc<[Value]>> for Value {
    fn from(v: Arc<[Value]>) -> Value {
        Value::Array(v)
    }
}
impl<T: FromValue> FromValue for Vec<T> {
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::Array).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::Array(elts) => elts
                .iter()
                .map(|v| <T as FromValue>::from_value(v.clone()))
                .collect::<Res<Vec<_>>>(),
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::Array(elts) => {
                elts.iter().map(|v| FromValue::get(v.clone())).collect::<Option<Vec<_>>>()
            }
            _ => None,
        }
    }
}
impl<T: convert::Into<Value>> convert::From<Vec<T>> for Value {
    fn from(v: Vec<T>) -> Value {
        let v = v.into_iter().map(|e| e.into()).collect::<Vec<Value>>();
        Value::Array(Arc::from(v))
    }
}
impl<T: convert::Into<Value> + Clone + Send + Sync> convert::From<Pooled<Vec<T>>>
    for Value
{
    fn from(v: Pooled<Vec<T>>) -> Value {
        let v = v.iter().map(|e| e.clone().into()).collect::<Vec<Value>>();
        Value::Array(Arc::from(v))
    }
}
impl<A> FromValue for SmallVec<A>
where
    A: smallvec::Array,
    <A as smallvec::Array>::Item: FromValue,
{
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::Array).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::Array(elts) => elts
                .iter()
                .map(|v| FromValue::from_value(v.clone()))
                .collect::<Res<SmallVec<A>>>(),
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::Array(elts) => elts
                .iter()
                .map(|v| FromValue::get(v.clone()))
                .collect::<Option<SmallVec<A>>>(),
            _ => None,
        }
    }
}
impl<A> convert::From<SmallVec<A>> for Value
where
    A: smallvec::Array,
    <A as smallvec::Array>::Item: convert::Into<Value>,
{
    fn from(v: SmallVec<A>) -> Self {
        let v = v.into_iter().map(|e| e.into()).collect::<Vec<Value>>();
        Value::Array(Arc::from(v))
    }
}
impl<T: FromValue, U: FromValue> FromValue for (T, U) {
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::Array).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::Array(elts) if elts.len() == 2 => {
                let v0 = elts[0].clone().cast_to::<T>()?;
                let v1 = elts[1].clone().cast_to::<U>()?;
                Ok((v0, v1))
            }
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::Array(elts) if elts.len() == 2 => {
                let v0 = elts[0].clone().get_as::<T>()?;
                let v1 = elts[1].clone().get_as::<U>()?;
                Some((v0, v1))
            }
            _ => None,
        }
    }
}
impl<T: convert::Into<Value>, U: convert::Into<Value>> convert::From<(T, U)> for Value {
    fn from((t, u): (T, U)) -> Value {
        let v0 = t.into();
        let v1 = u.into();
        let elts = Arc::from([v0, v1]);
        Value::Array(elts)
    }
}
impl<T: FromValue, U: FromValue, V: FromValue> FromValue for (T, U, V) {
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::Array).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::Array(elts) if elts.len() == 3 => {
                let v0 = elts[0].clone().cast_to::<T>()?;
                let v1 = elts[1].clone().cast_to::<U>()?;
                let v2 = elts[2].clone().cast_to::<V>()?;
                Ok((v0, v1, v2))
            }
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::Array(elts) if elts.len() == 3 => {
                let v0 = elts[0].clone().get_as::<T>()?;
                let v1 = elts[1].clone().get_as::<U>()?;
                let v2 = elts[2].clone().get_as::<V>()?;
                Some((v0, v1, v2))
            }
            _ => None,
        }
    }
}
impl<T: convert::Into<Value>, U: convert::Into<Value>, V: convert::Into<Value>>
    convert::From<(T, U, V)> for Value
{
    fn from((t, u, v): (T, U, V)) -> Value {
        let v0 = t.into();
        let v1 = u.into();
        let v2 = v.into();
        let elts = Arc::from([v0, v1, v2]);
        Value::Array(elts)
    }
}
impl<K: FromValue + Eq + Hash, V: FromValue, S: BuildHasher + Default> FromValue
    for HashMap<K, V, S>
{
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::Array).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::Array(elts) => {
                elts.iter().map(|v| v.clone().cast_to::<(K, V)>()).collect()
            }
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::Array(elts) => {
                elts.iter().map(|v| v.clone().get_as::<(K, V)>()).collect()
            }
            _ => None,
        }
    }
}
impl<K: convert::Into<Value>, V: convert::Into<Value>, S: BuildHasher + Default>
    convert::From<HashMap<K, V, S>> for Value
{
    fn from(h: HashMap<K, V, S>) -> Value {
        h.into_iter().map(|v| v.into()).collect::<Vec<Value>>().into()
    }
}
impl<K: FromValue + Ord, V: FromValue> FromValue for BTreeMap<K, V> {
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::Array).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::Array(elts) => {
                elts.iter().map(|v| v.clone().cast_to::<(K, V)>()).collect()
            }
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::Array(elts) => {
                elts.iter().map(|v| v.clone().get_as::<(K, V)>()).collect()
            }
            _ => None,
        }
    }
}
impl<K: convert::Into<Value>, V: convert::Into<Value>> convert::From<BTreeMap<K, V>>
    for Value
{
    fn from(v: BTreeMap<K, V>) -> Self {
        v.into_iter().map(|v| v.into()).collect::<Vec<Value>>().into()
    }
}
impl<K: FromValue + Eq + Hash, S: BuildHasher + Default> FromValue for HashSet<K, S> {
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::Array).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::Array(elts) => elts.iter().map(|v| v.clone().cast_to::<K>()).collect(),
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::Array(elts) => elts.iter().map(|v| v.clone().get_as::<K>()).collect(),
            _ => None,
        }
    }
}
impl<K: convert::Into<Value>, S: BuildHasher + Default> convert::From<HashSet<K, S>>
    for Value
{
    fn from(h: HashSet<K, S>) -> Value {
        h.into_iter().map(|v| v.into()).collect::<Vec<Value>>().into()
    }
}
impl<K: FromValue + Ord> FromValue for BTreeSet<K> {
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::Array).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::Array(elts) => elts.iter().map(|v| v.clone().cast_to::<K>()).collect(),
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::Array(elts) => elts.iter().map(|v| v.clone().get_as::<K>()).collect(),
            _ => None,
        }
    }
}
impl<K: convert::Into<Value>> convert::From<BTreeSet<K>> for Value {
    fn from(s: BTreeSet<K>) -> Self {
        s.into_iter().map(|v| v.into()).collect::<Vec<Value>>().into()
    }
}
impl<K: FromValue + Eq + Hash, V: FromValue, S: BuildHasher + Default> FromValue
    for IndexMap<K, V, S>
{
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::Array).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::Array(elts) => {
                elts.iter().map(|v| v.clone().cast_to::<(K, V)>()).collect()
            }
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::Array(elts) => {
                elts.iter().map(|v| v.clone().get_as::<(K, V)>()).collect()
            }
            _ => None,
        }
    }
}
impl<K: convert::Into<Value>, V: convert::Into<Value>, S: BuildHasher + Default>
    convert::From<IndexMap<K, V, S>> for Value
{
    fn from(h: IndexMap<K, V, S>) -> Value {
        h.into_iter().map(|v| v.into()).collect::<Vec<Value>>().into()
    }
}
impl<K: FromValue + Eq + Hash, S: BuildHasher + Default> FromValue for IndexSet<K, S> {
    fn from_value(v: Value) -> Res<Self> {
        v.cast(Typ::Array).ok_or_else(|| anyhow!("can't cast")).and_then(|v| match v {
            Value::Array(elts) => elts
                .iter()
                .map(|v| v.clone().cast_to::<K>())
                .collect::<Res<IndexSet<K, S>>>(),
            _ => bail!("can't cast"),
        })
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::Array(elts) => elts.iter().map(|v| v.clone().get_as::<K>()).collect(),
            _ => None,
        }
    }
}
impl<K: convert::Into<Value>, S: BuildHasher + Default> convert::From<IndexSet<K, S>>
    for Value
{
    fn from(h: IndexSet<K, S>) -> Value {
        h.into_iter().map(|v| v.into()).collect::<Vec<Value>>().into()
    }
}
impl<T: FromValue> FromValue for Option<T> {
    fn from_value(v: Value) -> Res<Self> {
        match v {
            Value::Null => Ok(None),
            v => v.cast_to::<T>().map(|v| Some(v)),
        }
    }
    fn get(v: Value) -> Option<Self> {
        match v {
            Value::Null => Some(None),
            v => v.get_as::<T>().map(|v| Some(v)),
        }
    }
}
impl<T: convert::Into<Value>> convert::From<Option<T>> for Value {
    fn from(o: Option<T>) -> Value {
        o.map(|v| v.into()).unwrap_or(Value::Null)
    }
}
use enumflags2::{BitFlag, BitFlags, _internal::RawBitFlags};
impl<T> FromValue for BitFlags<T>
where
    T: BitFlag,
    <T as RawBitFlags>::Numeric: FromValue,
{
    fn from_value(v: Value) -> Res<Self> {
        let bits = v.cast_to::<<T as RawBitFlags>::Numeric>()?;
        BitFlags::from_bits(bits).map_err(|_| anyhow!("invalid bits"))
    }
    fn get(v: Value) -> Option<Self> {
        let bits = v.get_as::<<T as RawBitFlags>::Numeric>()?;
        BitFlags::from_bits(bits).ok()
    }
}
impl<T> convert::From<BitFlags<T>> for Value
where
    T: BitFlag,
    <T as RawBitFlags>::Numeric: Into<Value>,
{
    fn from(v: BitFlags<T>) -> Self {
        v.bits().into()
    }
}
impl convert::From<uuid::Uuid> for Value {
    fn from(id: uuid::Uuid) -> Self {
        Value::from(id.to_string())
    }
}
impl FromValue for uuid::Uuid {
    fn from_value(v: Value) -> Res<Self> {
        match v {
            Value::String(v) => Ok(v.parse::<uuid::Uuid>()?),
            _ => bail!("can't cast"),
        }
    }
    fn get(v: Value) -> Option<Self> {
        <uuid::Uuid as FromValue>::from_value(v).ok()
    }
}
thread_local! {
    static POOLS: RefCell<FxHashMap<TypeId, Box<dyn Any>>> =
        RefCell::new(HashMap::default());
}
impl<T: FromValue + Send + Sync> FromValue for Pooled<Vec<T>> {
    fn from_value(v: Value) -> Res<Self> {
        match v {
            Value::Array(elts) => {
                let mut t = POOLS.with(|pools| {
                    let mut pools = pools.borrow_mut();
                    let pool: &mut Pool<Vec<T>> = pools
                        .entry(TypeId::of::<Vec<T>>())
                        .or_insert_with(|| Box::new(Pool::<Vec<T>>::new(10000, 10000)))
                        .downcast_mut()
                        .unwrap();
                    pool.take()
                });
                for elt in elts.iter() {
                    t.push(elt.clone().cast_to::<T>()?)
                }
                Ok(t)
            }
            _ => bail!("expected an array"),
        }
    }
    fn get(v: Value) -> Option<Self> {
        <Pooled<Vec<T>> as FromValue>::from_value(v).ok()
    }
}