use std::borrow::Cow;
use crate::value::{Int, Slot};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Kind {
Null,
Bool,
Int,
Float,
String,
Array,
Object,
UnsafeInteger,
IntegerTooWide,
Foreign,
}
impl Kind {
pub fn name(self) -> &'static str {
match self {
Kind::Null => "null",
Kind::Bool => "bool",
Kind::Int => "integer",
Kind::Float => "float",
Kind::String => "string",
Kind::Array => "array",
Kind::Object => "object",
Kind::UnsafeInteger => "integer beyond exact precision",
Kind::IntegerTooWide => "integer wider than 64 bits",
Kind::Foreign => "unsupported value",
}
}
}
pub trait Input {
type Child<'a>: Input
where
Self: 'a;
fn kind(&self) -> Kind;
fn as_bool(&self) -> Option<bool>;
fn as_int(&self) -> Option<Int>;
fn as_f64(&self) -> Option<f64>;
fn as_str(&self) -> Option<Cow<'_, str>>;
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn item(&self, index: usize) -> Option<Self::Child<'_>>;
fn slot(&self, key: &str) -> Slot<Self::Child<'_>>;
fn each_key(&self, f: &mut dyn FnMut(&str));
}
impl<T: Input> Input for &T {
type Child<'a>
= T::Child<'a>
where
Self: 'a;
fn kind(&self) -> Kind {
(**self).kind()
}
fn as_bool(&self) -> Option<bool> {
(**self).as_bool()
}
fn as_int(&self) -> Option<Int> {
(**self).as_int()
}
fn as_f64(&self) -> Option<f64> {
(**self).as_f64()
}
fn as_str(&self) -> Option<Cow<'_, str>> {
(**self).as_str()
}
fn len(&self) -> usize {
(**self).len()
}
fn item(&self, index: usize) -> Option<Self::Child<'_>> {
(**self).item(index)
}
fn slot(&self, key: &str) -> Slot<Self::Child<'_>> {
(**self).slot(key)
}
fn each_key(&self, f: &mut dyn FnMut(&str)) {
(**self).each_key(f);
}
}