1mod environment;
2mod eval;
3mod from;
4mod function;
5mod native;
6mod number;
7mod serde;
8
9use indexmap::IndexMap;
10use rimu_meta::{Span, Spanned};
11
12use std::fmt::{Debug, Display};
13
14pub use self::environment::{Environment, EnvironmentError};
15pub use self::eval::EvalError;
16pub use self::function::{Function, FunctionBody};
17pub use self::native::NativeFunction;
18pub use self::number::Number;
19pub use self::serde::{
20 convert, from_serde_value, to_serde_value, SerdeValue, SerdeValueError, SerdeValueList,
21 SerdeValueObject,
22};
23
24pub type ValueList = Vec<SpannedValue>;
25pub type ValueObject = IndexMap<String, SpannedValue>;
26
27#[derive(Default, Clone, PartialEq)]
28pub enum Value {
29 #[default]
30 Null,
31 Boolean(bool),
32 String(String),
33 Number(Number),
34 Function(Function),
35 List(ValueList),
36 Object(ValueObject),
37}
38
39pub type SpannedValue = Spanned<Value>;
40
41impl From<SpannedValue> for SerdeValue {
42 fn from(value: SpannedValue) -> Self {
43 value.into_inner().into()
44 }
45}
46
47impl From<Value> for SerdeValue {
48 fn from(value: Value) -> Self {
49 match value {
50 Value::Null => SerdeValue::Null,
51 Value::Boolean(boolean) => SerdeValue::Boolean(boolean),
52 Value::String(string) => SerdeValue::String(string),
53 Value::Number(number) => SerdeValue::Number(number),
54 Value::Function(function) => SerdeValue::Function(function),
55 Value::List(list) => SerdeValue::List(convert_value_list_to_serde_value_list(list)),
56 Value::Object(object) => {
57 SerdeValue::Object(convert_value_object_to_serde_value_object(object))
58 }
59 }
60 }
61}
62
63pub fn convert_value_list_to_serde_value_list(list: ValueList) -> SerdeValueList {
64 list.iter().map(|item| item.clone().into()).collect()
65}
66
67pub fn convert_value_object_to_serde_value_object(object: ValueObject) -> SerdeValueObject {
68 SerdeValueObject::from_iter(
69 object
70 .iter()
71 .map(|(key, value)| (key.clone(), value.clone().into()))
72 .collect::<Vec<_>>(),
73 )
74}
75
76impl SerdeValue {
77 pub fn with_span(&self, span: Span) -> SpannedValue {
78 let value = match self {
79 SerdeValue::Null => Value::Null,
80 SerdeValue::Boolean(boolean) => Value::Boolean(boolean.to_owned()),
81 SerdeValue::String(string) => Value::String(string.to_owned()),
82 SerdeValue::Number(number) => Value::Number(number.to_owned()),
83 SerdeValue::Function(function) => Value::Function(function.to_owned()),
84 SerdeValue::List(list) => Value::List(
85 list.iter()
86 .map(|item| item.clone().with_span(span.clone()))
87 .collect(),
88 ),
89 SerdeValue::Object(object) => Value::Object(ValueObject::from_iter(
90 object
91 .iter()
92 .map(|(key, value)| (key.clone(), value.clone().with_span(span.clone())))
93 .collect::<Vec<_>>(),
94 )),
95 };
96 Spanned::new(value, span)
97 }
98}
99
100impl Debug for Value {
101 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
102 match self {
103 Value::Null => formatter.write_str("Null"),
104 Value::Boolean(boolean) => match boolean {
105 true => formatter.write_str("true"),
106 false => formatter.write_str("false"),
107 },
108 Value::String(string) => write!(formatter, "String({:?})", string),
109 Value::Number(number) => write!(formatter, "Number({})", number),
110 Value::Function(function) => {
111 write!(formatter, "Function({:?})", function)
112 }
113 Value::List(list) => {
114 formatter.write_str("List ")?;
115 formatter.debug_list().entries(list).finish()
116 }
117 Value::Object(object) => {
118 formatter.write_str("Object ")?;
119 formatter.debug_map().entries(object).finish()
120 }
121 }
122 }
123}
124
125impl Display for Value {
126 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
127 match self {
128 Value::Null => write!(f, "null"),
129 Value::Boolean(boolean) => write!(f, "{}", boolean),
130 Value::String(string) => write!(f, "{}", string),
131 Value::Number(number) => write!(f, "{}", number),
132 Value::Function(function) => write!(f, "{}", function),
133 Value::List(list) => {
134 let items = list
135 .iter()
136 .map(|value| value.to_string())
137 .collect::<Vec<String>>()
138 .join(", ");
139 write!(f, "[{}]", items)
140 }
141 Value::Object(object) => {
142 let entries = object
143 .iter()
144 .map(|(key, value)| format!("\"{}\": {}", key, value))
145 .collect::<Vec<String>>()
146 .join(", ");
147 write!(f, "{{{}}}", entries)
148 }
149 }
150 }
151}
152
153impl From<Value> for bool {
155 fn from(value: Value) -> Self {
156 #[allow(clippy::match_like_matches_macro)]
157 match value {
158 Value::Null | Value::Boolean(false) => false,
159 _ => true,
160 }
161 }
162}