vrl/compiler/expression/
object.rs1use std::{collections::BTreeMap, fmt, ops::Deref};
2
3use crate::value::{KeyString, Value};
4use crate::{
5 compiler::{
6 Context, Expression, TypeDef,
7 expression::{Expr, Resolved},
8 state::{TypeInfo, TypeState},
9 },
10 value::Kind,
11};
12
13#[derive(Debug, Clone, PartialEq)]
14pub struct Object {
15 inner: BTreeMap<KeyString, Expr>,
16}
17
18impl Object {
19 #[must_use]
20 pub fn new(inner: BTreeMap<KeyString, Expr>) -> Self {
21 Self { inner }
22 }
23}
24
25impl Deref for Object {
26 type Target = BTreeMap<KeyString, Expr>;
27
28 fn deref(&self) -> &Self::Target {
29 &self.inner
30 }
31}
32
33impl Expression for Object {
34 fn resolve(&self, ctx: &mut Context) -> Resolved {
35 self.inner
36 .iter()
37 .map(|(key, expr)| expr.resolve(ctx).map(|v| (key.clone(), v)))
38 .collect::<Result<BTreeMap<_, _>, _>>()
39 .map(Value::Object)
40 }
41
42 fn resolve_constant(&self, state: &TypeState) -> Option<Value> {
43 self.inner
44 .iter()
45 .map(|(key, expr)| expr.resolve_constant(state).map(|v| (key.clone(), v)))
46 .collect::<Option<BTreeMap<_, _>>>()
47 .map(Value::Object)
48 }
49
50 fn type_info(&self, state: &TypeState) -> TypeInfo {
51 let mut state = state.clone();
52 let mut fallible = false;
53 let mut returns = Kind::never();
54
55 let mut type_defs = BTreeMap::new();
56 for (k, expr) in &self.inner {
57 let type_def = expr.apply_type_info(&mut state).upgrade_undefined();
58 returns.merge_keep(type_def.returns().clone(), false);
59
60 fallible |= type_def.is_fallible();
62
63 if type_def.is_never() {
65 return TypeInfo::new(
66 state,
67 TypeDef::never()
68 .maybe_fallible(fallible)
69 .with_returns(returns),
70 );
71 }
72 type_defs.insert(k.clone(), type_def);
73 }
74
75 let collection = type_defs
76 .into_iter()
77 .map(|(field, type_def)| (field.into(), type_def.into()))
78 .collect::<BTreeMap<_, _>>();
79
80 let result = TypeDef::object(collection)
81 .maybe_fallible(fallible)
82 .with_returns(returns);
83 TypeInfo::new(state, result)
84 }
85}
86
87impl fmt::Display for Object {
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89 let exprs = self
90 .inner
91 .iter()
92 .map(|(k, v)| format!(r#""{k}": {v}"#))
93 .collect::<Vec<_>>()
94 .join(", ");
95
96 write!(f, "{{ {exprs} }}")
97 }
98}
99
100impl From<BTreeMap<KeyString, Expr>> for Object {
101 fn from(inner: BTreeMap<KeyString, Expr>) -> Self {
102 Self { inner }
103 }
104}