use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::mem::discriminant;
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub enum Value {
Null,
Bool(bool),
Integer(i64),
Float(f64),
String(String),
Assoc(Assoc),
Array(Array),
Tuple(Vec<Value>),
Variant(Variant),
}
pub type Assoc = HashMap<String, Value>;
pub type Array = Vec<Value>;
pub type Variant = (String, Option<Box<Value>>);
impl Value {
pub fn is_null(&self) -> bool {
matches!(self, Value::Null)
}
pub fn as_integer(&self) -> Option<i64> {
match *self {
Value::Integer(i) => Some(i),
_ => None,
}
}
pub fn is_integer(&self) -> bool {
self.as_integer().is_some()
}
pub fn as_float(&self) -> Option<f64> {
match *self {
Value::Float(f) => Some(f),
_ => None,
}
}
pub fn is_float(&self) -> bool {
self.as_float().is_some()
}
pub fn as_bool(&self) -> Option<bool> {
match *self {
Value::Bool(b) => Some(b),
_ => None,
}
}
pub fn is_bool(&self) -> bool {
self.as_bool().is_some()
}
pub fn as_str(&self) -> Option<&str> {
match *self {
Value::String(ref s) => Some(&**s),
_ => None,
}
}
pub fn is_str(&self) -> bool {
self.as_str().is_some()
}
pub fn as_array(&self) -> Option<&Vec<Value>> {
match *self {
Value::Array(ref s) => Some(s),
_ => None,
}
}
pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> {
match *self {
Value::Array(ref mut s) => Some(s),
_ => None,
}
}
pub fn is_array(&self) -> bool {
self.as_array().is_some()
}
pub fn as_tuple(&self) -> Option<&Vec<Value>> {
match *self {
Value::Tuple(ref s) => Some(s),
_ => None,
}
}
pub fn as_tuple_mut(&mut self) -> Option<&mut Vec<Value>> {
match *self {
Value::Tuple(ref mut s) => Some(s),
_ => None,
}
}
pub fn is_tuple(&self) -> bool {
self.as_tuple().is_some()
}
pub fn as_assoc(&self) -> Option<&HashMap<String, Value>> {
match *self {
Value::Assoc(ref s) => Some(s),
_ => None,
}
}
pub fn as_assoc_mut(&mut self) -> Option<&mut HashMap<String, Value>> {
match *self {
Value::Assoc(ref mut s) => Some(s),
_ => None,
}
}
pub fn is_assoc(&self) -> bool {
self.as_assoc().is_some()
}
pub fn as_variant(&self) -> Option<&Variant> {
match *self {
Value::Variant(ref s) => Some(s),
_ => None,
}
}
pub fn as_variant_mut(&mut self) -> Option<&mut Variant> {
match *self {
Value::Variant(ref mut s) => Some(s),
_ => None,
}
}
pub fn is_variant(&self) -> bool {
self.as_variant().is_some()
}
pub fn same_type(&self, other: &Value) -> bool {
discriminant(self) == discriminant(other)
}
pub fn type_str(&self) -> &'static str {
match *self {
Value::Null => "null",
Value::String(..) => "string",
Value::Integer(..) => "integer",
Value::Float(..) => "float",
Value::Bool(..) => "boolean",
Value::Array(..) => "array",
Value::Assoc(..) => "assoc",
Value::Tuple(..) => "tuple",
Value::Variant(..) => "variant",
}
}
}