use crate::haystack::val::boolean::*;
use crate::haystack::val::coord::*;
use crate::haystack::val::date::*;
use crate::haystack::val::datetime::*;
use crate::haystack::val::dict::*;
use crate::haystack::val::grid::*;
use crate::haystack::val::list::*;
use crate::haystack::val::number::*;
use crate::haystack::val::reference::*;
use crate::haystack::val::string::*;
use crate::haystack::val::symbol::*;
use crate::haystack::val::time::*;
use crate::haystack::val::uri::*;
use crate::haystack::val::xstr::*;
use crate::units::Unit;
use std::fmt::{Display, Formatter};
use std::hash::Hash;
#[derive(PartialOrd, Eq, Ord, Clone, Debug, Default)]
pub enum Value {
#[default]
Null,
Remove,
Marker,
Bool(Bool),
Na,
Number(Number),
Str(Str),
Uri(Uri),
Ref(Ref),
Symbol(Symbol),
Date(Date),
Time(Time),
DateTime(DateTime),
Coord(Coord),
XStr(XStr),
List(List),
Dict(Dict),
Grid(Grid),
}
impl Value {
pub fn is_null(&self) -> bool {
matches!(self, Value::Null)
}
pub fn has_value(&self) -> bool {
!self.is_null()
}
pub fn make_remove() -> Value {
Value::Remove
}
pub fn is_remove(&self) -> bool {
matches!(self, Value::Remove)
}
pub fn make_marker() -> Value {
Value::Marker
}
pub fn is_marker(&self) -> bool {
matches!(self, Value::Marker)
}
pub fn make_bool(value: bool) -> Value {
Value::Bool(Bool::from(value))
}
pub fn make_true() -> Value {
Value::Bool(true.into())
}
pub fn is_true(&self) -> bool {
match self {
Value::Bool(v) => v.value,
_ => false,
}
}
pub fn is_false(&self) -> bool {
!self.is_true()
}
pub fn make_false() -> Value {
Value::Bool(false.into())
}
pub fn is_bool(&self) -> bool {
matches!(self, Value::Bool(_))
}
pub fn make_na() -> Value {
Value::Na
}
pub fn is_na(&self) -> bool {
matches!(self, Value::Na)
}
pub fn make_number(value: f64) -> Value {
Value::from(value)
}
pub fn make_int(value: i64) -> Value {
Value::from(value as f64)
}
pub fn make_number_unit(value: f64, unit: &'static Unit) -> Value {
Value::Number(Number::make_with_unit(value, unit))
}
pub fn is_number(&self) -> bool {
matches!(self, Value::Number(_))
}
pub fn make_str(value: &str) -> Value {
Value::from(value)
}
pub fn is_str(&self) -> bool {
matches!(self, Value::Str(_))
}
pub fn make_ref(value: &str) -> Value {
Value::from(Ref::from(value))
}
pub fn make_ref_gen() -> Value {
Value::from(Ref::generate())
}
pub fn make_ref_with_dis(value: &str, dis: &str) -> Value {
Value::from(Ref {
value: String::from(value),
dis: Some(String::from(dis)),
})
}
pub fn is_ref(&self) -> bool {
matches!(self, Value::Ref(_))
}
pub fn make_symbol(value: &str) -> Value {
Value::from(Symbol::from(value))
}
pub fn is_symbol(&self) -> bool {
matches!(self, Value::Symbol(_))
}
pub fn make_uri(value: &str) -> Value {
Value::from(Uri::from(value))
}
pub fn is_uri(&self) -> bool {
matches!(self, Value::Uri(_))
}
pub fn make_date(value: Date) -> Value {
Value::from(value)
}
pub fn is_date(&self) -> bool {
matches!(self, Value::Date(_))
}
pub fn make_time(value: Time) -> Value {
Value::from(value)
}
pub fn is_time(&self) -> bool {
matches!(self, Value::Time(_))
}
pub fn make_datetime(value: DateTime) -> Value {
Value::from(value)
}
pub fn make_datetime_from_iso(value: &str) -> Result<Value, String> {
let date_time = DateTime::parse_from_rfc3339(value)?;
Ok(Value::from(date_time))
}
pub fn is_datetime(&self) -> bool {
matches!(self, Value::DateTime(_))
}
pub fn make_coord(value: Coord) -> Value {
Value::from(value)
}
pub fn make_coord_from(lat: f64, long: f64) -> Value {
Value::from(Coord { lat, long })
}
pub fn is_coord(&self) -> bool {
matches!(self, Value::Coord(_))
}
pub fn make_xstr(value: XStr) -> Value {
Value::from(value)
}
pub fn make_xstr_from(typ: &str, value: &str) -> Value {
Value::from(XStr::make(typ, value))
}
pub fn is_xstr(&self) -> bool {
matches!(self, Value::XStr(_))
}
pub fn make_list(value: List) -> Value {
Value::from(value)
}
pub fn is_list(&self) -> bool {
matches!(self, Value::List(_))
}
pub fn make_dict(value: Dict) -> Value {
Value::from(value)
}
pub fn is_dict(&self) -> bool {
matches!(self, Value::Dict(_))
}
pub fn make_grid(value: Grid) -> Value {
Value::from(value)
}
pub fn make_grid_from_dicts(value: Vec<Dict>) -> Value {
Value::from(Grid::make_from_dicts(value))
}
pub fn is_grid(&self) -> bool {
matches!(self, Value::Grid(_))
}
}
impl Display for Value {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
use crate::haystack::encoding::zinc::encode::ToZinc;
match self {
Value::Null => f.write_str("Null"),
Value::Remove => f.write_str("Remove"),
Value::Marker => f.write_str("Marker"),
Value::Bool(val) => f.write_str(if val.value { "true" } else { "false" }),
Value::Na => f.write_str("Na"),
Value::Number(_)
| Value::Str(_)
| Value::Ref(_)
| Value::Uri(_)
| Value::Symbol(_)
| Value::Date(_)
| Value::Time(_)
| Value::DateTime(_)
| Value::Coord(_)
| Value::XStr(_)
| Value::List(_)
| Value::Dict(_)
| Value::Grid(_) => match self.to_zinc_string() {
Ok(zinc) => f.write_str(&zinc),
Err(_) => Err(std::fmt::Error),
},
}
}
}
impl Hash for Value {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
match self {
Value::Null => std::any::TypeId::of::<Value>().hash(state),
Value::Marker => super::marker::Marker.hash(state),
Value::Remove => super::remove::Remove.hash(state),
Value::Na => super::na::Na.hash(state),
Value::Bool(val) => val.hash(state),
Value::Number(val) => val.hash(state),
Value::Str(val) => val.hash(state),
Value::Ref(val) => val.hash(state),
Value::Uri(val) => val.hash(state),
Value::Symbol(val) => val.hash(state),
Value::Date(val) => val.hash(state),
Value::Time(val) => val.hash(state),
Value::DateTime(val) => val.hash(state),
Value::Coord(val) => val.hash(state),
Value::XStr(val) => val.hash(state),
Value::List(val) => val.hash(state),
Value::Dict(val) => val.hash(state),
Value::Grid(val) => val.hash(state),
}
}
}
impl PartialEq for Value {
fn eq(&self, other: &Self) -> bool {
match self {
Value::Null => other.is_null(),
Value::Marker => other.is_marker(),
Value::Remove => other.is_remove(),
Value::Na => other.is_na(),
Value::Bool(val) => matches!(other, Value::Bool(v) if v == val),
Value::Number(val) => matches!(other, Value::Number(v) if v == val),
Value::Str(val) => matches!(other, Value::Str(v) if v == val),
Value::Ref(val) => matches!(other, Value::Ref(v) if v == val),
Value::Uri(val) => matches!(other, Value::Uri(v) if v == val),
Value::Symbol(val) => matches!(other, Value::Symbol(v) if v == val),
Value::Date(val) => matches!(other, Value::Date(v) if v == val),
Value::Time(val) => matches!(other, Value::Time(v) if v == val),
Value::DateTime(val) => matches!(other, Value::DateTime(v) if v == val),
Value::Coord(val) => matches!(other, Value::Coord(v) if v == val),
Value::XStr(val) => matches!(other, Value::XStr(v) if v == val),
Value::List(val) => matches!(other, Value::List(v) if v == val),
Value::Dict(val) => matches!(other, Value::Dict(v) if v == val),
Value::Grid(val) => matches!(other, Value::Grid(v) if v == val),
}
}
}