114 lines
No EOL
2.1 KiB
Rust
114 lines
No EOL
2.1 KiB
Rust
use std::collections::HashMap;
|
|
|
|
#[derive(PartialEq, Debug)]
|
|
pub enum Value {
|
|
None,
|
|
True,
|
|
False,
|
|
Number(f64),
|
|
String(String),
|
|
Table {
|
|
arr: Vec<Value>,
|
|
map: HashMap<String, Value>,
|
|
}
|
|
}
|
|
|
|
impl From<i32> for Value {
|
|
fn from(v: i32) -> Value {
|
|
Value::Number(f64::from(v))
|
|
}
|
|
}
|
|
impl From<f32> for Value {
|
|
fn from(v: f32) -> Value {
|
|
Value::Number(f64::from(v))
|
|
}
|
|
}
|
|
impl From<f64> for Value {
|
|
fn from(v: f64) -> Value {
|
|
Value::Number(v)
|
|
}
|
|
}
|
|
impl From<String> for Value {
|
|
fn from(v: String) -> Value {
|
|
Value::String(v)
|
|
}
|
|
}
|
|
|
|
impl From<&str> for Value {
|
|
fn from(v: &str) -> Value {
|
|
Value::String(v.to_string())
|
|
}
|
|
}
|
|
|
|
impl From<bool> for Value {
|
|
fn from(v: bool) -> Value {
|
|
match v {
|
|
true => Value::True,
|
|
false => Value::False,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T: Into<Value>> From<Vec<T>> for Value {
|
|
fn from(v: Vec<T>) -> Value {
|
|
let mut vec: Vec<Value> = Vec::new();
|
|
for val in v {
|
|
vec.push(val.into());
|
|
}
|
|
Value::Table { arr: vec, map: HashMap::new() }
|
|
}
|
|
}
|
|
impl<T: Into<Value>> From<HashMap<String, T>> for Value {
|
|
fn from(v: HashMap<String, T>) -> Value {
|
|
let mut map: HashMap<String, Value> = HashMap::new();
|
|
for (k, v) in v {
|
|
map.insert(k, v.into());
|
|
}
|
|
Value::Table { arr: Vec::new(), map}
|
|
}
|
|
}
|
|
|
|
impl<T: Into<Value>> From<Option<T>> for Value {
|
|
fn from(v: Option<T>) -> Value {
|
|
match v {
|
|
Some(v) => v.into(),
|
|
None => Value::None,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub trait FromValue {
|
|
fn from_value(v: Value) -> Result<Self, &'static str> where Self: Sized;
|
|
}
|
|
|
|
impl FromValue for f64 {
|
|
fn from_value(v: Value) -> Result<f64, &'static str> {
|
|
match v {
|
|
Value::Number(v) => Ok(v),
|
|
_ => Err("Value is not a number"),
|
|
}
|
|
}
|
|
}
|
|
impl FromValue for bool {
|
|
fn from_value(v: Value) -> Result<bool, &'static str> {
|
|
match v {
|
|
Value::True => Ok(true),
|
|
Value::False => Ok(false),
|
|
_ => Err("Value is not a boolean"),
|
|
}
|
|
}
|
|
}
|
|
impl FromValue for String {
|
|
fn from_value(v: Value) -> Result<String, &'static str> {
|
|
match v {
|
|
Value::String(v) => Ok(v),
|
|
_ => Err("Value is not a string"),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Value {
|
|
pub fn extract<T: FromValue>(self) -> Result<T, &'static str> {
|
|
FromValue::from_value(self)
|
|
}
|
|
} |