simple_expressions/types/
value.rs1use 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}