vrl/compiler/expression/
if_statement.rs1use std::fmt;
2
3use crate::value::Value;
4
5use crate::compiler::state::{TypeInfo, TypeState};
6use crate::compiler::{
7 Context, Expression,
8 expression::{Block, Predicate, Resolved},
9 value::VrlValueConvert,
10};
11
12#[derive(Debug, Clone, PartialEq)]
13pub struct IfStatement {
14 pub predicate: Predicate,
15 pub if_block: Block,
16 pub else_block: Option<Block>,
17}
18
19impl Expression for IfStatement {
20 fn resolve(&self, ctx: &mut Context) -> Resolved {
21 let predicate = self.predicate.resolve(ctx)?.try_boolean()?;
22
23 if predicate {
24 self.if_block.resolve(ctx)
25 } else {
26 self.else_block
27 .as_ref()
28 .map_or(Ok(Value::Null), |block| block.resolve(ctx))
29 }
30 }
31
32 fn type_info(&self, state: &TypeState) -> TypeInfo {
33 let mut state = state.clone();
34 let predicate_info = self.predicate.apply_type_info(&mut state);
35
36 let if_info = self.if_block.type_info(&state);
37
38 if let Some(else_block) = &self.else_block {
39 let else_info = else_block.type_info(&state);
40
41 let final_state = if_info.state.merge(else_info.state);
43
44 let mut result = if_info.result.union(else_info.result);
46
47 result
49 .returns_mut()
50 .merge_keep(predicate_info.returns().clone(), false);
51
52 TypeInfo::new(final_state, result)
53 } else {
54 let final_state = if_info.state.merge(state);
56
57 let mut result = if_info.result.or_null();
59
60 result
62 .returns_mut()
63 .merge_keep(predicate_info.returns().clone(), false);
64
65 TypeInfo::new(final_state, result)
66 }
67 }
68}
69
70impl fmt::Display for IfStatement {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 f.write_str("if ")?;
73 self.predicate.fmt(f)?;
74 f.write_str(" ")?;
75 self.if_block.fmt(f)?;
76
77 if let Some(alt) = &self.else_block {
78 f.write_str(" else")?;
79 alt.fmt(f)?;
80 }
81
82 Ok(())
83 }
84}