fvm/src/value.rs
2024-10-25 19:22:52 -05:00

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)
}
}