use crate::model::ShapeID;
use std::collections::HashMap;
use std::fmt::{Display, Formatter};
#[derive(Clone, Debug, PartialEq, PartialOrd)]
pub enum Number {
Integer(i64),
Float(f64),
}
#[derive(Clone, Debug, PartialEq)]
pub enum Value {
Array(Vec<Value>),
Object(ValueMap),
Number(Number),
Boolean(bool),
String(String),
None,
}
pub type ValueMap = HashMap<String, Value>;
impl From<i8> for Number {
fn from(n: i8) -> Self {
Self::Integer(n as i64)
}
}
impl From<i16> for Number {
fn from(n: i16) -> Self {
Self::Integer(n as i64)
}
}
impl From<i32> for Number {
fn from(n: i32) -> Self {
Self::Integer(n as i64)
}
}
impl From<i64> for Number {
fn from(n: i64) -> Self {
Self::Integer(n)
}
}
impl From<f32> for Number {
fn from(n: f32) -> Self {
Self::Float(n as f64)
}
}
impl From<f64> for Number {
fn from(n: f64) -> Self {
Self::Float(n)
}
}
impl Display for Number {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::Integer(n) => write!(f, "{}", n),
Self::Float(n) => write!(f, "{}", n),
}
}
}
impl From<Number> for Value {
fn from(n: Number) -> Self {
Self::Number(n)
}
}
impl From<i8> for Value {
fn from(n: i8) -> Self {
Self::Number((n as i64).into())
}
}
impl From<i16> for Value {
fn from(n: i16) -> Self {
Self::Number((n as i64).into())
}
}
impl From<i32> for Value {
fn from(n: i32) -> Self {
Self::Number((n as i64).into())
}
}
impl From<i64> for Value {
fn from(n: i64) -> Self {
Self::Number(n.into())
}
}
impl From<f32> for Value {
fn from(n: f32) -> Self {
Self::Number((n as f64).into())
}
}
impl From<f64> for Value {
fn from(n: f64) -> Self {
Self::Number(n.into())
}
}
impl From<bool> for Value {
fn from(b: bool) -> Self {
Self::Boolean(b)
}
}
impl From<String> for Value {
fn from(v: String) -> Self {
Self::String(v)
}
}
impl From<&str> for Value {
fn from(v: &str) -> Self {
Self::String(v.to_string())
}
}
impl From<ShapeID> for Value {
fn from(v: ShapeID) -> Self {
Self::String(v.to_string())
}
}
impl From<&ShapeID> for Value {
fn from(v: &ShapeID) -> Self {
Self::String(v.to_string())
}
}
impl From<Vec<Value>> for Value {
fn from(v: Vec<Value>) -> Self {
Self::Array(v)
}
}
impl From<&[Value]> for Value {
fn from(v: &[Value]) -> Self {
Self::from(v.to_vec())
}
}
impl From<HashMap<String, Value>> for Value {
fn from(v: HashMap<String, Value>) -> Self {
Self::Object(v)
}
}
impl Display for Value {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Value::Array(vs) => write!(
f,
"[ {} ]",
vs.iter()
.map(|v| v.to_string())
.collect::<Vec<String>>()
.join(", ")
),
Value::Object(vs) => write!(
f,
"{{ {} }}",
vs.iter()
.map(|(k, v)| format!("{}: {}", k, v.to_string()))
.collect::<Vec<String>>()
.join(", ")
),
Value::Number(v) => write!(f, "{}", v),
Value::Boolean(v) => write!(f, "{}", v),
Value::String(v) => write!(f, "\"{}\"", v),
Value::None => write!(f, "None"),
}
}
}
impl Value {
is_as! { array, Array, Vec<Value> }
is_as! { object, Object, HashMap<String, Value> }
is_as! { number, Number, Number }
is_as! { boolean, Boolean, bool }
is_as! { string, String, String }
is_only! { none, None }
}