cel_rs/
value.rs

1use std::{hash::Hash, rc::Rc};
2use ordered_float::OrderedFloat;
3use ordered_hash_map::OrderedHashMap;
4use crate::parser::Atom;
5
6#[derive(PartialEq, Eq, Clone, Debug)]
7pub enum Value {
8    Int(i64),   
9    UInt(u64),
10    // We need to use a wrapper for floats for Eq, Hash
11    Float(OrderedFloat<f64>),
12    Null,
13    Bool(bool),
14    Bytes(Rc<Vec<u8>>),
15    String(Rc<String>),
16    Map(Rc<OrderedHashMap<Value, Value>>),
17    List(Rc<Vec<Value>>),
18    Function(Rc<FnValue>)
19}
20
21#[derive(PartialEq, Eq, Debug)]
22pub struct FnValue {
23    pub name: &'static str,
24    pub overloads: &'static [Overload],
25}
26
27pub type Func = fn(lhs: &Value, rhs: &Value) -> Value;
28
29#[derive(PartialEq, Eq, Debug)]
30pub struct Overload {
31    pub key: &'static str,
32    pub func: Func
33}
34
35impl Into<bool> for Value {
36    fn into(self) -> bool {
37        match self {
38            Value::Int(v) => v != 0,
39            Value::UInt(v) => v != 0,
40            Value::Float(v) => v != 0.0,
41            Value::Null => false,
42            Value::Bool(v) => v,
43            Value::Bytes(v) => v.len() > 0,
44            Value::String(v) => v.len() > 0,
45            Value::Map(v) => v.len() > 0,
46            Value::List(v) => v.len() > 0,
47            Value::Function(_) => true,
48        }
49    }
50}
51
52impl Hash for Value {
53    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
54        // TODO: this is not right. hash each arm separately.
55        core::mem::discriminant(self).hash(state);
56    }
57}
58
59impl From<Atom> for Value {
60    fn from(atom: Atom) -> Self {
61        match atom {
62            Atom::Int(i) => Value::Int(i),
63            Atom::UInt(ui) => Value::UInt(ui),
64            Atom::Float(f) => Value::Float(f.into()),
65            Atom::Bool(b) => Value::Bool(b),
66            Atom::Null => Value::Null,
67            Atom::Bytes(b) => Value::Bytes(b),
68            Atom::String(s) => Value::String(s),
69        }
70    }
71}
72
73impl std::fmt::Display for Value {
74    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75        match self {
76            Value::Int(v) => write!(f, "int({})", v),
77            Value::UInt(v) => write!(f, "uint({})", v),
78            Value::Float(v) => write!(f, "float({})", v),
79            Value::Null => write!(f, "null"),
80            Value::Bool(v) => write!(f, "bool({})", v),
81            Value::Bytes(v) => write!(f, "bytes(len = {})", v.len()),
82            Value::String(v) => write!(f, "string({})", v),
83            Value::Map(v) => write!(f, "map(len = {})", v.len()),
84            Value::List(v) => write!(f, "list(len = {})", v.len()),
85            Value::Function(v) => write!(f, "function(name = {})", v.name),
86        }
87    }
88}
89
90impl std::ops::Mul for Value {
91    type Output = Value;
92
93    fn mul(self, rhs: Self) -> Self::Output {
94        match (self, rhs) {
95            (Value::Int(l), Value::Int(r)) => Value::Int(l * r),
96            (a, b) => todo!("mul {} {}", a, b),
97        }
98    }
99}
100
101impl std::ops::Div for Value {
102    type Output = Value;
103
104    fn div(self, rhs: Self) -> Self::Output {
105        match (self, rhs) {
106            (Value::Int(l), Value::Int(r)) => Value::Int(l / r),
107            (a, b) => todo!("div {} {}", a, b),
108        }
109    }
110}
111
112impl std::ops::Add<Value> for Value {
113    type Output = Value;
114
115    fn add(self, o: Value) -> Self::Output {
116        match (self, o) {
117            (Value::Int(l), Value::Int(r)) => Value::Int(l + r),
118            (a, b) => todo!("add {} {}", a, b),
119        }
120    }
121}
122
123impl std::ops::Sub<Value> for Value {
124    type Output = Value;
125    fn sub(self, o: Value) -> Self::Output {
126        match (self, o) {
127            (Value::Int(l), Value::Int(r)) => Value::Int(l - r),
128            (a, b) => todo!("sub {} {}", a, b),
129        }
130    }
131}