fastn_resolved/
value.rs

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