Skip to main content

simple_expressions/types/
value.rs

1use crate::types::error::{Error, Result};
2pub(crate) use crate::types::object::Object;
3use crate::types::primitive::Primitive;
4use crate::types::string_members::get_string_member;
5use std::fmt;
6use std::fmt::{Debug, Display, Formatter};
7use std::rc::Rc;
8
9#[derive(Clone)]
10pub enum Value {
11    Primitive(Primitive),
12    Object(Rc<dyn Object>),
13}
14
15impl Value {
16    pub fn as_str_lossy(&self) -> String {
17        match self {
18            Value::Primitive(p) => p.as_str_lossy(),
19            Value::Object(obj) => obj.as_string().unwrap_or_else(|| format!("{}", obj)),
20        }
21    }
22
23    pub fn type_name(&self) -> &'static str {
24        match self {
25            Value::Primitive(Primitive::Str(_)) => "string",
26            Value::Primitive(Primitive::Int(_)) | Value::Primitive(Primitive::Float(_)) => "number",
27            Value::Primitive(Primitive::Bool(_)) => "bool",
28            Value::Object(obj) => obj.type_name(),
29        }
30    }
31
32    pub fn get_member(&self, name: &str) -> Result<Value> {
33        match self {
34            Value::Primitive(Primitive::Str(s)) => get_string_member(s, name),
35            Value::Object(obj) => obj.get_member(name),
36            _ => Err(Error::UnknownMember {
37                type_name: self.type_name().into(),
38                member: name.to_string(),
39            }),
40        }
41    }
42}
43
44impl Display for Primitive {
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46        write!(f, "{}", self.as_str_lossy())
47    }
48}
49impl Display for Value {
50    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51        write!(f, "{}", self.as_str_lossy())
52    }
53}
54
55impl Debug for Value {
56    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
57        match self {
58            Value::Primitive(p) => write!(f, "{}", p),
59            Value::Object(obj) => write!(f, "{}", obj),
60        }
61    }
62}
63
64impl PartialEq for Value {
65    fn eq(&self, other: &Self) -> bool {
66        match (self, other) {
67            (Value::Primitive(p1), Value::Primitive(p2)) => p1 == p2,
68            (Value::Object(obj1), other) => obj1.equals(other),
69            (other, Value::Object(obj2)) => obj2.equals(other),
70        }
71    }
72}
73
74impl From<Primitive> for Value {
75    fn from(p: Primitive) -> Self {
76        Value::Primitive(p)
77    }
78}
79impl From<i64> for Value {
80    fn from(v: i64) -> Self {
81        Value::Primitive(v.into())
82    }
83}
84impl From<f64> for Value {
85    fn from(v: f64) -> Self {
86        Value::Primitive(v.into())
87    }
88}
89impl From<bool> for Value {
90    fn from(v: bool) -> Self {
91        Value::Primitive(v.into())
92    }
93}
94impl From<String> for Value {
95    fn from(v: String) -> Self {
96        Value::Primitive(v.into())
97    }
98}
99impl From<&str> for Value {
100    fn from(v: &str) -> Self {
101        Value::Primitive(v.into())
102    }
103}
104
105impl TryFrom<Value> for i64 {
106    type Error = Error;
107    fn try_from(v: Value) -> Result<Self> {
108        if let Value::Primitive(p) = v { p.try_into() } else { Err(Error::TypeMismatch("expected int".into())) }
109    }
110}
111impl TryFrom<Value> for f64 {
112    type Error = Error;
113    fn try_from(v: Value) -> Result<Self> {
114        if let Value::Primitive(p) = v { p.try_into() } else { Err(Error::TypeMismatch("expected float".into())) }
115    }
116}
117impl TryFrom<Value> for bool {
118    type Error = Error;
119    fn try_from(v: Value) -> Result<Self> {
120        if let Value::Primitive(p) = v { p.try_into() } else { Err(Error::TypeMismatch("expected bool".into())) }
121    }
122}
123impl TryFrom<Value> for String {
124    type Error = Error;
125    fn try_from(v: Value) -> Result<Self> {
126        if let Value::Primitive(p) = v { p.try_into() } else { Err(Error::TypeMismatch("expected string".into())) }
127    }
128}