1use crate::call_type::{CallType, InstanceCreationType};
16use crate::generic_type_parameter::GenericTypeParameter;
17use crate::inferred_type::{DefaultType, TypeOrigin};
18use crate::parser::block::block;
19use crate::parser::type_name::TypeName;
20use crate::rib_source_span::SourceSpan;
21use crate::rib_type_error::RibTypeErrorInternal;
22use crate::{
23 from_string, text, type_checker, type_inference, ComponentDependencies, ComponentDependencyKey,
24 DynamicParsedFunctionName, ExprVisitor, GlobalVariableTypeSpec, InferredType,
25 InstanceIdentifier, ParsedFunctionName, VariableId,
26};
27use bigdecimal::{BigDecimal, FromPrimitive, ToPrimitive};
28use combine::parser::char::spaces;
29use combine::stream::position;
30use combine::Parser;
31use combine::{eof, EasyParser};
32use golem_api_grpc::proto::golem::rib::range_expr::RangeExpr;
33use golem_wasm_ast::analysis::AnalysedType;
34use golem_wasm_rpc::{IntoValueAndType, ValueAndType};
35use serde::{Deserialize, Serialize, Serializer};
36use serde_json::Value;
37use std::collections::VecDeque;
38use std::fmt::Display;
39use std::ops::Deref;
40use std::str::FromStr;
41
42#[derive(Debug, Hash, Clone, PartialEq, Eq, PartialOrd, Ord)]
43pub enum Expr {
44 Let {
45 variable_id: VariableId,
46 type_annotation: Option<TypeName>,
47 expr: Box<Expr>,
48 inferred_type: InferredType,
49 source_span: SourceSpan,
50 },
51 SelectField {
52 expr: Box<Expr>,
53 field: String,
54 type_annotation: Option<TypeName>,
55 inferred_type: InferredType,
56 source_span: SourceSpan,
57 },
58 SelectIndex {
59 expr: Box<Expr>,
60 index: Box<Expr>,
61 type_annotation: Option<TypeName>,
62 inferred_type: InferredType,
63 source_span: SourceSpan,
64 },
65 Sequence {
66 exprs: Vec<Expr>,
67 type_annotation: Option<TypeName>,
68 inferred_type: InferredType,
69 source_span: SourceSpan,
70 },
71 Range {
72 range: Range,
73 type_annotation: Option<TypeName>,
74 inferred_type: InferredType,
75 source_span: SourceSpan,
76 },
77 Record {
78 exprs: Vec<(String, Box<Expr>)>,
79 type_annotation: Option<TypeName>,
80 inferred_type: InferredType,
81 source_span: SourceSpan,
82 },
83 Tuple {
84 exprs: Vec<Expr>,
85 type_annotation: Option<TypeName>,
86 inferred_type: InferredType,
87 source_span: SourceSpan,
88 },
89 Literal {
90 value: String,
91 type_annotation: Option<TypeName>,
92 inferred_type: InferredType,
93 source_span: SourceSpan,
94 },
95 Number {
96 number: Number,
97 type_annotation: Option<TypeName>,
98 inferred_type: InferredType,
99 source_span: SourceSpan,
100 },
101 Flags {
102 flags: Vec<String>,
103 type_annotation: Option<TypeName>,
104 inferred_type: InferredType,
105 source_span: SourceSpan,
106 },
107 Identifier {
108 variable_id: VariableId,
109 type_annotation: Option<TypeName>,
110 inferred_type: InferredType,
111 source_span: SourceSpan,
112 },
113 Boolean {
114 value: bool,
115 type_annotation: Option<TypeName>,
116 inferred_type: InferredType,
117 source_span: SourceSpan,
118 },
119 Concat {
120 exprs: Vec<Expr>,
121 type_annotation: Option<TypeName>,
122 inferred_type: InferredType,
123 source_span: SourceSpan,
124 },
125 ExprBlock {
126 exprs: Vec<Expr>,
127 type_annotation: Option<TypeName>,
128 inferred_type: InferredType,
129 source_span: SourceSpan,
130 },
131 Not {
132 expr: Box<Expr>,
133 inferred_type: InferredType,
134 type_annotation: Option<TypeName>,
135 source_span: SourceSpan,
136 },
137 GreaterThan {
138 lhs: Box<Expr>,
139 rhs: Box<Expr>,
140 type_annotation: Option<TypeName>,
141 inferred_type: InferredType,
142 source_span: SourceSpan,
143 },
144 And {
145 lhs: Box<Expr>,
146 rhs: Box<Expr>,
147 type_annotation: Option<TypeName>,
148 inferred_type: InferredType,
149 source_span: SourceSpan,
150 },
151 Or {
152 lhs: Box<Expr>,
153 rhs: Box<Expr>,
154 type_annotation: Option<TypeName>,
155 inferred_type: InferredType,
156 source_span: SourceSpan,
157 },
158 GreaterThanOrEqualTo {
159 lhs: Box<Expr>,
160 rhs: Box<Expr>,
161 type_annotation: Option<TypeName>,
162 inferred_type: InferredType,
163 source_span: SourceSpan,
164 },
165 LessThanOrEqualTo {
166 lhs: Box<Expr>,
167 rhs: Box<Expr>,
168 type_annotation: Option<TypeName>,
169 inferred_type: InferredType,
170 source_span: SourceSpan,
171 },
172 Plus {
173 lhs: Box<Expr>,
174 rhs: Box<Expr>,
175 type_annotation: Option<TypeName>,
176 inferred_type: InferredType,
177 source_span: SourceSpan,
178 },
179 Multiply {
180 lhs: Box<Expr>,
181 rhs: Box<Expr>,
182 type_annotation: Option<TypeName>,
183 inferred_type: InferredType,
184 source_span: SourceSpan,
185 },
186 Minus {
187 lhs: Box<Expr>,
188 rhs: Box<Expr>,
189 type_annotation: Option<TypeName>,
190 inferred_type: InferredType,
191 source_span: SourceSpan,
192 },
193 Divide {
194 lhs: Box<Expr>,
195 rhs: Box<Expr>,
196 type_annotation: Option<TypeName>,
197 inferred_type: InferredType,
198 source_span: SourceSpan,
199 },
200 EqualTo {
201 lhs: Box<Expr>,
202 rhs: Box<Expr>,
203 type_annotation: Option<TypeName>,
204 inferred_type: InferredType,
205 source_span: SourceSpan,
206 },
207 LessThan {
208 lhs: Box<Expr>,
209 rhs: Box<Expr>,
210 type_annotation: Option<TypeName>,
211 inferred_type: InferredType,
212 source_span: SourceSpan,
213 },
214 Cond {
215 cond: Box<Expr>,
216 lhs: Box<Expr>,
217 rhs: Box<Expr>,
218 type_annotation: Option<TypeName>,
219 inferred_type: InferredType,
220 source_span: SourceSpan,
221 },
222 PatternMatch {
223 predicate: Box<Expr>,
224 match_arms: Vec<MatchArm>,
225 type_annotation: Option<TypeName>,
226 inferred_type: InferredType,
227 source_span: SourceSpan,
228 },
229 Option {
230 expr: Option<Box<Expr>>,
231 type_annotation: Option<TypeName>,
232 inferred_type: InferredType,
233 source_span: SourceSpan,
234 },
235 Result {
236 expr: Result<Box<Expr>, Box<Expr>>,
237 type_annotation: Option<TypeName>,
238 inferred_type: InferredType,
239 source_span: SourceSpan,
240 },
241 Call {
247 call_type: CallType,
248 generic_type_parameter: Option<GenericTypeParameter>,
249 args: Vec<Expr>,
250 type_annotation: Option<TypeName>,
251 inferred_type: InferredType,
252 source_span: SourceSpan,
253 },
254 InvokeMethodLazy {
260 lhs: Box<Expr>,
261 method: String,
262 generic_type_parameter: Option<GenericTypeParameter>,
263 args: Vec<Expr>,
264 type_annotation: Option<TypeName>,
265 inferred_type: InferredType,
266 source_span: SourceSpan,
267 },
268 Unwrap {
269 expr: Box<Expr>,
270 inferred_type: InferredType,
271 type_annotation: Option<TypeName>,
272 source_span: SourceSpan,
273 },
274 Throw {
275 message: String,
276 inferred_type: InferredType,
277 type_annotation: Option<TypeName>,
278 source_span: SourceSpan,
279 },
280 GetTag {
281 expr: Box<Expr>,
282 inferred_type: InferredType,
283 type_annotation: Option<TypeName>,
284 source_span: SourceSpan,
285 },
286 ListComprehension {
287 iterated_variable: VariableId,
288 iterable_expr: Box<Expr>,
289 yield_expr: Box<Expr>,
290 type_annotation: Option<TypeName>,
291 inferred_type: InferredType,
292 source_span: SourceSpan,
293 },
294 ListReduce {
295 reduce_variable: VariableId,
296 iterated_variable: VariableId,
297 iterable_expr: Box<Expr>,
298 type_annotation: Option<TypeName>,
299 yield_expr: Box<Expr>,
300 init_value_expr: Box<Expr>,
301 inferred_type: InferredType,
302 source_span: SourceSpan,
303 },
304 Length {
305 expr: Box<Expr>,
306 inferred_type: InferredType,
307 type_annotation: Option<TypeName>,
308 source_span: SourceSpan,
309 },
310
311 GenerateWorkerName {
312 inferred_type: InferredType,
313 type_annotation: Option<TypeName>,
314 source_span: SourceSpan,
315 variable_id: Option<VariableId>,
316 },
317}
318
319impl Expr {
320 pub fn as_record(&self) -> Option<Vec<(String, Expr)>> {
321 match self {
322 Expr::Record { exprs: fields, .. } => Some(
323 fields
324 .iter()
325 .map(|(k, v)| (k.clone(), v.deref().clone()))
326 .collect::<Vec<_>>(),
327 ),
328 _ => None,
329 }
330 }
331 pub fn from_text(input: &str) -> Result<Expr, String> {
348 if input.trim().ends_with(';') {
349 return Err("unexpected `;` at the end of rib expression. \nnote: `;` is used to separate expressions, but it should not appear after the last expression (which is the return value)".to_string());
350 }
351
352 spaces()
353 .with(block().skip(eof()))
354 .easy_parse(position::Stream::new(input))
355 .map(|t| t.0)
356 .map_err(|err| format!("{err}"))
357 }
358
359 pub fn lookup(&self, source_span: &SourceSpan) -> Option<Expr> {
360 let mut expr = self.clone();
361 find_expr(&mut expr, source_span)
362 }
363
364 pub fn is_literal(&self) -> bool {
365 matches!(self, Expr::Literal { .. })
366 }
367
368 pub fn is_block(&self) -> bool {
369 matches!(self, Expr::ExprBlock { .. })
370 }
371
372 pub fn is_number(&self) -> bool {
373 matches!(self, Expr::Number { .. })
374 }
375
376 pub fn is_record(&self) -> bool {
377 matches!(self, Expr::Record { .. })
378 }
379
380 pub fn is_result(&self) -> bool {
381 matches!(self, Expr::Result { .. })
382 }
383
384 pub fn is_option(&self) -> bool {
385 matches!(self, Expr::Option { .. })
386 }
387
388 pub fn is_tuple(&self) -> bool {
389 matches!(self, Expr::Tuple { .. })
390 }
391
392 pub fn is_list(&self) -> bool {
393 matches!(self, Expr::Sequence { .. })
394 }
395
396 pub fn is_flags(&self) -> bool {
397 matches!(self, Expr::Flags { .. })
398 }
399
400 pub fn is_identifier(&self) -> bool {
401 matches!(self, Expr::Identifier { .. })
402 }
403
404 pub fn is_select_field(&self) -> bool {
405 matches!(self, Expr::SelectField { .. })
406 }
407
408 pub fn is_if_else(&self) -> bool {
409 matches!(self, Expr::Cond { .. })
410 }
411
412 pub fn is_function_call(&self) -> bool {
413 matches!(self, Expr::Call { .. })
414 }
415
416 pub fn is_match_expr(&self) -> bool {
417 matches!(self, Expr::PatternMatch { .. })
418 }
419
420 pub fn is_boolean(&self) -> bool {
421 matches!(self, Expr::Boolean { .. })
422 }
423
424 pub fn is_comparison(&self) -> bool {
425 matches!(
426 self,
427 Expr::GreaterThan { .. }
428 | Expr::GreaterThanOrEqualTo { .. }
429 | Expr::LessThanOrEqualTo { .. }
430 | Expr::EqualTo { .. }
431 | Expr::LessThan { .. }
432 )
433 }
434
435 pub fn is_concat(&self) -> bool {
436 matches!(self, Expr::Concat { .. })
437 }
438
439 pub fn is_multiple(&self) -> bool {
440 matches!(self, Expr::ExprBlock { .. })
441 }
442
443 pub fn inbuilt_variant(&self) -> Option<(String, Option<Expr>)> {
444 match self {
445 Expr::Option {
446 expr: Some(expr), ..
447 } => Some(("some".to_string(), Some(expr.deref().clone()))),
448 Expr::Option { expr: None, .. } => Some(("some".to_string(), None)),
449 Expr::Result { expr: Ok(expr), .. } => {
450 Some(("ok".to_string(), Some(expr.deref().clone())))
451 }
452 Expr::Result {
453 expr: Err(expr), ..
454 } => Some(("err".to_string(), Some(expr.deref().clone()))),
455 _ => None,
456 }
457 }
458 pub fn unwrap(&self) -> Self {
459 Expr::Unwrap {
460 expr: Box::new(self.clone()),
461 inferred_type: InferredType::unknown(),
462 source_span: SourceSpan::default(),
463 type_annotation: None,
464 }
465 }
466
467 pub fn length(expr: Expr) -> Self {
468 Expr::Length {
469 expr: Box::new(expr),
470 inferred_type: InferredType::u64(),
471 source_span: SourceSpan::default(),
472 type_annotation: None,
473 }
474 }
475
476 pub fn boolean(value: bool) -> Self {
477 Expr::Boolean {
478 value,
479 inferred_type: InferredType::bool(),
480 source_span: SourceSpan::default(),
481 type_annotation: None,
482 }
483 }
484
485 pub fn and(left: Expr, right: Expr) -> Self {
486 Expr::And {
487 lhs: Box::new(left),
488 rhs: Box::new(right),
489 inferred_type: InferredType::bool(),
490 source_span: SourceSpan::default(),
491 type_annotation: None,
492 }
493 }
494
495 pub fn throw(message: impl AsRef<str>) -> Self {
496 Expr::Throw {
497 message: message.as_ref().to_string(),
498 inferred_type: InferredType::unknown(),
499 source_span: SourceSpan::default(),
500 type_annotation: None,
501 }
502 }
503
504 pub fn generate_worker_name(variable_id: Option<VariableId>) -> Self {
505 Expr::GenerateWorkerName {
506 inferred_type: InferredType::string(),
507 type_annotation: None,
508 source_span: SourceSpan::default(),
509 variable_id,
510 }
511 }
512
513 pub fn plus(left: Expr, right: Expr) -> Self {
514 Expr::Plus {
515 lhs: Box::new(left),
516 rhs: Box::new(right),
517 inferred_type: InferredType::unknown(),
518 source_span: SourceSpan::default(),
519 type_annotation: None,
520 }
521 }
522
523 pub fn minus(left: Expr, right: Expr) -> Self {
524 Expr::Minus {
525 lhs: Box::new(left),
526 rhs: Box::new(right),
527 inferred_type: InferredType::unknown(),
528 source_span: SourceSpan::default(),
529 type_annotation: None,
530 }
531 }
532
533 pub fn divide(left: Expr, right: Expr) -> Self {
534 Expr::Divide {
535 lhs: Box::new(left),
536 rhs: Box::new(right),
537 inferred_type: InferredType::unknown(),
538 source_span: SourceSpan::default(),
539 type_annotation: None,
540 }
541 }
542
543 pub fn multiply(left: Expr, right: Expr) -> Self {
544 Expr::Multiply {
545 lhs: Box::new(left),
546 rhs: Box::new(right),
547 inferred_type: InferredType::unknown(),
548 source_span: SourceSpan::default(),
549 type_annotation: None,
550 }
551 }
552
553 pub fn and_combine(conditions: Vec<Expr>) -> Option<Expr> {
554 let mut cond: Option<Expr> = None;
555
556 for i in conditions {
557 let left = Box::new(cond.clone().unwrap_or(Expr::boolean(true)));
558 cond = Some(Expr::And {
559 lhs: left,
560 rhs: Box::new(i),
561 inferred_type: InferredType::bool(),
562 source_span: SourceSpan::default(),
563 type_annotation: None,
564 });
565 }
566
567 cond
568 }
569
570 pub fn call_worker_function(
571 dynamic_parsed_fn_name: DynamicParsedFunctionName,
572 generic_type_parameter: Option<GenericTypeParameter>,
573 module_identifier: Option<InstanceIdentifier>,
574 args: Vec<Expr>,
575 component_info: Option<ComponentDependencyKey>,
576 ) -> Self {
577 Expr::Call {
578 call_type: CallType::Function {
579 function_name: dynamic_parsed_fn_name,
580 instance_identifier: module_identifier.map(Box::new),
581 component_info,
582 },
583 generic_type_parameter,
584 args,
585 inferred_type: InferredType::unknown(),
586 source_span: SourceSpan::default(),
587 type_annotation: None,
588 }
589 }
590
591 pub fn call(
592 call_type: CallType,
593 generic_type_parameter: Option<GenericTypeParameter>,
594 args: Vec<Expr>,
595 ) -> Self {
596 Expr::Call {
597 call_type,
598 generic_type_parameter,
599 args,
600 inferred_type: InferredType::unknown(),
601 source_span: SourceSpan::default(),
602 type_annotation: None,
603 }
604 }
605
606 pub fn invoke_worker_function(
607 lhs: Expr,
608 function_name: String,
609 generic_type_parameter: Option<GenericTypeParameter>,
610 args: Vec<Expr>,
611 ) -> Self {
612 Expr::InvokeMethodLazy {
613 lhs: Box::new(lhs),
614 method: function_name,
615 generic_type_parameter,
616 args,
617 inferred_type: InferredType::unknown(),
618 source_span: SourceSpan::default(),
619 type_annotation: None,
620 }
621 }
622
623 pub fn concat(expressions: Vec<Expr>) -> Self {
624 Expr::Concat {
625 exprs: expressions,
626 inferred_type: InferredType::string(),
627 source_span: SourceSpan::default(),
628 type_annotation: None,
629 }
630 }
631
632 pub fn cond(cond: Expr, lhs: Expr, rhs: Expr) -> Self {
633 Expr::Cond {
634 cond: Box::new(cond),
635 lhs: Box::new(lhs),
636 rhs: Box::new(rhs),
637 inferred_type: InferredType::unknown(),
638 source_span: SourceSpan::default(),
639 type_annotation: None,
640 }
641 }
642
643 pub fn equal_to(left: Expr, right: Expr) -> Self {
644 Expr::EqualTo {
645 lhs: Box::new(left),
646 rhs: Box::new(right),
647 inferred_type: InferredType::bool(),
648 source_span: SourceSpan::default(),
649 type_annotation: None,
650 }
651 }
652
653 pub fn err(expr: Expr, type_annotation: Option<TypeName>) -> Self {
654 let inferred_type = expr.inferred_type();
655 Expr::Result {
656 expr: Err(Box::new(expr)),
657 type_annotation,
658 inferred_type: InferredType::result(Some(InferredType::unknown()), Some(inferred_type)),
659 source_span: SourceSpan::default(),
660 }
661 }
662
663 pub fn flags(flags: Vec<String>) -> Self {
664 Expr::Flags {
665 flags: flags.clone(),
666 inferred_type: InferredType::flags(flags),
667 source_span: SourceSpan::default(),
668 type_annotation: None,
669 }
670 }
671
672 pub fn greater_than(left: Expr, right: Expr) -> Self {
673 Expr::GreaterThan {
674 lhs: Box::new(left),
675 rhs: Box::new(right),
676 inferred_type: InferredType::bool(),
677 source_span: SourceSpan::default(),
678 type_annotation: None,
679 }
680 }
681
682 pub fn greater_than_or_equal_to(left: Expr, right: Expr) -> Self {
683 Expr::GreaterThanOrEqualTo {
684 lhs: Box::new(left),
685 rhs: Box::new(right),
686 inferred_type: InferredType::bool(),
687 source_span: SourceSpan::default(),
688 type_annotation: None,
689 }
690 }
691
692 pub fn identifier_global(name: impl AsRef<str>, type_annotation: Option<TypeName>) -> Self {
694 Expr::Identifier {
695 variable_id: VariableId::global(name.as_ref().to_string()),
696 type_annotation,
697 inferred_type: InferredType::unknown(),
698 source_span: SourceSpan::default(),
699 }
700 }
701
702 pub fn identifier_local(
703 name: impl AsRef<str>,
704 id: u32,
705 type_annotation: Option<TypeName>,
706 ) -> Self {
707 Expr::Identifier {
708 variable_id: VariableId::local(name.as_ref(), id),
709 type_annotation,
710 inferred_type: InferredType::unknown(),
711 source_span: SourceSpan::default(),
712 }
713 }
714
715 pub fn identifier_with_variable_id(
716 variable_id: VariableId,
717 type_annotation: Option<TypeName>,
718 ) -> Self {
719 Expr::Identifier {
720 variable_id,
721 type_annotation,
722 inferred_type: InferredType::unknown(),
723 source_span: SourceSpan::default(),
724 }
725 }
726
727 pub fn less_than(left: Expr, right: Expr) -> Self {
728 Expr::LessThan {
729 lhs: Box::new(left),
730 rhs: Box::new(right),
731 inferred_type: InferredType::bool(),
732 source_span: SourceSpan::default(),
733 type_annotation: None,
734 }
735 }
736
737 pub fn less_than_or_equal_to(left: Expr, right: Expr) -> Self {
738 Expr::LessThanOrEqualTo {
739 lhs: Box::new(left),
740 rhs: Box::new(right),
741 inferred_type: InferredType::bool(),
742 source_span: SourceSpan::default(),
743 type_annotation: None,
744 }
745 }
746
747 pub fn range(from: Expr, to: Expr) -> Self {
748 Expr::Range {
749 range: Range::Range {
750 from: Box::new(from.clone()),
751 to: Box::new(to.clone()),
752 },
753 inferred_type: InferredType::range(from.inferred_type(), Some(to.inferred_type())),
754 source_span: SourceSpan::default(),
755 type_annotation: None,
756 }
757 }
758
759 pub fn range_from(from: Expr) -> Self {
760 Expr::Range {
761 range: Range::RangeFrom {
762 from: Box::new(from.clone()),
763 },
764 inferred_type: InferredType::range(from.inferred_type(), None),
765 source_span: SourceSpan::default(),
766 type_annotation: None,
767 }
768 }
769
770 pub fn range_inclusive(from: Expr, to: Expr) -> Self {
771 Expr::Range {
772 range: Range::RangeInclusive {
773 from: Box::new(from.clone()),
774 to: Box::new(to.clone()),
775 },
776 inferred_type: InferredType::range(from.inferred_type(), Some(to.inferred_type())),
777 source_span: SourceSpan::default(),
778 type_annotation: None,
779 }
780 }
781
782 pub fn let_binding(
783 name: impl AsRef<str>,
784 expr: Expr,
785 type_annotation: Option<TypeName>,
786 ) -> Self {
787 Expr::Let {
788 variable_id: VariableId::global(name.as_ref().to_string()),
789 type_annotation,
790 expr: Box::new(expr),
791 source_span: SourceSpan::default(),
792 inferred_type: InferredType::tuple(vec![]),
793 }
794 }
795
796 pub fn let_binding_with_variable_id(
797 variable_id: VariableId,
798 expr: Expr,
799 type_annotation: Option<TypeName>,
800 ) -> Self {
801 Expr::Let {
802 variable_id,
803 type_annotation,
804 expr: Box::new(expr),
805 source_span: SourceSpan::default(),
806 inferred_type: InferredType::tuple(vec![]),
807 }
808 }
809
810 pub fn typed_list_reduce(
811 reduce_variable: VariableId,
812 iterated_variable: VariableId,
813 iterable_expr: Expr,
814 init_value_expr: Expr,
815 yield_expr: Expr,
816 inferred_type: InferredType,
817 ) -> Self {
818 Expr::ListReduce {
819 reduce_variable,
820 iterated_variable,
821 iterable_expr: Box::new(iterable_expr),
822 yield_expr: Box::new(yield_expr),
823 init_value_expr: Box::new(init_value_expr),
824 inferred_type,
825 source_span: SourceSpan::default(),
826 type_annotation: None,
827 }
828 }
829
830 pub fn list_reduce(
831 reduce_variable: VariableId,
832 iterated_variable: VariableId,
833 iterable_expr: Expr,
834 init_value_expr: Expr,
835 yield_expr: Expr,
836 ) -> Self {
837 Expr::typed_list_reduce(
838 reduce_variable,
839 iterated_variable,
840 iterable_expr,
841 init_value_expr,
842 yield_expr,
843 InferredType::unknown(),
844 )
845 }
846
847 pub fn list_comprehension_typed(
848 iterated_variable: VariableId,
849 iterable_expr: Expr,
850 yield_expr: Expr,
851 inferred_type: InferredType,
852 ) -> Self {
853 Expr::ListComprehension {
854 iterated_variable,
855 iterable_expr: Box::new(iterable_expr),
856 yield_expr: Box::new(yield_expr),
857 inferred_type,
858 source_span: SourceSpan::default(),
859 type_annotation: None,
860 }
861 }
862
863 pub fn list_comprehension(
864 variable_id: VariableId,
865 iterable_expr: Expr,
866 yield_expr: Expr,
867 ) -> Self {
868 Expr::list_comprehension_typed(
869 variable_id,
870 iterable_expr,
871 yield_expr,
872 InferredType::list(InferredType::unknown()),
873 )
874 }
875
876 pub fn bind_global_variable_types(&mut self, type_spec: &Vec<GlobalVariableTypeSpec>) {
877 type_inference::bind_global_variable_types(self, type_spec)
878 }
879
880 pub fn bind_instance_types(&mut self) {
881 type_inference::bind_instance_types(self)
882 }
883
884 pub fn literal(value: impl AsRef<str>) -> Self {
885 let default_type = DefaultType::String;
886
887 Expr::Literal {
888 value: value.as_ref().to_string(),
889 inferred_type: InferredType::from(&default_type),
890 source_span: SourceSpan::default(),
891 type_annotation: None,
892 }
893 }
894
895 pub fn empty_expr() -> Self {
896 Expr::literal("")
897 }
898
899 pub fn expr_block(expressions: Vec<Expr>) -> Self {
900 let inferred_type = expressions
901 .last()
902 .map_or(InferredType::unknown(), |e| e.inferred_type());
903
904 Expr::ExprBlock {
905 exprs: expressions,
906 inferred_type,
907 source_span: SourceSpan::default(),
908 type_annotation: None,
909 }
910 }
911
912 #[allow(clippy::should_implement_trait)]
913 pub fn not(expr: Expr) -> Self {
914 Expr::Not {
915 expr: Box::new(expr),
916 inferred_type: InferredType::bool(),
917 source_span: SourceSpan::default(),
918 type_annotation: None,
919 }
920 }
921
922 pub fn ok(expr: Expr, type_annotation: Option<TypeName>) -> Self {
923 let inferred_type = expr.inferred_type();
924
925 Expr::Result {
926 expr: Ok(Box::new(expr)),
927 type_annotation,
928 inferred_type: InferredType::result(Some(inferred_type), Some(InferredType::unknown())),
929 source_span: SourceSpan::default(),
930 }
931 }
932
933 pub fn option(expr: Option<Expr>) -> Self {
934 let inferred_type = match &expr {
935 Some(expr) => expr.inferred_type(),
936 None => InferredType::unknown(),
937 };
938
939 Expr::Option {
940 expr: expr.map(Box::new),
941 type_annotation: None,
942 inferred_type: InferredType::option(inferred_type),
943 source_span: SourceSpan::default(),
944 }
945 }
946
947 pub fn or(left: Expr, right: Expr) -> Self {
948 Expr::Or {
949 lhs: Box::new(left),
950 rhs: Box::new(right),
951 inferred_type: InferredType::bool(),
952 source_span: SourceSpan::default(),
953 type_annotation: None,
954 }
955 }
956
957 pub fn pattern_match(expr: Expr, match_arms: Vec<MatchArm>) -> Self {
958 Expr::PatternMatch {
959 predicate: Box::new(expr),
960 match_arms,
961 inferred_type: InferredType::unknown(),
962 source_span: SourceSpan::default(),
963 type_annotation: None,
964 }
965 }
966
967 pub fn record(expressions: Vec<(String, Expr)>) -> Self {
968 let inferred_type = InferredType::record(
969 expressions
970 .iter()
971 .map(|(field_name, expr)| (field_name.to_string(), expr.inferred_type()))
972 .collect(),
973 );
974
975 Expr::Record {
976 exprs: expressions
977 .into_iter()
978 .map(|(field_name, expr)| (field_name, Box::new(expr)))
979 .collect(),
980 inferred_type,
981 source_span: SourceSpan::default(),
982 type_annotation: None,
983 }
984 }
985
986 pub fn select_field(
987 expr: Expr,
988 field: impl AsRef<str>,
989 type_annotation: Option<TypeName>,
990 ) -> Self {
991 Expr::SelectField {
992 expr: Box::new(expr),
993 field: field.as_ref().to_string(),
994 type_annotation,
995 inferred_type: InferredType::unknown(),
996 source_span: SourceSpan::default(),
997 }
998 }
999
1000 pub fn select_index(expr: Expr, index: Expr) -> Self {
1001 Expr::SelectIndex {
1002 expr: Box::new(expr),
1003 index: Box::new(index),
1004 type_annotation: None,
1005 inferred_type: InferredType::unknown(),
1006 source_span: SourceSpan::default(),
1007 }
1008 }
1009
1010 pub fn get_tag(expr: Expr) -> Self {
1011 Expr::GetTag {
1012 expr: Box::new(expr),
1013 inferred_type: InferredType::unknown(),
1014 source_span: SourceSpan::default(),
1015 type_annotation: None,
1016 }
1017 }
1018
1019 pub fn tuple(expressions: Vec<Expr>) -> Self {
1020 let inferred_type = InferredType::tuple(
1021 expressions
1022 .iter()
1023 .map(|expr| expr.inferred_type())
1024 .collect(),
1025 );
1026
1027 Expr::Tuple {
1028 exprs: expressions,
1029 inferred_type,
1030 source_span: SourceSpan::default(),
1031 type_annotation: None,
1032 }
1033 }
1034
1035 pub fn sequence(expressions: Vec<Expr>, type_annotation: Option<TypeName>) -> Self {
1036 let inferred_type = InferredType::list(
1037 expressions
1038 .first()
1039 .map_or(InferredType::unknown(), |x| x.inferred_type()),
1040 );
1041
1042 Expr::Sequence {
1043 exprs: expressions,
1044 type_annotation,
1045 inferred_type,
1046 source_span: SourceSpan::default(),
1047 }
1048 }
1049
1050 pub fn inferred_type_mut(&mut self) -> &mut InferredType {
1051 match self {
1052 Expr::Let { inferred_type, .. }
1053 | Expr::SelectField { inferred_type, .. }
1054 | Expr::SelectIndex { inferred_type, .. }
1055 | Expr::Sequence { inferred_type, .. }
1056 | Expr::Record { inferred_type, .. }
1057 | Expr::Tuple { inferred_type, .. }
1058 | Expr::Literal { inferred_type, .. }
1059 | Expr::Number { inferred_type, .. }
1060 | Expr::Flags { inferred_type, .. }
1061 | Expr::Identifier { inferred_type, .. }
1062 | Expr::Boolean { inferred_type, .. }
1063 | Expr::Concat { inferred_type, .. }
1064 | Expr::ExprBlock { inferred_type, .. }
1065 | Expr::Not { inferred_type, .. }
1066 | Expr::GreaterThan { inferred_type, .. }
1067 | Expr::GreaterThanOrEqualTo { inferred_type, .. }
1068 | Expr::LessThanOrEqualTo { inferred_type, .. }
1069 | Expr::EqualTo { inferred_type, .. }
1070 | Expr::Plus { inferred_type, .. }
1071 | Expr::Minus { inferred_type, .. }
1072 | Expr::Divide { inferred_type, .. }
1073 | Expr::Multiply { inferred_type, .. }
1074 | Expr::LessThan { inferred_type, .. }
1075 | Expr::Cond { inferred_type, .. }
1076 | Expr::PatternMatch { inferred_type, .. }
1077 | Expr::Option { inferred_type, .. }
1078 | Expr::Result { inferred_type, .. }
1079 | Expr::Unwrap { inferred_type, .. }
1080 | Expr::Throw { inferred_type, .. }
1081 | Expr::GetTag { inferred_type, .. }
1082 | Expr::And { inferred_type, .. }
1083 | Expr::Or { inferred_type, .. }
1084 | Expr::ListComprehension { inferred_type, .. }
1085 | Expr::ListReduce { inferred_type, .. }
1086 | Expr::Call { inferred_type, .. }
1087 | Expr::Range { inferred_type, .. }
1088 | Expr::InvokeMethodLazy { inferred_type, .. }
1089 | Expr::Length { inferred_type, .. }
1090 | Expr::GenerateWorkerName { inferred_type, .. } => &mut *inferred_type,
1091 }
1092 }
1093
1094 pub fn inferred_type(&self) -> InferredType {
1095 match self {
1096 Expr::Let { inferred_type, .. }
1097 | Expr::SelectField { inferred_type, .. }
1098 | Expr::SelectIndex { inferred_type, .. }
1099 | Expr::Sequence { inferred_type, .. }
1100 | Expr::Record { inferred_type, .. }
1101 | Expr::Tuple { inferred_type, .. }
1102 | Expr::Literal { inferred_type, .. }
1103 | Expr::Number { inferred_type, .. }
1104 | Expr::Flags { inferred_type, .. }
1105 | Expr::Identifier { inferred_type, .. }
1106 | Expr::Boolean { inferred_type, .. }
1107 | Expr::Concat { inferred_type, .. }
1108 | Expr::ExprBlock { inferred_type, .. }
1109 | Expr::Not { inferred_type, .. }
1110 | Expr::GreaterThan { inferred_type, .. }
1111 | Expr::GreaterThanOrEqualTo { inferred_type, .. }
1112 | Expr::LessThanOrEqualTo { inferred_type, .. }
1113 | Expr::EqualTo { inferred_type, .. }
1114 | Expr::Plus { inferred_type, .. }
1115 | Expr::Minus { inferred_type, .. }
1116 | Expr::Divide { inferred_type, .. }
1117 | Expr::Multiply { inferred_type, .. }
1118 | Expr::LessThan { inferred_type, .. }
1119 | Expr::Cond { inferred_type, .. }
1120 | Expr::PatternMatch { inferred_type, .. }
1121 | Expr::Option { inferred_type, .. }
1122 | Expr::Result { inferred_type, .. }
1123 | Expr::Unwrap { inferred_type, .. }
1124 | Expr::Throw { inferred_type, .. }
1125 | Expr::GetTag { inferred_type, .. }
1126 | Expr::And { inferred_type, .. }
1127 | Expr::Or { inferred_type, .. }
1128 | Expr::ListComprehension { inferred_type, .. }
1129 | Expr::ListReduce { inferred_type, .. }
1130 | Expr::Call { inferred_type, .. }
1131 | Expr::Range { inferred_type, .. }
1132 | Expr::InvokeMethodLazy { inferred_type, .. }
1133 | Expr::Length { inferred_type, .. }
1134 | Expr::GenerateWorkerName { inferred_type, .. } => inferred_type.clone(),
1135 }
1136 }
1137
1138 pub fn infer_types(
1139 &mut self,
1140 component_dependency: &ComponentDependencies,
1141 type_spec: &Vec<GlobalVariableTypeSpec>,
1142 ) -> Result<(), RibTypeErrorInternal> {
1143 self.infer_types_initial_phase(component_dependency, type_spec)?;
1144 self.bind_instance_types();
1145 self.resolve_method_calls()?;
1150 type_inference::type_inference_fix_point(Self::resolve_method_calls, self)?;
1151 self.infer_function_call_types(component_dependency)?;
1152 type_inference::type_inference_fix_point(Self::inference_scan, self)?;
1153 self.check_types(component_dependency)?;
1154 self.unify_types()?;
1155 Ok(())
1156 }
1157
1158 pub fn infer_types_initial_phase(
1159 &mut self,
1160 component_dependency: &ComponentDependencies,
1161 type_spec: &Vec<GlobalVariableTypeSpec>,
1162 ) -> Result<(), RibTypeErrorInternal> {
1163 self.set_origin();
1164 self.bind_global_variable_types(type_spec);
1165 self.bind_type_annotations();
1166 self.bind_variables_of_list_comprehension();
1167 self.bind_variables_of_list_reduce();
1168 self.bind_variables_of_pattern_match();
1169 self.bind_variables_of_let_assignment();
1170 self.identify_instance_creation(component_dependency)?;
1171 self.ensure_stateful_instance();
1172 self.infer_variants(component_dependency);
1173 self.infer_enums(component_dependency);
1174 Ok(())
1175 }
1176
1177 pub fn resolve_method_calls(&mut self) -> Result<(), RibTypeErrorInternal> {
1178 self.bind_instance_types();
1179 self.infer_worker_function_invokes()?;
1180 Ok(())
1181 }
1182
1183 pub fn set_origin(&mut self) {
1184 let mut visitor = ExprVisitor::bottom_up(self);
1185
1186 while let Some(expr) = visitor.pop_front() {
1187 let source_location = expr.source_span();
1188 let origin = TypeOrigin::OriginatedAt(source_location.clone());
1189 let inferred_type = expr.inferred_type();
1190 let origin = inferred_type.add_origin(origin);
1191 expr.with_inferred_type_mut(origin);
1192 }
1193 }
1194
1195 pub fn inference_scan(&mut self) -> Result<(), RibTypeErrorInternal> {
1199 self.infer_all_identifiers();
1200 self.push_types_down()?;
1201 self.infer_all_identifiers();
1202 self.pull_types_up()?;
1203 self.infer_global_inputs();
1204 Ok(())
1205 }
1206
1207 pub fn infer_worker_function_invokes(&mut self) -> Result<(), RibTypeErrorInternal> {
1208 type_inference::infer_worker_function_invokes(self)
1209 }
1210
1211 pub fn bind_variables_of_pattern_match(&mut self) {
1215 type_inference::bind_variables_of_pattern_match(self);
1216 }
1217
1218 pub fn bind_variables_of_let_assignment(&mut self) {
1222 type_inference::bind_variables_of_let_assignment(self);
1223 }
1224
1225 pub fn bind_variables_of_list_comprehension(&mut self) {
1226 type_inference::bind_variables_of_list_comprehension(self);
1227 }
1228
1229 pub fn bind_variables_of_list_reduce(&mut self) {
1230 type_inference::bind_variables_of_list_reduce(self);
1231 }
1232
1233 pub fn identify_instance_creation(
1234 &mut self,
1235 component_dependency: &ComponentDependencies,
1236 ) -> Result<(), RibTypeErrorInternal> {
1237 type_inference::identify_instance_creation(self, component_dependency)
1238 }
1239
1240 pub fn ensure_stateful_instance(&mut self) {
1241 type_inference::ensure_stateful_instance(self)
1242 }
1243
1244 pub fn infer_function_call_types(
1245 &mut self,
1246 component_dependency: &ComponentDependencies,
1247 ) -> Result<(), RibTypeErrorInternal> {
1248 type_inference::infer_function_call_types(self, component_dependency)?;
1249 Ok(())
1250 }
1251
1252 pub fn push_types_down(&mut self) -> Result<(), RibTypeErrorInternal> {
1253 type_inference::push_types_down(self)
1254 }
1255
1256 pub fn infer_all_identifiers(&mut self) {
1257 type_inference::infer_all_identifiers(self)
1258 }
1259
1260 pub fn pull_types_up(&mut self) -> Result<(), RibTypeErrorInternal> {
1261 type_inference::type_pull_up(self)
1262 }
1263
1264 pub fn infer_global_inputs(&mut self) {
1265 type_inference::infer_global_inputs(self);
1266 }
1267
1268 pub fn bind_type_annotations(&mut self) {
1269 type_inference::bind_type_annotations(self);
1270 }
1271
1272 pub fn check_types(
1273 &mut self,
1274 component_dependency: &ComponentDependencies,
1275 ) -> Result<(), RibTypeErrorInternal> {
1276 type_checker::type_check(self, component_dependency)
1277 }
1278
1279 pub fn unify_types(&mut self) -> Result<(), RibTypeErrorInternal> {
1280 type_inference::unify_types(self)?;
1281 Ok(())
1282 }
1283
1284 pub fn merge_inferred_type(&self, new_inferred_type: InferredType) -> Expr {
1285 let mut expr_copied = self.clone();
1286 expr_copied.add_infer_type_mut(new_inferred_type);
1287 expr_copied
1288 }
1289
1290 pub fn add_infer_type_mut(&mut self, new_inferred_type: InferredType) {
1291 match self {
1292 Expr::Identifier { inferred_type, .. }
1293 | Expr::Let { inferred_type, .. }
1294 | Expr::SelectField { inferred_type, .. }
1295 | Expr::SelectIndex { inferred_type, .. }
1296 | Expr::Sequence { inferred_type, .. }
1297 | Expr::Record { inferred_type, .. }
1298 | Expr::Tuple { inferred_type, .. }
1299 | Expr::Literal { inferred_type, .. }
1300 | Expr::Number { inferred_type, .. }
1301 | Expr::Flags { inferred_type, .. }
1302 | Expr::Boolean { inferred_type, .. }
1303 | Expr::Concat { inferred_type, .. }
1304 | Expr::ExprBlock { inferred_type, .. }
1305 | Expr::Not { inferred_type, .. }
1306 | Expr::GreaterThan { inferred_type, .. }
1307 | Expr::GreaterThanOrEqualTo { inferred_type, .. }
1308 | Expr::LessThanOrEqualTo { inferred_type, .. }
1309 | Expr::EqualTo { inferred_type, .. }
1310 | Expr::Plus { inferred_type, .. }
1311 | Expr::Minus { inferred_type, .. }
1312 | Expr::Divide { inferred_type, .. }
1313 | Expr::Multiply { inferred_type, .. }
1314 | Expr::LessThan { inferred_type, .. }
1315 | Expr::Cond { inferred_type, .. }
1316 | Expr::PatternMatch { inferred_type, .. }
1317 | Expr::Option { inferred_type, .. }
1318 | Expr::Result { inferred_type, .. }
1319 | Expr::Unwrap { inferred_type, .. }
1320 | Expr::Throw { inferred_type, .. }
1321 | Expr::GetTag { inferred_type, .. }
1322 | Expr::And { inferred_type, .. }
1323 | Expr::Or { inferred_type, .. }
1324 | Expr::ListComprehension { inferred_type, .. }
1325 | Expr::ListReduce { inferred_type, .. }
1326 | Expr::InvokeMethodLazy { inferred_type, .. }
1327 | Expr::Range { inferred_type, .. }
1328 | Expr::Length { inferred_type, .. }
1329 | Expr::GenerateWorkerName { inferred_type, .. }
1330 | Expr::Call { inferred_type, .. } => {
1331 if !new_inferred_type.is_unknown() {
1332 *inferred_type = inferred_type.merge(new_inferred_type);
1333 }
1334 }
1335 }
1336 }
1337
1338 pub fn reset_type(&mut self) {
1339 type_inference::reset_type_info(self);
1340 }
1341
1342 pub fn source_span(&self) -> SourceSpan {
1343 match self {
1344 Expr::Identifier { source_span, .. }
1345 | Expr::Let { source_span, .. }
1346 | Expr::SelectField { source_span, .. }
1347 | Expr::SelectIndex { source_span, .. }
1348 | Expr::Sequence { source_span, .. }
1349 | Expr::Record { source_span, .. }
1350 | Expr::Tuple { source_span, .. }
1351 | Expr::Literal { source_span, .. }
1352 | Expr::Number { source_span, .. }
1353 | Expr::Flags { source_span, .. }
1354 | Expr::Boolean { source_span, .. }
1355 | Expr::Concat { source_span, .. }
1356 | Expr::ExprBlock { source_span, .. }
1357 | Expr::Not { source_span, .. }
1358 | Expr::GreaterThan { source_span, .. }
1359 | Expr::GreaterThanOrEqualTo { source_span, .. }
1360 | Expr::LessThanOrEqualTo { source_span, .. }
1361 | Expr::EqualTo { source_span, .. }
1362 | Expr::LessThan { source_span, .. }
1363 | Expr::Plus { source_span, .. }
1364 | Expr::Minus { source_span, .. }
1365 | Expr::Divide { source_span, .. }
1366 | Expr::Multiply { source_span, .. }
1367 | Expr::Cond { source_span, .. }
1368 | Expr::PatternMatch { source_span, .. }
1369 | Expr::Option { source_span, .. }
1370 | Expr::Result { source_span, .. }
1371 | Expr::Unwrap { source_span, .. }
1372 | Expr::Throw { source_span, .. }
1373 | Expr::And { source_span, .. }
1374 | Expr::Or { source_span, .. }
1375 | Expr::GetTag { source_span, .. }
1376 | Expr::ListComprehension { source_span, .. }
1377 | Expr::ListReduce { source_span, .. }
1378 | Expr::InvokeMethodLazy { source_span, .. }
1379 | Expr::Range { source_span, .. }
1380 | Expr::Length { source_span, .. }
1381 | Expr::Call { source_span, .. }
1382 | Expr::GenerateWorkerName { source_span, .. } => source_span.clone(),
1383 }
1384 }
1385
1386 pub fn type_annotation(&self) -> &Option<TypeName> {
1387 match self {
1388 Expr::Identifier {
1389 type_annotation, ..
1390 }
1391 | Expr::Let {
1392 type_annotation, ..
1393 }
1394 | Expr::SelectField {
1395 type_annotation, ..
1396 }
1397 | Expr::SelectIndex {
1398 type_annotation, ..
1399 }
1400 | Expr::Sequence {
1401 type_annotation, ..
1402 }
1403 | Expr::Record {
1404 type_annotation, ..
1405 }
1406 | Expr::Tuple {
1407 type_annotation, ..
1408 }
1409 | Expr::Literal {
1410 type_annotation, ..
1411 }
1412 | Expr::Number {
1413 type_annotation, ..
1414 }
1415 | Expr::Flags {
1416 type_annotation, ..
1417 }
1418 | Expr::Boolean {
1419 type_annotation, ..
1420 }
1421 | Expr::Concat {
1422 type_annotation, ..
1423 }
1424 | Expr::ExprBlock {
1425 type_annotation, ..
1426 }
1427 | Expr::Not {
1428 type_annotation, ..
1429 }
1430 | Expr::GreaterThan {
1431 type_annotation, ..
1432 }
1433 | Expr::GreaterThanOrEqualTo {
1434 type_annotation, ..
1435 }
1436 | Expr::LessThanOrEqualTo {
1437 type_annotation, ..
1438 }
1439 | Expr::EqualTo {
1440 type_annotation, ..
1441 }
1442 | Expr::LessThan {
1443 type_annotation, ..
1444 }
1445 | Expr::Plus {
1446 type_annotation, ..
1447 }
1448 | Expr::Minus {
1449 type_annotation, ..
1450 }
1451 | Expr::Divide {
1452 type_annotation, ..
1453 }
1454 | Expr::Multiply {
1455 type_annotation, ..
1456 }
1457 | Expr::Cond {
1458 type_annotation, ..
1459 }
1460 | Expr::PatternMatch {
1461 type_annotation, ..
1462 }
1463 | Expr::Option {
1464 type_annotation, ..
1465 }
1466 | Expr::Result {
1467 type_annotation, ..
1468 }
1469 | Expr::Unwrap {
1470 type_annotation, ..
1471 }
1472 | Expr::Throw {
1473 type_annotation, ..
1474 }
1475 | Expr::And {
1476 type_annotation, ..
1477 }
1478 | Expr::Or {
1479 type_annotation, ..
1480 }
1481 | Expr::GetTag {
1482 type_annotation, ..
1483 }
1484 | Expr::ListComprehension {
1485 type_annotation, ..
1486 }
1487 | Expr::ListReduce {
1488 type_annotation, ..
1489 }
1490 | Expr::InvokeMethodLazy {
1491 type_annotation, ..
1492 }
1493 | Expr::Range {
1494 type_annotation, ..
1495 }
1496 | Expr::Length {
1497 type_annotation, ..
1498 }
1499 | Expr::GenerateWorkerName {
1500 type_annotation, ..
1501 }
1502 | Expr::Call {
1503 type_annotation, ..
1504 } => type_annotation,
1505 }
1506 }
1507
1508 pub fn with_type_annotation_opt(&self, type_annotation: Option<TypeName>) -> Expr {
1509 if let Some(type_annotation) = type_annotation {
1510 self.with_type_annotation(type_annotation)
1511 } else {
1512 self.clone()
1513 }
1514 }
1515
1516 pub fn with_type_annotation(&self, type_annotation: TypeName) -> Expr {
1517 let mut expr_copied = self.clone();
1518 expr_copied.with_type_annotation_mut(type_annotation);
1519 expr_copied
1520 }
1521
1522 pub fn with_type_annotation_mut(&mut self, type_annotation: TypeName) {
1523 let new_type_annotation = type_annotation;
1524
1525 match self {
1526 Expr::Identifier {
1527 type_annotation, ..
1528 }
1529 | Expr::Let {
1530 type_annotation, ..
1531 }
1532 | Expr::SelectField {
1533 type_annotation, ..
1534 }
1535 | Expr::SelectIndex {
1536 type_annotation, ..
1537 }
1538 | Expr::Sequence {
1539 type_annotation, ..
1540 }
1541 | Expr::Record {
1542 type_annotation, ..
1543 }
1544 | Expr::Tuple {
1545 type_annotation, ..
1546 }
1547 | Expr::Literal {
1548 type_annotation, ..
1549 }
1550 | Expr::Number {
1551 type_annotation, ..
1552 }
1553 | Expr::Flags {
1554 type_annotation, ..
1555 }
1556 | Expr::Boolean {
1557 type_annotation, ..
1558 }
1559 | Expr::Concat {
1560 type_annotation, ..
1561 }
1562 | Expr::ExprBlock {
1563 type_annotation, ..
1564 }
1565 | Expr::Not {
1566 type_annotation, ..
1567 }
1568 | Expr::GreaterThan {
1569 type_annotation, ..
1570 }
1571 | Expr::GreaterThanOrEqualTo {
1572 type_annotation, ..
1573 }
1574 | Expr::LessThanOrEqualTo {
1575 type_annotation, ..
1576 }
1577 | Expr::EqualTo {
1578 type_annotation, ..
1579 }
1580 | Expr::LessThan {
1581 type_annotation, ..
1582 }
1583 | Expr::Plus {
1584 type_annotation, ..
1585 }
1586 | Expr::Minus {
1587 type_annotation, ..
1588 }
1589 | Expr::Divide {
1590 type_annotation, ..
1591 }
1592 | Expr::Multiply {
1593 type_annotation, ..
1594 }
1595 | Expr::Cond {
1596 type_annotation, ..
1597 }
1598 | Expr::PatternMatch {
1599 type_annotation, ..
1600 }
1601 | Expr::Option {
1602 type_annotation, ..
1603 }
1604 | Expr::Result {
1605 type_annotation, ..
1606 }
1607 | Expr::Unwrap {
1608 type_annotation, ..
1609 }
1610 | Expr::Throw {
1611 type_annotation, ..
1612 }
1613 | Expr::And {
1614 type_annotation, ..
1615 }
1616 | Expr::Or {
1617 type_annotation, ..
1618 }
1619 | Expr::GetTag {
1620 type_annotation, ..
1621 }
1622 | Expr::Range {
1623 type_annotation, ..
1624 }
1625 | Expr::ListComprehension {
1626 type_annotation, ..
1627 }
1628 | Expr::ListReduce {
1629 type_annotation, ..
1630 }
1631 | Expr::InvokeMethodLazy {
1632 type_annotation, ..
1633 }
1634 | Expr::Length {
1635 type_annotation, ..
1636 }
1637 | Expr::GenerateWorkerName {
1638 type_annotation, ..
1639 }
1640 | Expr::Call {
1641 type_annotation, ..
1642 } => {
1643 *type_annotation = Some(new_type_annotation);
1644 }
1645 }
1646 }
1647
1648 pub fn with_source_span(&self, new_source_span: SourceSpan) -> Expr {
1649 let mut expr_copied = self.clone();
1650 expr_copied.with_source_span_mut(new_source_span);
1651 expr_copied
1652 }
1653
1654 pub fn with_source_span_mut(&mut self, new_source_span: SourceSpan) {
1655 match self {
1656 Expr::Identifier { source_span, .. }
1657 | Expr::Let { source_span, .. }
1658 | Expr::SelectField { source_span, .. }
1659 | Expr::SelectIndex { source_span, .. }
1660 | Expr::Sequence { source_span, .. }
1661 | Expr::Number { source_span, .. }
1662 | Expr::Record { source_span, .. }
1663 | Expr::Tuple { source_span, .. }
1664 | Expr::Literal { source_span, .. }
1665 | Expr::Flags { source_span, .. }
1666 | Expr::Boolean { source_span, .. }
1667 | Expr::Concat { source_span, .. }
1668 | Expr::ExprBlock { source_span, .. }
1669 | Expr::Not { source_span, .. }
1670 | Expr::GreaterThan { source_span, .. }
1671 | Expr::GreaterThanOrEqualTo { source_span, .. }
1672 | Expr::LessThanOrEqualTo { source_span, .. }
1673 | Expr::EqualTo { source_span, .. }
1674 | Expr::LessThan { source_span, .. }
1675 | Expr::Plus { source_span, .. }
1676 | Expr::Minus { source_span, .. }
1677 | Expr::Divide { source_span, .. }
1678 | Expr::Multiply { source_span, .. }
1679 | Expr::Cond { source_span, .. }
1680 | Expr::PatternMatch { source_span, .. }
1681 | Expr::Option { source_span, .. }
1682 | Expr::Result { source_span, .. }
1683 | Expr::Unwrap { source_span, .. }
1684 | Expr::Throw { source_span, .. }
1685 | Expr::And { source_span, .. }
1686 | Expr::Or { source_span, .. }
1687 | Expr::GetTag { source_span, .. }
1688 | Expr::Range { source_span, .. }
1689 | Expr::ListComprehension { source_span, .. }
1690 | Expr::ListReduce { source_span, .. }
1691 | Expr::InvokeMethodLazy { source_span, .. }
1692 | Expr::Length { source_span, .. }
1693 | Expr::GenerateWorkerName { source_span, .. }
1694 | Expr::Call { source_span, .. } => {
1695 *source_span = new_source_span;
1696 }
1697 }
1698 }
1699
1700 pub fn with_inferred_type(&self, new_inferred_type: InferredType) -> Expr {
1701 let mut expr_copied = self.clone();
1702 expr_copied.with_inferred_type_mut(new_inferred_type);
1703 expr_copied
1704 }
1705
1706 pub fn with_inferred_type_mut(&mut self, new_inferred_type: InferredType) {
1709 match self {
1710 Expr::Identifier { inferred_type, .. }
1711 | Expr::Let { inferred_type, .. }
1712 | Expr::SelectField { inferred_type, .. }
1713 | Expr::SelectIndex { inferred_type, .. }
1714 | Expr::Sequence { inferred_type, .. }
1715 | Expr::Record { inferred_type, .. }
1716 | Expr::Tuple { inferred_type, .. }
1717 | Expr::Literal { inferred_type, .. }
1718 | Expr::Number { inferred_type, .. }
1719 | Expr::Flags { inferred_type, .. }
1720 | Expr::Boolean { inferred_type, .. }
1721 | Expr::Concat { inferred_type, .. }
1722 | Expr::ExprBlock { inferred_type, .. }
1723 | Expr::Not { inferred_type, .. }
1724 | Expr::GreaterThan { inferred_type, .. }
1725 | Expr::GreaterThanOrEqualTo { inferred_type, .. }
1726 | Expr::LessThanOrEqualTo { inferred_type, .. }
1727 | Expr::EqualTo { inferred_type, .. }
1728 | Expr::LessThan { inferred_type, .. }
1729 | Expr::Plus { inferred_type, .. }
1730 | Expr::Minus { inferred_type, .. }
1731 | Expr::Divide { inferred_type, .. }
1732 | Expr::Multiply { inferred_type, .. }
1733 | Expr::Cond { inferred_type, .. }
1734 | Expr::PatternMatch { inferred_type, .. }
1735 | Expr::Option { inferred_type, .. }
1736 | Expr::Result { inferred_type, .. }
1737 | Expr::Unwrap { inferred_type, .. }
1738 | Expr::Throw { inferred_type, .. }
1739 | Expr::And { inferred_type, .. }
1740 | Expr::Or { inferred_type, .. }
1741 | Expr::GetTag { inferred_type, .. }
1742 | Expr::ListComprehension { inferred_type, .. }
1743 | Expr::ListReduce { inferred_type, .. }
1744 | Expr::InvokeMethodLazy { inferred_type, .. }
1745 | Expr::Range { inferred_type, .. }
1746 | Expr::Length { inferred_type, .. }
1747 | Expr::GenerateWorkerName { inferred_type, .. }
1748 | Expr::Call { inferred_type, .. } => {
1749 *inferred_type = new_inferred_type;
1750 }
1751 }
1752 }
1753
1754 pub fn infer_enums(&mut self, component_dependency: &ComponentDependencies) {
1755 type_inference::infer_enums(self, component_dependency);
1756 }
1757
1758 pub fn infer_variants(&mut self, component_dependency: &ComponentDependencies) {
1759 type_inference::infer_variants(self, component_dependency);
1760 }
1761
1762 pub fn visit_expr_nodes_lazy<'a>(&'a mut self, queue: &mut VecDeque<&'a mut Expr>) {
1763 type_inference::visit_expr_nodes_lazy(self, queue);
1764 }
1765
1766 pub fn number_inferred(
1767 big_decimal: BigDecimal,
1768 type_annotation: Option<TypeName>,
1769 inferred_type: InferredType,
1770 ) -> Expr {
1771 Expr::Number {
1772 number: Number { value: big_decimal },
1773 type_annotation,
1774 inferred_type,
1775 source_span: SourceSpan::default(),
1776 }
1777 }
1778
1779 pub fn number(big_decimal: BigDecimal) -> Expr {
1780 let default_type = DefaultType::from(&big_decimal);
1781 let inferred_type = InferredType::from(&default_type);
1782
1783 Expr::number_inferred(big_decimal, None, inferred_type)
1784 }
1785}
1786
1787#[derive(Debug, Hash, Clone, PartialEq, Eq, PartialOrd, Ord)]
1788pub enum Range {
1789 Range { from: Box<Expr>, to: Box<Expr> },
1790 RangeInclusive { from: Box<Expr>, to: Box<Expr> },
1791 RangeFrom { from: Box<Expr> },
1792}
1793
1794impl Range {
1795 pub fn from(&self) -> Option<&Expr> {
1796 match self {
1797 Range::Range { from, .. } => Some(from),
1798 Range::RangeInclusive { from, .. } => Some(from),
1799 Range::RangeFrom { from } => Some(from),
1800 }
1801 }
1802
1803 pub fn to(&self) -> Option<&Expr> {
1804 match self {
1805 Range::Range { to, .. } => Some(to),
1806 Range::RangeInclusive { to, .. } => Some(to),
1807 Range::RangeFrom { .. } => None,
1808 }
1809 }
1810
1811 pub fn inclusive(&self) -> bool {
1812 matches!(self, Range::RangeInclusive { .. })
1813 }
1814
1815 pub fn get_exprs_mut(&mut self) -> Vec<&mut Box<Expr>> {
1816 match self {
1817 Range::Range { from, to } => vec![from, to],
1818 Range::RangeInclusive { from, to } => vec![from, to],
1819 Range::RangeFrom { from } => vec![from],
1820 }
1821 }
1822
1823 pub fn get_exprs(&self) -> Vec<&Expr> {
1824 match self {
1825 Range::Range { from, to } => vec![from.as_ref(), to.as_ref()],
1826 Range::RangeInclusive { from, to } => vec![from.as_ref(), to.as_ref()],
1827 Range::RangeFrom { from } => vec![from.as_ref()],
1828 }
1829 }
1830}
1831
1832#[derive(Debug, Hash, Clone, PartialEq, Ord, PartialOrd)]
1833pub struct Number {
1834 pub value: BigDecimal,
1835}
1836
1837impl Eq for Number {}
1838
1839impl Number {
1840 pub fn to_val(&self, analysed_type: &AnalysedType) -> Option<ValueAndType> {
1841 match analysed_type {
1842 AnalysedType::F64(_) => self.value.to_f64().map(|v| v.into_value_and_type()),
1843 AnalysedType::U64(_) => self.value.to_u64().map(|v| v.into_value_and_type()),
1844 AnalysedType::F32(_) => self.value.to_f32().map(|v| v.into_value_and_type()),
1845 AnalysedType::U32(_) => self.value.to_u32().map(|v| v.into_value_and_type()),
1846 AnalysedType::S32(_) => self.value.to_i32().map(|v| v.into_value_and_type()),
1847 AnalysedType::S64(_) => self.value.to_i64().map(|v| v.into_value_and_type()),
1848 AnalysedType::U8(_) => self.value.to_u8().map(|v| v.into_value_and_type()),
1849 AnalysedType::S8(_) => self.value.to_i8().map(|v| v.into_value_and_type()),
1850 AnalysedType::U16(_) => self.value.to_u16().map(|v| v.into_value_and_type()),
1851 AnalysedType::S16(_) => self.value.to_i16().map(|v| v.into_value_and_type()),
1852 _ => None,
1853 }
1854 }
1855}
1856
1857impl Display for Number {
1858 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1859 write!(f, "{}", self.value)
1860 }
1861}
1862
1863#[derive(Debug, Hash, Clone, PartialEq, Eq, Ord, PartialOrd)]
1864pub struct MatchArm {
1865 pub arm_pattern: ArmPattern,
1866 pub arm_resolution_expr: Box<Expr>,
1867}
1868
1869impl MatchArm {
1870 pub fn new(arm_pattern: ArmPattern, arm_resolution: Expr) -> MatchArm {
1871 MatchArm {
1872 arm_pattern,
1873 arm_resolution_expr: Box::new(arm_resolution),
1874 }
1875 }
1876}
1877#[derive(Debug, Hash, Clone, PartialEq, Eq, Ord, PartialOrd)]
1878pub enum ArmPattern {
1879 WildCard,
1880 As(String, Box<ArmPattern>),
1881 Constructor(String, Vec<ArmPattern>),
1882 TupleConstructor(Vec<ArmPattern>),
1883 RecordConstructor(Vec<(String, ArmPattern)>),
1884 ListConstructor(Vec<ArmPattern>),
1885 Literal(Box<Expr>),
1886}
1887
1888impl ArmPattern {
1889 pub fn is_wildcard(&self) -> bool {
1890 matches!(self, ArmPattern::WildCard)
1891 }
1892
1893 pub fn is_literal_identifier(&self) -> bool {
1894 matches!(self, ArmPattern::Literal(expr) if expr.is_identifier())
1895 }
1896
1897 pub fn constructor(name: &str, patterns: Vec<ArmPattern>) -> ArmPattern {
1898 ArmPattern::Constructor(name.to_string(), patterns)
1899 }
1900
1901 pub fn literal(expr: Expr) -> ArmPattern {
1902 ArmPattern::Literal(Box::new(expr))
1903 }
1904
1905 pub fn get_expr_literals_mut(&mut self) -> Vec<&mut Box<Expr>> {
1906 match self {
1907 ArmPattern::Literal(expr) => vec![expr],
1908 ArmPattern::As(_, pattern) => pattern.get_expr_literals_mut(),
1909 ArmPattern::Constructor(_, patterns) => {
1910 let mut result = vec![];
1911 for pattern in patterns {
1912 result.extend(pattern.get_expr_literals_mut());
1913 }
1914 result
1915 }
1916 ArmPattern::TupleConstructor(patterns) => {
1917 let mut result = vec![];
1918 for pattern in patterns {
1919 result.extend(pattern.get_expr_literals_mut());
1920 }
1921 result
1922 }
1923 ArmPattern::RecordConstructor(patterns) => {
1924 let mut result = vec![];
1925 for (_, pattern) in patterns {
1926 result.extend(pattern.get_expr_literals_mut());
1927 }
1928 result
1929 }
1930 ArmPattern::ListConstructor(patterns) => {
1931 let mut result = vec![];
1932 for pattern in patterns {
1933 result.extend(pattern.get_expr_literals_mut());
1934 }
1935 result
1936 }
1937 ArmPattern::WildCard => vec![],
1938 }
1939 }
1940
1941 pub fn get_expr_literals(&self) -> Vec<&Expr> {
1942 match self {
1943 ArmPattern::Literal(expr) => vec![expr.as_ref()],
1944 ArmPattern::As(_, pattern) => pattern.get_expr_literals(),
1945 ArmPattern::Constructor(_, patterns) => {
1946 let mut result = vec![];
1947 for pattern in patterns {
1948 result.extend(pattern.get_expr_literals());
1949 }
1950 result
1951 }
1952 ArmPattern::TupleConstructor(patterns) => {
1953 let mut result = vec![];
1954 for pattern in patterns {
1955 result.extend(pattern.get_expr_literals());
1956 }
1957 result
1958 }
1959 ArmPattern::RecordConstructor(patterns) => {
1960 let mut result = vec![];
1961 for (_, pattern) in patterns {
1962 result.extend(pattern.get_expr_literals());
1963 }
1964 result
1965 }
1966 ArmPattern::ListConstructor(patterns) => {
1967 let mut result = vec![];
1968 for pattern in patterns {
1969 result.extend(pattern.get_expr_literals());
1970 }
1971 result
1972 }
1973 ArmPattern::WildCard => vec![],
1974 }
1975 }
1976 pub fn ok(binding_variable: &str) -> ArmPattern {
1978 ArmPattern::Literal(Box::new(Expr::Result {
1979 expr: Ok(Box::new(Expr::Identifier {
1980 variable_id: VariableId::global(binding_variable.to_string()),
1981 type_annotation: None,
1982 inferred_type: InferredType::unknown(),
1983 source_span: SourceSpan::default(),
1984 })),
1985 type_annotation: None,
1986 inferred_type: InferredType::result(
1987 Some(InferredType::unknown()),
1988 Some(InferredType::unknown()),
1989 ),
1990 source_span: SourceSpan::default(),
1991 }))
1992 }
1993
1994 pub fn err(binding_variable: &str) -> ArmPattern {
1996 ArmPattern::Literal(Box::new(Expr::Result {
1997 expr: Err(Box::new(Expr::Identifier {
1998 variable_id: VariableId::global(binding_variable.to_string()),
1999 type_annotation: None,
2000 inferred_type: InferredType::unknown(),
2001 source_span: SourceSpan::default(),
2002 })),
2003 type_annotation: None,
2004 inferred_type: InferredType::result(
2005 Some(InferredType::unknown()),
2006 Some(InferredType::unknown()),
2007 ),
2008 source_span: SourceSpan::default(),
2009 }))
2010 }
2011
2012 pub fn some(binding_variable: &str) -> ArmPattern {
2014 ArmPattern::Literal(Box::new(Expr::Option {
2015 expr: Some(Box::new(Expr::Identifier {
2016 variable_id: VariableId::local_with_no_id(binding_variable),
2017 type_annotation: None,
2018 inferred_type: InferredType::unknown(),
2019 source_span: SourceSpan::default(),
2020 })),
2021 type_annotation: None,
2022 inferred_type: InferredType::unknown(),
2023 source_span: SourceSpan::default(),
2024 }))
2025 }
2026
2027 pub fn none() -> ArmPattern {
2028 ArmPattern::Literal(Box::new(Expr::Option {
2029 expr: None,
2030 type_annotation: None,
2031 inferred_type: InferredType::unknown(),
2032 source_span: SourceSpan::default(),
2033 }))
2034 }
2035
2036 pub fn identifier(binding_variable: &str) -> ArmPattern {
2037 ArmPattern::Literal(Box::new(Expr::Identifier {
2038 variable_id: VariableId::global(binding_variable.to_string()),
2039 type_annotation: None,
2040 inferred_type: InferredType::unknown(),
2041 source_span: SourceSpan::default(),
2042 }))
2043 }
2044 pub fn custom_constructor(name: &str, args: Vec<ArmPattern>) -> ArmPattern {
2045 ArmPattern::Constructor(name.to_string(), args)
2046 }
2047}
2048
2049#[cfg(feature = "protobuf")]
2050impl TryFrom<golem_api_grpc::proto::golem::rib::Expr> for Expr {
2051 type Error = String;
2052
2053 fn try_from(value: golem_api_grpc::proto::golem::rib::Expr) -> Result<Self, Self::Error> {
2054 let expr = value.expr.ok_or("Missing expr")?;
2055
2056 let expr = match expr {
2057 golem_api_grpc::proto::golem::rib::expr::Expr::Let(expr) => {
2058 let name = expr.name;
2059 let type_annotation = expr.type_name.map(TypeName::try_from).transpose()?;
2060 let expr_: golem_api_grpc::proto::golem::rib::Expr =
2061 *expr.expr.ok_or("Missing expr")?;
2062 let expr: Expr = expr_.try_into()?;
2063 Expr::let_binding(name, expr, type_annotation)
2064 }
2065
2066 golem_api_grpc::proto::golem::rib::expr::Expr::SelectIndexV1(expr) => {
2067 let selection = *expr.expr.ok_or("Missing expr")?;
2068 let field = *expr.index.ok_or("Missing index")?;
2069 let type_annotation = expr.type_name.map(TypeName::try_from).transpose()?;
2070
2071 Expr::select_index(selection.try_into()?, field.try_into()?)
2072 .with_type_annotation_opt(type_annotation)
2073 }
2074
2075 golem_api_grpc::proto::golem::rib::expr::Expr::Length(expr) => {
2076 let expr = expr.expr.ok_or("Missing expr")?;
2077 Expr::Length {
2078 expr: Box::new((*expr).try_into()?),
2079 type_annotation: None,
2080 inferred_type: InferredType::unknown(),
2081 source_span: SourceSpan::default(),
2082 }
2083 }
2084
2085 golem_api_grpc::proto::golem::rib::expr::Expr::Range(range) => {
2086 let range_expr = range.range_expr.ok_or("Missing range expr")?;
2087
2088 match range_expr {
2089 RangeExpr::RangeFrom(range_from) => {
2090 let from = range_from.from.ok_or("Missing from expr")?;
2091 Expr::range_from((*from).try_into()?)
2092 }
2093 RangeExpr::Range(range) => {
2094 let from = range.from.ok_or("Missing from expr")?;
2095 let to = range.to.ok_or("Missing to expr")?;
2096 Expr::range((*from).try_into()?, (*to).try_into()?)
2097 }
2098 RangeExpr::RangeInclusive(range_inclusive) => {
2099 let from = range_inclusive.from.ok_or("Missing from expr")?;
2100 let to = range_inclusive.to.ok_or("Missing to expr")?;
2101 Expr::range_inclusive((*from).try_into()?, (*to).try_into()?)
2102 }
2103 }
2104 }
2105
2106 golem_api_grpc::proto::golem::rib::expr::Expr::Not(expr) => {
2107 let expr = expr.expr.ok_or("Missing expr")?;
2108 Expr::not((*expr).try_into()?)
2109 }
2110
2111 golem_api_grpc::proto::golem::rib::expr::Expr::GreaterThan(expr) => {
2112 let left = expr.left.ok_or("Missing left expr")?;
2113 let right = expr.right.ok_or("Missing right expr")?;
2114 Expr::greater_than((*left).try_into()?, (*right).try_into()?)
2115 }
2116
2117 golem_api_grpc::proto::golem::rib::expr::Expr::GreaterThanOrEqual(expr) => {
2118 let left = expr.left.ok_or("Missing left expr")?;
2119 let right = expr.right.ok_or("Missing right expr")?;
2120 Expr::greater_than_or_equal_to((*left).try_into()?, (*right).try_into()?)
2121 }
2122
2123 golem_api_grpc::proto::golem::rib::expr::Expr::LessThan(expr) => {
2124 let left = expr.left.ok_or("Missing left expr")?;
2125 let right = expr.right.ok_or("Missing right expr")?;
2126 Expr::less_than((*left).try_into()?, (*right).try_into()?)
2127 }
2128
2129 golem_api_grpc::proto::golem::rib::expr::Expr::LessThanOrEqual(expr) => {
2130 let left = expr.left.ok_or("Missing left expr")?;
2131 let right = expr.right.ok_or("Missing right expr")?;
2132 Expr::less_than_or_equal_to((*left).try_into()?, (*right).try_into()?)
2133 }
2134
2135 golem_api_grpc::proto::golem::rib::expr::Expr::EqualTo(expr) => {
2136 let left = expr.left.ok_or("Missing left expr")?;
2137 let right = expr.right.ok_or("Missing right expr")?;
2138 Expr::equal_to((*left).try_into()?, (*right).try_into()?)
2139 }
2140
2141 golem_api_grpc::proto::golem::rib::expr::Expr::Add(expr) => {
2142 let left = expr.left.ok_or("Missing left expr")?;
2143 let right = expr.right.ok_or("Missing right expr")?;
2144 Expr::plus((*left).try_into()?, (*right).try_into()?)
2145 }
2146
2147 golem_api_grpc::proto::golem::rib::expr::Expr::Subtract(expr) => {
2148 let left = expr.left.ok_or("Missing left expr")?;
2149 let right = expr.right.ok_or("Missing right expr")?;
2150 Expr::plus((*left).try_into()?, (*right).try_into()?)
2151 }
2152
2153 golem_api_grpc::proto::golem::rib::expr::Expr::Divide(expr) => {
2154 let left = expr.left.ok_or("Missing left expr")?;
2155 let right = expr.right.ok_or("Missing right expr")?;
2156 Expr::plus((*left).try_into()?, (*right).try_into()?)
2157 }
2158
2159 golem_api_grpc::proto::golem::rib::expr::Expr::Multiply(expr) => {
2160 let left = expr.left.ok_or("Missing left expr")?;
2161 let right = expr.right.ok_or("Missing right expr")?;
2162 Expr::plus((*left).try_into()?, (*right).try_into()?)
2163 }
2164
2165 golem_api_grpc::proto::golem::rib::expr::Expr::Cond(expr) => {
2166 let left = expr.left.ok_or("Missing left expr")?;
2167 let cond = expr.cond.ok_or("Missing cond expr")?;
2168 let right = expr.right.ok_or("Missing right expr")?;
2169 Expr::cond(
2170 (*left).try_into()?,
2171 (*cond).try_into()?,
2172 (*right).try_into()?,
2173 )
2174 }
2175
2176 golem_api_grpc::proto::golem::rib::expr::Expr::Concat(
2177 golem_api_grpc::proto::golem::rib::ConcatExpr { exprs },
2178 ) => {
2179 let exprs: Vec<Expr> = exprs
2180 .into_iter()
2181 .map(|expr| expr.try_into())
2182 .collect::<Result<Vec<_>, _>>()?;
2183 Expr::concat(exprs)
2184 }
2185
2186 golem_api_grpc::proto::golem::rib::expr::Expr::Multiple(
2187 golem_api_grpc::proto::golem::rib::MultipleExpr { exprs },
2188 ) => {
2189 let exprs: Vec<Expr> = exprs
2190 .into_iter()
2191 .map(|expr| expr.try_into())
2192 .collect::<Result<Vec<_>, _>>()?;
2193 Expr::expr_block(exprs)
2194 }
2195
2196 golem_api_grpc::proto::golem::rib::expr::Expr::Sequence(
2197 golem_api_grpc::proto::golem::rib::SequenceExpr { exprs, type_name },
2198 ) => {
2199 let type_annotation = type_name.map(TypeName::try_from).transpose()?;
2200
2201 let exprs: Vec<Expr> = exprs
2202 .into_iter()
2203 .map(|expr| expr.try_into())
2204 .collect::<Result<Vec<_>, _>>()?;
2205 Expr::sequence(exprs, type_annotation)
2206 }
2207
2208 golem_api_grpc::proto::golem::rib::expr::Expr::Tuple(
2209 golem_api_grpc::proto::golem::rib::TupleExpr { exprs },
2210 ) => {
2211 let exprs: Vec<Expr> = exprs
2212 .into_iter()
2213 .map(|expr| expr.try_into())
2214 .collect::<Result<Vec<_>, _>>()?;
2215 Expr::tuple(exprs)
2216 }
2217
2218 golem_api_grpc::proto::golem::rib::expr::Expr::Record(
2219 golem_api_grpc::proto::golem::rib::RecordExpr { fields },
2220 ) => {
2221 let mut values: Vec<(String, Expr)> = vec![];
2222 for record in fields.into_iter() {
2223 let name = record.name;
2224 let expr = record.expr.ok_or("Missing expr")?;
2225 values.push((name, expr.try_into()?));
2226 }
2227 Expr::record(values)
2228 }
2229
2230 golem_api_grpc::proto::golem::rib::expr::Expr::Flags(
2231 golem_api_grpc::proto::golem::rib::FlagsExpr { values },
2232 ) => Expr::flags(values),
2233
2234 golem_api_grpc::proto::golem::rib::expr::Expr::Literal(
2235 golem_api_grpc::proto::golem::rib::LiteralExpr { value },
2236 ) => Expr::literal(value),
2237
2238 golem_api_grpc::proto::golem::rib::expr::Expr::Identifier(
2239 golem_api_grpc::proto::golem::rib::IdentifierExpr { name, type_name },
2240 ) => {
2241 let type_name = type_name.map(TypeName::try_from).transpose()?;
2242
2243 Expr::identifier_global(name.as_str(), type_name)
2244 }
2245
2246 golem_api_grpc::proto::golem::rib::expr::Expr::Boolean(
2247 golem_api_grpc::proto::golem::rib::BooleanExpr { value },
2248 ) => Expr::boolean(value),
2249
2250 golem_api_grpc::proto::golem::rib::expr::Expr::Throw(
2251 golem_api_grpc::proto::golem::rib::ThrowExpr { message },
2252 ) => Expr::throw(message),
2253
2254 golem_api_grpc::proto::golem::rib::expr::Expr::GenerateWorkerName(
2255 golem_api_grpc::proto::golem::rib::GenerateWorkerNameExpr {},
2256 ) => Expr::generate_worker_name(None),
2257
2258 golem_api_grpc::proto::golem::rib::expr::Expr::And(expr) => {
2259 let left = expr.left.ok_or("Missing left expr")?;
2260 let right = expr.right.ok_or("Missing right expr")?;
2261 Expr::and((*left).try_into()?, (*right).try_into()?)
2262 }
2263
2264 golem_api_grpc::proto::golem::rib::expr::Expr::Or(expr) => {
2265 let left = expr.left.ok_or("Missing left expr")?;
2266 let right = expr.right.ok_or("Missing right expr")?;
2267 Expr::or((*left).try_into()?, (*right).try_into()?)
2268 }
2269
2270 golem_api_grpc::proto::golem::rib::expr::Expr::Tag(expr) => {
2271 let expr = expr.expr.ok_or("Missing expr in tag")?;
2272 Expr::get_tag((*expr).try_into()?)
2273 }
2274
2275 golem_api_grpc::proto::golem::rib::expr::Expr::Unwrap(expr) => {
2276 let expr = expr.expr.ok_or("Missing expr")?;
2277 let expr: Expr = (*expr).try_into()?;
2278 expr.unwrap()
2279 }
2280
2281 golem_api_grpc::proto::golem::rib::expr::Expr::Number(number) => {
2282 let type_name = number.type_name.map(TypeName::try_from).transpose()?;
2284 let big_decimal = if let Some(number) = number.number {
2285 BigDecimal::from_str(&number).map_err(|e| e.to_string())?
2286 } else if let Some(float) = number.float {
2287 BigDecimal::from_f64(float).ok_or("Invalid float")?
2288 } else {
2289 return Err("Missing number".to_string());
2290 };
2291
2292 Expr::number(big_decimal).with_type_annotation_opt(type_name)
2293 }
2294 golem_api_grpc::proto::golem::rib::expr::Expr::SelectField(expr) => {
2295 let expr = *expr;
2296 let field = expr.field;
2297 let type_name = expr.type_name.map(TypeName::try_from).transpose()?;
2298 let expr = *expr.expr.ok_or(
2299 "Mi\
2300 ssing expr",
2301 )?;
2302
2303 Expr::select_field(expr.try_into()?, field.as_str(), type_name)
2304 }
2305 golem_api_grpc::proto::golem::rib::expr::Expr::SelectIndex(expr) => {
2306 let expr = *expr;
2307 let type_name = expr.type_name.map(TypeName::try_from).transpose()?;
2308 let index = expr.index as usize;
2309 let expr = *expr.expr.ok_or("Missing expr")?;
2310
2311 let index_expr =
2312 Expr::number(BigDecimal::from_usize(index).ok_or("Invalid index")?);
2313
2314 Expr::select_index(expr.try_into()?, index_expr).with_type_annotation_opt(type_name)
2315 }
2316 golem_api_grpc::proto::golem::rib::expr::Expr::Option(expr) => {
2317 let type_name = expr.type_name;
2318 let type_name = type_name.map(TypeName::try_from).transpose()?;
2319
2320 match expr.expr {
2321 Some(expr) => {
2322 Expr::option(Some((*expr).try_into()?)).with_type_annotation_opt(type_name)
2323 }
2324 None => Expr::option(None).with_type_annotation_opt(type_name),
2325 }
2326 }
2327 golem_api_grpc::proto::golem::rib::expr::Expr::Result(expr) => {
2328 let type_name = expr.type_name;
2329 let type_name = type_name.map(TypeName::try_from).transpose()?;
2330 let result = expr.result.ok_or("Missing result")?;
2331 match result {
2332 golem_api_grpc::proto::golem::rib::result_expr::Result::Ok(expr) => {
2333 Expr::ok((*expr).try_into()?, type_name)
2334 }
2335 golem_api_grpc::proto::golem::rib::result_expr::Result::Err(expr) => {
2336 Expr::err((*expr).try_into()?, type_name)
2337 }
2338 }
2339 }
2340 golem_api_grpc::proto::golem::rib::expr::Expr::PatternMatch(expr) => {
2341 let patterns: Vec<MatchArm> = expr
2342 .patterns
2343 .into_iter()
2344 .map(|expr| expr.try_into())
2345 .collect::<Result<Vec<_>, _>>()?;
2346 let expr = expr.expr.ok_or("Missing expr")?;
2347 Expr::pattern_match((*expr).try_into()?, patterns)
2348 }
2349 golem_api_grpc::proto::golem::rib::expr::Expr::ListComprehension(
2350 list_comprehension,
2351 ) => {
2352 let iterable_expr = list_comprehension.iterable_expr.ok_or("Missing expr")?;
2353 let iterable_expr = (*iterable_expr).try_into()?;
2354 let yield_expr = list_comprehension.yield_expr.ok_or("Missing list")?;
2355 let yield_expr = (*yield_expr).try_into()?;
2356 let variable_id =
2357 VariableId::list_comprehension_identifier(list_comprehension.iterated_variable);
2358 Expr::list_comprehension(variable_id, iterable_expr, yield_expr)
2359 }
2360 golem_api_grpc::proto::golem::rib::expr::Expr::ListReduce(list_reduce) => {
2361 let init_value_expr = list_reduce.init_value_expr.ok_or("Missing initial expr")?;
2362 let init_value_expr = (*init_value_expr).try_into()?;
2363 let iterable_expr = list_reduce.iterable_expr.ok_or("Missing expr")?;
2364 let iterable_expr = (*iterable_expr).try_into()?;
2365 let yield_expr = list_reduce.yield_expr.ok_or("Missing list")?;
2366 let yield_expr = (*yield_expr).try_into()?;
2367 let iterated_variable_id =
2368 VariableId::list_comprehension_identifier(list_reduce.iterated_variable);
2369 let reduce_variable_id =
2370 VariableId::list_reduce_identifier(list_reduce.reduce_variable);
2371 Expr::list_reduce(
2372 reduce_variable_id,
2373 iterated_variable_id,
2374 iterable_expr,
2375 init_value_expr,
2376 yield_expr,
2377 )
2378 }
2379 golem_api_grpc::proto::golem::rib::expr::Expr::Call(expr) => {
2380 let params: Vec<Expr> = expr
2381 .params
2382 .into_iter()
2383 .map(|expr| expr.try_into())
2384 .collect::<Result<Vec<_>, _>>()?;
2385 let legacy_invocation_name = expr.name;
2387 let call_type = expr.call_type;
2388 let generic_type_parameter = expr
2389 .generic_type_parameter
2390 .map(|tp| GenericTypeParameter { value: tp });
2391
2392 match (legacy_invocation_name, call_type) {
2393 (Some(legacy), None) => {
2394 let name = legacy.name.ok_or("Missing function call name")?;
2395 match name {
2396 golem_api_grpc::proto::golem::rib::invocation_name::Name::Parsed(name) => {
2397 Expr::call_worker_function(DynamicParsedFunctionName::parse(
2399 ParsedFunctionName::try_from(name)?.to_string()
2400 )?, generic_type_parameter, None, params, None)
2401 }
2402 golem_api_grpc::proto::golem::rib::invocation_name::Name::VariantConstructor(
2403 name,
2404 ) => Expr::call_worker_function(DynamicParsedFunctionName::parse(name)?, generic_type_parameter, None, params, None),
2405 golem_api_grpc::proto::golem::rib::invocation_name::Name::EnumConstructor(
2406 name,
2407 ) => Expr::call_worker_function(DynamicParsedFunctionName::parse(name)?, generic_type_parameter, None, params, None),
2408 }
2409 }
2410 (_, Some(call_type)) => {
2411 let name = call_type.name.ok_or("Missing function call name")?;
2412 match name {
2413 golem_api_grpc::proto::golem::rib::call_type::Name::Parsed(name) => {
2414 Expr::call_worker_function(name.try_into()?, generic_type_parameter, None, params, None)
2415 }
2416 golem_api_grpc::proto::golem::rib::call_type::Name::VariantConstructor(
2417 name,
2418 ) => Expr::call_worker_function(DynamicParsedFunctionName::parse(name)?, generic_type_parameter, None, params, None),
2419 golem_api_grpc::proto::golem::rib::call_type::Name::EnumConstructor(
2420 name,
2421 ) => Expr::call_worker_function(DynamicParsedFunctionName::parse(name)?, generic_type_parameter, None, params, None),
2422 golem_api_grpc::proto::golem::rib::call_type::Name::InstanceCreation(instance_creation) => {
2423 let instance_creation_type = InstanceCreationType::try_from(*instance_creation)?;
2424 let call_type = CallType::InstanceCreation(instance_creation_type);
2425 Expr::Call {
2426 call_type,
2427 generic_type_parameter,
2428 args: vec![],
2429 inferred_type: InferredType::unknown(),
2430 source_span: SourceSpan::default(),
2431 type_annotation: None, }
2433 }
2434 }
2435 }
2436 (_, _) => Err("Missing both call type (and legacy invocation type)")?,
2437 }
2438 }
2439 golem_api_grpc::proto::golem::rib::expr::Expr::LazyInvokeMethod(lazy_invoke) => {
2440 let lhs_proto = lazy_invoke.lhs.ok_or("Missing lhs")?;
2441 let lhs = Box::new((*lhs_proto).try_into()?);
2442 let method = lazy_invoke.method;
2443 let generic_type_parameter = lazy_invoke.generic_type_parameter;
2444 let args: Vec<Expr> = lazy_invoke
2445 .args
2446 .into_iter()
2447 .map(Expr::try_from)
2448 .collect::<Result<Vec<_>, _>>()?;
2449
2450 Expr::InvokeMethodLazy {
2451 lhs,
2452 method,
2453 generic_type_parameter: generic_type_parameter
2454 .map(|value| GenericTypeParameter { value }),
2455 args,
2456 inferred_type: InferredType::unknown(),
2457 source_span: SourceSpan::default(),
2458 type_annotation: None, }
2460 }
2461 };
2462 Ok(expr)
2463 }
2464}
2465
2466impl Display for Expr {
2467 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2468 write!(f, "{}", text::to_string(self).unwrap())
2469 }
2470}
2471
2472impl Display for ArmPattern {
2473 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2474 write!(f, "{}", text::to_string_arm_pattern(self).unwrap())
2475 }
2476}
2477
2478impl<'de> Deserialize<'de> for Expr {
2479 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
2480 where
2481 D: serde::Deserializer<'de>,
2482 {
2483 let value = Value::deserialize(deserializer)?;
2484 match value {
2485 Value::String(expr_string) => match from_string(expr_string.as_str()) {
2486 Ok(expr) => Ok(expr),
2487 Err(message) => Err(serde::de::Error::custom(message.to_string())),
2488 },
2489
2490 e => Err(serde::de::Error::custom(format!(
2491 "Failed to deserialize expression {e}"
2492 ))),
2493 }
2494 }
2495}
2496
2497impl Serialize for Expr {
2498 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2499 where
2500 S: Serializer,
2501 {
2502 match text::to_string(self) {
2503 Ok(value) => Value::serialize(&Value::String(value), serializer),
2504 Err(error) => Err(serde::ser::Error::custom(error.to_string())),
2505 }
2506 }
2507}
2508
2509#[cfg(feature = "protobuf")]
2510mod protobuf {
2511 use crate::{ArmPattern, Expr, MatchArm, Range};
2512 use golem_api_grpc::proto::golem::rib::range_expr::RangeExpr;
2513
2514 impl From<Expr> for golem_api_grpc::proto::golem::rib::Expr {
2532 fn from(value: Expr) -> Self {
2533 let expr = match value {
2534 Expr::GenerateWorkerName { .. } => Some(
2535 golem_api_grpc::proto::golem::rib::expr::Expr::GenerateWorkerName(
2536 golem_api_grpc::proto::golem::rib::GenerateWorkerNameExpr {},
2537 ),
2538 ),
2539 Expr::Let {
2540 variable_id,
2541 type_annotation,
2542 expr,
2543 ..
2544 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Let(
2545 Box::new(golem_api_grpc::proto::golem::rib::LetExpr {
2546 name: variable_id.name().to_string(),
2547 expr: Some(Box::new((*expr).into())),
2548 type_name: type_annotation.map(|t| t.into()),
2549 }),
2550 )),
2551
2552 Expr::Length { expr, .. } => {
2553 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Length(
2554 Box::new(golem_api_grpc::proto::golem::rib::LengthExpr {
2555 expr: Some(Box::new((*expr).into())),
2556 }),
2557 ))
2558 }
2559
2560 Expr::SelectField {
2561 expr,
2562 field,
2563 type_annotation,
2564 ..
2565 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::SelectField(
2566 Box::new(golem_api_grpc::proto::golem::rib::SelectFieldExpr {
2567 expr: Some(Box::new((*expr).into())),
2568 field,
2569 type_name: type_annotation.map(|t| t.into()),
2570 }),
2571 )),
2572
2573 Expr::Range { range, .. } => match range {
2574 Range::RangeFrom { from } => {
2575 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Range(
2576 Box::new(golem_api_grpc::proto::golem::rib::RangeExpr {
2577 range_expr: Some(RangeExpr::RangeFrom(Box::new(
2578 golem_api_grpc::proto::golem::rib::RangeFrom {
2579 from: Some(Box::new((*from).into())),
2580 },
2581 ))),
2582 }),
2583 ))
2584 }
2585 Range::Range { from, to } => {
2586 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Range(
2587 Box::new(golem_api_grpc::proto::golem::rib::RangeExpr {
2588 range_expr: Some(RangeExpr::Range(Box::new(
2589 golem_api_grpc::proto::golem::rib::Range {
2590 from: Some(Box::new((*from).into())),
2591 to: Some(Box::new((*to).into())),
2592 },
2593 ))),
2594 }),
2595 ))
2596 }
2597 Range::RangeInclusive { from, to } => {
2598 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Range(
2599 Box::new(golem_api_grpc::proto::golem::rib::RangeExpr {
2600 range_expr: Some(RangeExpr::RangeInclusive(Box::new(
2601 golem_api_grpc::proto::golem::rib::RangeInclusive {
2602 from: Some(Box::new((*from).into())),
2603 to: Some(Box::new((*to).into())),
2604 },
2605 ))),
2606 }),
2607 ))
2608 }
2609 },
2610
2611 Expr::SelectIndex {
2612 expr,
2613 index,
2614 type_annotation,
2615 ..
2616 } => Some(
2617 golem_api_grpc::proto::golem::rib::expr::Expr::SelectIndexV1(Box::new(
2618 golem_api_grpc::proto::golem::rib::SelectIndexExprV1 {
2619 expr: Some(Box::new((*expr).into())),
2620 index: Some(Box::new((*index).into())),
2621 type_name: type_annotation.map(|t| t.into()),
2622 },
2623 )),
2624 ),
2625
2626 Expr::Sequence {
2627 exprs: expressions,
2628 type_annotation,
2629 ..
2630 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Sequence(
2631 golem_api_grpc::proto::golem::rib::SequenceExpr {
2632 exprs: expressions.into_iter().map(|expr| expr.into()).collect(),
2633 type_name: type_annotation.map(|t| t.into()),
2634 },
2635 )),
2636 Expr::Record { exprs: fields, .. } => {
2637 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Record(
2638 golem_api_grpc::proto::golem::rib::RecordExpr {
2639 fields: fields
2640 .into_iter()
2641 .map(|(name, expr)| {
2642 golem_api_grpc::proto::golem::rib::RecordFieldExpr {
2643 name,
2644 expr: Some((*expr).into()),
2645 }
2646 })
2647 .collect(),
2648 },
2649 ))
2650 }
2651 Expr::Tuple {
2652 exprs: expressions, ..
2653 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Tuple(
2654 golem_api_grpc::proto::golem::rib::TupleExpr {
2655 exprs: expressions.into_iter().map(|expr| expr.into()).collect(),
2656 },
2657 )),
2658 Expr::Literal { value, .. } => {
2659 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Literal(
2660 golem_api_grpc::proto::golem::rib::LiteralExpr { value },
2661 ))
2662 }
2663 Expr::Number {
2664 number,
2665 type_annotation,
2666 ..
2667 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Number(
2668 golem_api_grpc::proto::golem::rib::NumberExpr {
2669 number: Some(number.value.to_string()),
2670 float: None,
2671 type_name: type_annotation.map(|t| t.into()),
2672 },
2673 )),
2674 Expr::Flags { flags, .. } => {
2675 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Flags(
2676 golem_api_grpc::proto::golem::rib::FlagsExpr { values: flags },
2677 ))
2678 }
2679 Expr::Identifier {
2680 variable_id,
2681 type_annotation,
2682 ..
2683 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Identifier(
2684 golem_api_grpc::proto::golem::rib::IdentifierExpr {
2685 name: variable_id.name(),
2686 type_name: type_annotation.map(|t| t.into()),
2687 },
2688 )),
2689 Expr::Boolean { value, .. } => {
2690 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Boolean(
2691 golem_api_grpc::proto::golem::rib::BooleanExpr { value },
2692 ))
2693 }
2694 Expr::Concat {
2695 exprs: expressions, ..
2696 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Concat(
2697 golem_api_grpc::proto::golem::rib::ConcatExpr {
2698 exprs: expressions.into_iter().map(|expr| expr.into()).collect(),
2699 },
2700 )),
2701 Expr::ExprBlock {
2702 exprs: expressions, ..
2703 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Multiple(
2704 golem_api_grpc::proto::golem::rib::MultipleExpr {
2705 exprs: expressions.into_iter().map(|expr| expr.into()).collect(),
2706 },
2707 )),
2708 Expr::Not { expr, .. } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Not(
2709 Box::new(golem_api_grpc::proto::golem::rib::NotExpr {
2710 expr: Some(Box::new((*expr).into())),
2711 }),
2712 )),
2713 Expr::GreaterThan {
2714 lhs: left,
2715 rhs: right,
2716 ..
2717 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::GreaterThan(
2718 Box::new(golem_api_grpc::proto::golem::rib::GreaterThanExpr {
2719 left: Some(Box::new((*left).into())),
2720 right: Some(Box::new((*right).into())),
2721 }),
2722 )),
2723 Expr::GreaterThanOrEqualTo { lhs, rhs, .. } => Some(
2724 golem_api_grpc::proto::golem::rib::expr::Expr::GreaterThanOrEqual(Box::new(
2725 golem_api_grpc::proto::golem::rib::GreaterThanOrEqualToExpr {
2726 left: Some(Box::new((*lhs).into())),
2727 right: Some(Box::new((*rhs).into())),
2728 },
2729 )),
2730 ),
2731 Expr::LessThan {
2732 lhs: left,
2733 rhs: right,
2734 ..
2735 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::LessThan(
2736 Box::new(golem_api_grpc::proto::golem::rib::LessThanExpr {
2737 left: Some(Box::new((*left).into())),
2738 right: Some(Box::new((*right).into())),
2739 }),
2740 )),
2741 Expr::Plus {
2742 lhs: left,
2743 rhs: right,
2744 ..
2745 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Add(
2746 Box::new(golem_api_grpc::proto::golem::rib::AddExpr {
2747 left: Some(Box::new((*left).into())),
2748 right: Some(Box::new((*right).into())),
2749 }),
2750 )),
2751 Expr::Minus {
2752 lhs: left,
2753 rhs: right,
2754 ..
2755 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Subtract(
2756 Box::new(golem_api_grpc::proto::golem::rib::SubtractExpr {
2757 left: Some(Box::new((*left).into())),
2758 right: Some(Box::new((*right).into())),
2759 }),
2760 )),
2761 Expr::Divide { lhs, rhs, .. } => {
2762 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Divide(
2763 Box::new(golem_api_grpc::proto::golem::rib::DivideExpr {
2764 left: Some(Box::new((*lhs).into())),
2765 right: Some(Box::new((*rhs).into())),
2766 }),
2767 ))
2768 }
2769 Expr::Multiply { lhs, rhs, .. } => {
2770 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Multiply(
2771 Box::new(golem_api_grpc::proto::golem::rib::MultiplyExpr {
2772 left: Some(Box::new((*lhs).into())),
2773 right: Some(Box::new((*rhs).into())),
2774 }),
2775 ))
2776 }
2777 Expr::LessThanOrEqualTo { lhs, rhs, .. } => Some(
2778 golem_api_grpc::proto::golem::rib::expr::Expr::LessThanOrEqual(Box::new(
2779 golem_api_grpc::proto::golem::rib::LessThanOrEqualToExpr {
2780 left: Some(Box::new((*lhs).into())),
2781 right: Some(Box::new((*rhs).into())),
2782 },
2783 )),
2784 ),
2785 Expr::EqualTo { lhs, rhs, .. } => {
2786 Some(golem_api_grpc::proto::golem::rib::expr::Expr::EqualTo(
2787 Box::new(golem_api_grpc::proto::golem::rib::EqualToExpr {
2788 left: Some(Box::new((*lhs).into())),
2789 right: Some(Box::new((*rhs).into())),
2790 }),
2791 ))
2792 }
2793 Expr::Cond {
2799 cond: lhs,
2800 lhs: cond,
2801 rhs,
2802 ..
2803 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Cond(
2804 Box::new(golem_api_grpc::proto::golem::rib::CondExpr {
2805 left: Some(Box::new((*lhs).into())),
2806 cond: Some(Box::new((*cond).into())),
2807 right: Some(Box::new((*rhs).into())),
2808 }),
2809 )),
2810 Expr::PatternMatch {
2811 predicate,
2812 match_arms,
2813 ..
2814 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::PatternMatch(
2815 Box::new(golem_api_grpc::proto::golem::rib::PatternMatchExpr {
2816 expr: Some(Box::new((*predicate).into())),
2817 patterns: match_arms.into_iter().map(|a| a.into()).collect(),
2818 }),
2819 )),
2820 Expr::Option {
2821 expr,
2822 type_annotation,
2823 ..
2824 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Option(
2825 Box::new(golem_api_grpc::proto::golem::rib::OptionExpr {
2826 expr: expr.map(|expr| Box::new((*expr).into())),
2827 type_name: type_annotation.map(|t| t.into()),
2828 }),
2829 )),
2830 Expr::Result {
2831 expr,
2832 type_annotation,
2833 ..
2834 } => {
2835 let type_name = type_annotation.map(|t| t.into());
2836
2837 let result = match expr {
2838 Ok(expr) => golem_api_grpc::proto::golem::rib::result_expr::Result::Ok(
2839 Box::new((*expr).into()),
2840 ),
2841 Err(expr) => golem_api_grpc::proto::golem::rib::result_expr::Result::Err(
2842 Box::new((*expr).into()),
2843 ),
2844 };
2845
2846 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Result(
2847 Box::new(golem_api_grpc::proto::golem::rib::ResultExpr {
2848 result: Some(result),
2849 type_name,
2850 }),
2851 ))
2852 }
2853 Expr::Call {
2854 call_type,
2855 generic_type_parameter,
2856 args,
2857 ..
2858 } => {
2859 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Call(
2860 Box::new(golem_api_grpc::proto::golem::rib::CallExpr {
2861 name: None, params: args.into_iter().map(|expr| expr.into()).collect(),
2863 generic_type_parameter: generic_type_parameter.map(|t| t.value),
2864 call_type: Some(Box::new(
2865 golem_api_grpc::proto::golem::rib::CallType::from(call_type),
2866 )),
2867 }),
2868 ))
2869 }
2870 Expr::Unwrap { expr, .. } => {
2871 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Unwrap(
2872 Box::new(golem_api_grpc::proto::golem::rib::UnwrapExpr {
2873 expr: Some(Box::new((*expr).into())),
2874 }),
2875 ))
2876 }
2877 Expr::Throw { message, .. } => {
2878 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Throw(
2879 golem_api_grpc::proto::golem::rib::ThrowExpr { message },
2880 ))
2881 }
2882 Expr::GetTag { expr, .. } => {
2883 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Tag(
2884 Box::new(golem_api_grpc::proto::golem::rib::GetTagExpr {
2885 expr: Some(Box::new((*expr).into())),
2886 }),
2887 ))
2888 }
2889 Expr::And { lhs, rhs, .. } => {
2890 Some(golem_api_grpc::proto::golem::rib::expr::Expr::And(
2891 Box::new(golem_api_grpc::proto::golem::rib::AndExpr {
2892 left: Some(Box::new((*lhs).into())),
2893 right: Some(Box::new((*rhs).into())),
2894 }),
2895 ))
2896 }
2897
2898 Expr::Or { lhs, rhs, .. } => {
2899 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Or(Box::new(
2900 golem_api_grpc::proto::golem::rib::OrExpr {
2901 left: Some(Box::new((*lhs).into())),
2902 right: Some(Box::new((*rhs).into())),
2903 },
2904 )))
2905 }
2906 Expr::ListComprehension {
2907 iterated_variable,
2908 iterable_expr,
2909 yield_expr,
2910 ..
2911 } => Some(
2912 golem_api_grpc::proto::golem::rib::expr::Expr::ListComprehension(Box::new(
2913 golem_api_grpc::proto::golem::rib::ListComprehensionExpr {
2914 iterated_variable: iterated_variable.name(),
2915 iterable_expr: Some(Box::new((*iterable_expr).into())),
2916 yield_expr: Some(Box::new((*yield_expr).into())),
2917 },
2918 )),
2919 ),
2920
2921 Expr::ListReduce {
2922 reduce_variable,
2923 iterated_variable,
2924 iterable_expr,
2925 yield_expr,
2926 init_value_expr,
2927 ..
2928 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::ListReduce(
2929 Box::new(golem_api_grpc::proto::golem::rib::ListReduceExpr {
2930 reduce_variable: reduce_variable.name(),
2931 iterated_variable: iterated_variable.name(),
2932 iterable_expr: Some(Box::new((*iterable_expr).into())),
2933 init_value_expr: Some(Box::new((*init_value_expr).into())),
2934 yield_expr: Some(Box::new((*yield_expr).into())),
2935 }),
2936 )),
2937 Expr::InvokeMethodLazy {
2938 lhs,
2939 method,
2940 generic_type_parameter,
2941 args,
2942 ..
2943 } => Some(
2944 golem_api_grpc::proto::golem::rib::expr::Expr::LazyInvokeMethod(Box::new(
2945 golem_api_grpc::proto::golem::rib::LazyInvokeMethodExpr {
2946 lhs: Some(Box::new((*lhs).into())),
2947 method,
2948 generic_type_parameter: generic_type_parameter.map(|t| t.value),
2949 args: args.into_iter().map(|expr| expr.into()).collect(),
2950 },
2951 )),
2952 ),
2953 };
2954
2955 golem_api_grpc::proto::golem::rib::Expr { expr }
2956 }
2957 }
2958
2959 impl TryFrom<golem_api_grpc::proto::golem::rib::ArmPattern> for ArmPattern {
2960 type Error = String;
2961
2962 fn try_from(
2963 value: golem_api_grpc::proto::golem::rib::ArmPattern,
2964 ) -> Result<Self, Self::Error> {
2965 let pattern = value.pattern.ok_or("Missing pattern")?;
2966 match pattern {
2967 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::WildCard(_) => {
2968 Ok(ArmPattern::WildCard)
2969 }
2970 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::As(asp) => {
2971 let name = asp.name;
2972 let pattern = asp.pattern.ok_or("Missing pattern")?;
2973 Ok(ArmPattern::As(name, Box::new((*pattern).try_into()?)))
2974 }
2975 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::Constructor(
2976 golem_api_grpc::proto::golem::rib::ConstructorArmPattern { name, patterns },
2977 ) => {
2978 let patterns = patterns
2979 .into_iter()
2980 .map(ArmPattern::try_from)
2981 .collect::<Result<Vec<_>, _>>()?;
2982 Ok(ArmPattern::Constructor(name, patterns))
2983 }
2984 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::TupleConstructor(
2985 golem_api_grpc::proto::golem::rib::TupleConstructorArmPattern { patterns },
2986 ) => {
2987 let patterns = patterns
2988 .into_iter()
2989 .map(ArmPattern::try_from)
2990 .collect::<Result<Vec<_>, _>>()?;
2991 Ok(ArmPattern::TupleConstructor(patterns))
2992 }
2993 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::Literal(
2994 golem_api_grpc::proto::golem::rib::LiteralArmPattern { expr },
2995 ) => {
2996 let inner = expr.ok_or("Missing expr")?;
2997 Ok(ArmPattern::Literal(Box::new(inner.try_into()?)))
2998 }
2999 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::RecordConstructor(
3000 golem_api_grpc::proto::golem::rib::RecordConstructorArmPattern { fields },
3001 ) => {
3002 let fields = fields
3003 .into_iter()
3004 .map(|field| {
3005 let name = field.name;
3006 let proto_pattern = field.pattern.ok_or("Missing pattern")?;
3007 let arm_pattern = ArmPattern::try_from(proto_pattern)?;
3008 Ok((name, arm_pattern))
3009 })
3010 .collect::<Result<Vec<_>, String>>()?;
3011 Ok(ArmPattern::RecordConstructor(fields))
3012 }
3013 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::ListConstructor(
3014 golem_api_grpc::proto::golem::rib::ListConstructorArmPattern { patterns },
3015 ) => {
3016 let patterns = patterns
3017 .into_iter()
3018 .map(ArmPattern::try_from)
3019 .collect::<Result<Vec<_>, _>>()?;
3020 Ok(ArmPattern::ListConstructor(patterns))
3021 }
3022 }
3023 }
3024 }
3025
3026 impl From<ArmPattern> for golem_api_grpc::proto::golem::rib::ArmPattern {
3027 fn from(value: ArmPattern) -> Self {
3028 match value {
3029 ArmPattern::WildCard => golem_api_grpc::proto::golem::rib::ArmPattern {
3030 pattern: Some(
3031 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::WildCard(
3032 golem_api_grpc::proto::golem::rib::WildCardArmPattern {},
3033 ),
3034 ),
3035 },
3036 ArmPattern::As(name, pattern) => golem_api_grpc::proto::golem::rib::ArmPattern {
3037 pattern: Some(golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::As(
3038 Box::new(golem_api_grpc::proto::golem::rib::AsArmPattern {
3039 name,
3040 pattern: Some(Box::new((*pattern).into())),
3041 }),
3042 )),
3043 },
3044 ArmPattern::Constructor(name, patterns) => {
3045 golem_api_grpc::proto::golem::rib::ArmPattern {
3046 pattern: Some(
3047 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::Constructor(
3048 golem_api_grpc::proto::golem::rib::ConstructorArmPattern {
3049 name,
3050 patterns: patterns
3051 .into_iter()
3052 .map(golem_api_grpc::proto::golem::rib::ArmPattern::from)
3053 .collect(),
3054 },
3055 ),
3056 ),
3057 }
3058 }
3059 ArmPattern::Literal(expr) => golem_api_grpc::proto::golem::rib::ArmPattern {
3060 pattern: Some(
3061 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::Literal(
3062 golem_api_grpc::proto::golem::rib::LiteralArmPattern {
3063 expr: Some((*expr).into()),
3064 },
3065 ),
3066 ),
3067 },
3068
3069 ArmPattern::TupleConstructor(patterns) => {
3070 golem_api_grpc::proto::golem::rib::ArmPattern {
3071 pattern: Some(
3072 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::TupleConstructor(
3073 golem_api_grpc::proto::golem::rib::TupleConstructorArmPattern {
3074 patterns: patterns
3075 .into_iter()
3076 .map(golem_api_grpc::proto::golem::rib::ArmPattern::from)
3077 .collect(),
3078 },
3079 ),
3080 ),
3081 }
3082 }
3083
3084 ArmPattern::RecordConstructor(fields) => {
3085 golem_api_grpc::proto::golem::rib::ArmPattern {
3086 pattern: Some(
3087 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::RecordConstructor(
3088 golem_api_grpc::proto::golem::rib::RecordConstructorArmPattern {
3089 fields: fields
3090 .into_iter()
3091 .map(|(name, pattern)| {
3092 golem_api_grpc::proto::golem::rib::RecordFieldArmPattern {
3093 name,
3094 pattern: Some(pattern.into()),
3095 }
3096 })
3097 .collect(),
3098 },
3099 ),
3100 ),
3101 }
3102 }
3103
3104 ArmPattern::ListConstructor(patterns) => {
3105 golem_api_grpc::proto::golem::rib::ArmPattern {
3106 pattern: Some(
3107 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::ListConstructor(
3108 golem_api_grpc::proto::golem::rib::ListConstructorArmPattern {
3109 patterns: patterns
3110 .into_iter()
3111 .map(golem_api_grpc::proto::golem::rib::ArmPattern::from)
3112 .collect(),
3113 },
3114 ),
3115 ),
3116 }
3117 }
3118 }
3119 }
3120 }
3121
3122 impl TryFrom<golem_api_grpc::proto::golem::rib::MatchArm> for MatchArm {
3123 type Error = String;
3124
3125 fn try_from(
3126 value: golem_api_grpc::proto::golem::rib::MatchArm,
3127 ) -> Result<Self, Self::Error> {
3128 let pattern = value.pattern.ok_or("Missing pattern")?;
3129 let expr = value.expr.ok_or("Missing expr")?;
3130 Ok(MatchArm::new(pattern.try_into()?, expr.try_into()?))
3131 }
3132 }
3133
3134 impl From<MatchArm> for golem_api_grpc::proto::golem::rib::MatchArm {
3135 fn from(value: MatchArm) -> Self {
3136 let MatchArm {
3137 arm_pattern,
3138 arm_resolution_expr,
3139 } = value;
3140 golem_api_grpc::proto::golem::rib::MatchArm {
3141 pattern: Some(arm_pattern.into()),
3142 expr: Some((*arm_resolution_expr).into()),
3143 }
3144 }
3145 }
3146}
3147
3148fn find_expr(expr: &mut Expr, source_span: &SourceSpan) -> Option<Expr> {
3149 let mut expr = expr.clone();
3150
3151 let mut visitor = ExprVisitor::bottom_up(&mut expr);
3152
3153 while let Some(current) = visitor.pop_back() {
3154 let span = current.source_span();
3155
3156 if source_span.eq(&span) {
3157 return Some(current.clone());
3158 }
3159 }
3160
3161 None
3162}