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>, },
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}