fastn_type/
value.rs

1#[derive(Debug, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
2pub enum PropertyValue {
3    Value {
4        value: fastn_type::Value,
5        is_mutable: bool,
6        line_number: usize,
7    },
8    Reference {
9        name: String,
10        kind: fastn_type::KindData,
11        source: fastn_type::PropertyValueSource,
12        is_mutable: bool,
13        line_number: usize,
14    },
15    Clone {
16        name: String,
17        kind: fastn_type::KindData,
18        source: fastn_type::PropertyValueSource,
19        is_mutable: bool,
20        line_number: usize,
21    },
22    FunctionCall(fastn_type::FunctionCall),
23}
24
25impl PropertyValue {
26    pub fn line_number(&self) -> usize {
27        match self {
28            PropertyValue::Value { line_number, .. }
29            | PropertyValue::Reference { line_number, .. }
30            | PropertyValue::Clone { line_number, .. }
31            | PropertyValue::FunctionCall(fastn_type::FunctionCall { line_number, .. }) => {
32                *line_number
33            }
34        }
35    }
36
37    pub fn is_mutable(&self) -> bool {
38        match self {
39            PropertyValue::Value { is_mutable, .. }
40            | PropertyValue::Reference { is_mutable, .. }
41            | PropertyValue::Clone { is_mutable, .. }
42            | PropertyValue::FunctionCall(fastn_type::FunctionCall { is_mutable, .. }) => {
43                *is_mutable
44            }
45        }
46    }
47
48    pub fn get_reference_or_clone(&self) -> Option<&String> {
49        match self {
50            PropertyValue::Reference { name, .. } | PropertyValue::Clone { name, .. } => Some(name),
51            _ => None,
52        }
53    }
54
55    pub fn reference_name(&self) -> Option<&String> {
56        match self {
57            PropertyValue::Reference { name, .. } => Some(name),
58            _ => None,
59        }
60    }
61
62    pub fn kind(&self) -> fastn_type::Kind {
63        match self {
64            PropertyValue::Value { value, .. } => value.kind(),
65            PropertyValue::Reference { kind, .. } => kind.kind.to_owned(),
66            PropertyValue::Clone { kind, .. } => kind.kind.to_owned(),
67            PropertyValue::FunctionCall(fastn_type::FunctionCall { kind, .. }) => {
68                kind.kind.to_owned()
69            }
70        }
71    }
72
73    pub fn set_reference_or_clone(&mut self, new_name: &str) {
74        match self {
75            PropertyValue::Reference { name, .. } | PropertyValue::Clone { name, .. } => {
76                *name = new_name.to_string();
77            }
78            _ => {}
79        }
80    }
81
82    pub fn is_value(&self) -> bool {
83        matches!(self, fastn_type::PropertyValue::Value { .. })
84    }
85
86    pub fn is_clone(&self) -> bool {
87        matches!(self, fastn_type::PropertyValue::Clone { .. })
88    }
89
90    pub fn get_function(&self) -> Option<&fastn_type::FunctionCall> {
91        match self {
92            PropertyValue::FunctionCall(f) => Some(f),
93            _ => None,
94        }
95    }
96
97    pub fn new_none(kind: fastn_type::KindData, line_number: usize) -> fastn_type::PropertyValue {
98        fastn_type::PropertyValue::Value {
99            value: fastn_type::Value::new_none(kind),
100            is_mutable: false,
101            line_number,
102        }
103    }
104
105    pub fn set_mutable(&mut self, mutable: bool) {
106        match self {
107            PropertyValue::Value { is_mutable, .. }
108            | PropertyValue::Reference { is_mutable, .. }
109            | PropertyValue::Clone { is_mutable, .. }
110            | PropertyValue::FunctionCall(fastn_type::FunctionCall { is_mutable, .. }) => {
111                *is_mutable = mutable;
112            }
113        }
114    }
115}
116
117#[derive(Debug, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
118pub enum PropertyValueSource {
119    Global,
120    Local(String),
121    Loop(String),
122}
123
124impl PropertyValueSource {
125    pub fn is_global(&self) -> bool {
126        PropertyValueSource::Global.eq(self)
127    }
128
129    pub fn is_local(&self, name: &str) -> bool {
130        matches!(self, PropertyValueSource::Local(l_name) if l_name.eq(name))
131    }
132
133    pub fn get_name(&self) -> Option<String> {
134        match self {
135            PropertyValueSource::Local(s) | PropertyValueSource::Loop(s) => Some(s.to_owned()),
136            _ => None,
137        }
138    }
139}
140
141#[derive(Debug, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
142pub enum Value {
143    String {
144        text: String,
145    },
146    Integer {
147        value: i64,
148    },
149    Decimal {
150        value: f64,
151    },
152    Boolean {
153        value: bool,
154    },
155    Object {
156        values: fastn_type::Map<PropertyValue>,
157    },
158    Record {
159        name: String,
160        fields: fastn_type::Map<PropertyValue>,
161    },
162    KwArgs {
163        arguments: fastn_type::Map<PropertyValue>,
164    },
165    OrType {
166        name: String,
167        variant: String,
168        full_variant: String,
169        value: Box<PropertyValue>, // Todo: Make it optional
170    },
171    List {
172        data: Vec<PropertyValue>,
173        kind: fastn_type::KindData,
174    },
175    Optional {
176        data: Box<Option<Value>>,
177        kind: fastn_type::KindData,
178    },
179    UI {
180        name: String,
181        kind: fastn_type::KindData,
182        component: fastn_type::ComponentInvocation,
183    },
184    Module {
185        name: String,
186        things: fastn_type::Map<fastn_type::ModuleThing>,
187    },
188}
189
190impl Value {
191    pub fn new_none(kind: fastn_type::KindData) -> fastn_type::Value {
192        fastn_type::Value::Optional {
193            data: Box::new(None),
194            kind,
195        }
196    }
197
198    pub fn new_string(text: &str) -> fastn_type::Value {
199        fastn_type::Value::String {
200            text: text.to_string(),
201        }
202    }
203
204    pub fn new_or_type(
205        name: &str,
206        variant: &str,
207        full_variant: &str,
208        value: fastn_type::PropertyValue,
209    ) -> fastn_type::Value {
210        fastn_type::Value::OrType {
211            name: name.to_string(),
212            variant: variant.to_string(),
213            full_variant: full_variant.to_string(),
214            value: Box::new(value),
215        }
216    }
217
218    pub fn inner(&self) -> Option<Self> {
219        match self {
220            Value::Optional { data, .. } => data.as_ref().to_owned(),
221            t => Some(t.to_owned()),
222        }
223    }
224
225    pub fn into_property_value(self, is_mutable: bool, line_number: usize) -> PropertyValue {
226        PropertyValue::Value {
227            value: self,
228            is_mutable,
229            line_number,
230        }
231    }
232
233    pub fn kind(&self) -> fastn_type::Kind {
234        match self {
235            Value::String { .. } => fastn_type::Kind::string(),
236            Value::Integer { .. } => fastn_type::Kind::integer(),
237            Value::Decimal { .. } => fastn_type::Kind::decimal(),
238            Value::Boolean { .. } => fastn_type::Kind::boolean(),
239            Value::Object { .. } => fastn_type::Kind::object(),
240            Value::Record { name, .. } => fastn_type::Kind::record(name),
241            Value::KwArgs { .. } => fastn_type::Kind::kwargs(),
242            Value::List { kind, .. } => kind.kind.clone().into_list(),
243            Value::Optional { kind, .. } => fastn_type::Kind::Optional {
244                kind: Box::new(kind.kind.clone()),
245            },
246            Value::UI { name, .. } => fastn_type::Kind::ui_with_name(name),
247            Value::OrType {
248                name,
249                variant,
250                full_variant,
251                ..
252            } => fastn_type::Kind::or_type_with_variant(name, variant, full_variant),
253            Value::Module { .. } => fastn_type::Kind::module(),
254        }
255    }
256
257    pub fn is_record(&self, rec_name: &str) -> bool {
258        matches!(self, Self::Record { name, .. } if rec_name.eq(name))
259    }
260
261    pub fn is_or_type_variant(&self, or_variant: &str) -> bool {
262        matches!(self, Self::OrType { variant, .. } if or_variant.eq(variant))
263    }
264
265    pub fn ref_inner(&self) -> Option<&Self> {
266        match self {
267            Value::Optional { data, .. } => data.as_ref().as_ref(),
268            t => Some(t),
269        }
270    }
271
272    pub fn module_name_optional(&self) -> Option<String> {
273        match self {
274            fastn_type::Value::Module { name, .. } => Some(name.to_string()),
275            _ => None,
276        }
277    }
278
279    pub fn mut_module_optional(
280        &mut self,
281    ) -> Option<(&str, &mut fastn_type::Map<fastn_type::ModuleThing>)> {
282        match self {
283            fastn_type::Value::Module { name, things } => Some((name, things)),
284            _ => None,
285        }
286    }
287
288    pub fn is_null(&self) -> bool {
289        if let Self::String { text, .. } = self {
290            return text.is_empty();
291        }
292        if let Self::Optional { data, .. } = self {
293            let value = if let Some(fastn_type::Value::String { text, .. }) = data.as_ref() {
294                text.is_empty()
295            } else {
296                false
297            };
298            if data.as_ref().eq(&None) || value {
299                return true;
300            }
301        }
302        false
303    }
304
305    pub fn is_empty(&self) -> bool {
306        if let Self::List { data, .. } = self {
307            if data.is_empty() {
308                return true;
309            }
310        }
311        false
312    }
313
314    pub fn is_equal(&self, other: &Self) -> bool {
315        match (self.to_owned().inner(), other.to_owned().inner()) {
316            (Some(Value::String { text: ref a, .. }), Some(Value::String { text: ref b, .. })) => {
317                a == b
318            }
319            (a, b) => a == b,
320        }
321    }
322}