tinc_build/codegen/cel/functions/
has.rs

1use super::Function;
2use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx};
3
4#[derive(Debug, Clone, Default)]
5pub(crate) struct Has;
6
7// has(field-arg)
8impl Function for Has {
9    fn name(&self) -> &'static str {
10        "has"
11    }
12
13    fn syntax(&self) -> &'static str {
14        "has(<field accessor>)"
15    }
16
17    fn compile(&self, ctx: CompilerCtx) -> Result<CompiledExpr, CompileError> {
18        if ctx.this.is_some() {
19            return Err(CompileError::syntax("function has no this", self));
20        };
21
22        if ctx.args.len() != 1 {
23            return Err(CompileError::syntax("invalid arguments", self));
24        }
25
26        let arg = ctx.resolve(&ctx.args[0]);
27
28        Ok(CompiledExpr::constant(arg.is_ok()))
29    }
30}
31
32#[cfg(test)]
33#[cfg(feature = "prost")]
34#[cfg_attr(coverage_nightly, coverage(off))]
35mod tests {
36    use tinc_cel::CelValue;
37
38    use crate::codegen::cel::compiler::{CompiledExpr, Compiler, CompilerCtx};
39    use crate::codegen::cel::functions::{Function, Has};
40    use crate::extern_paths::ExternPaths;
41    use crate::path_set::PathSet;
42    use crate::types::ProtoTypeRegistry;
43
44    #[test]
45    fn test_has_syntax() {
46        let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default());
47        let mut compiler = Compiler::new(&registry);
48        insta::assert_debug_snapshot!(Has.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#"
49        Err(
50            InvalidSyntax {
51                message: "invalid arguments",
52                syntax: "has(<field accessor>)",
53            },
54        )
55        "#);
56
57        insta::assert_debug_snapshot!(Has.compile(CompilerCtx::new(compiler.child(), Some(CompiledExpr::constant(CelValue::String("hi".into()))), &[])), @r#"
58        Err(
59            InvalidSyntax {
60                message: "function has no this",
61                syntax: "has(<field accessor>)",
62            },
63        )
64        "#);
65
66        insta::assert_debug_snapshot!(Has.compile(CompilerCtx::new(compiler.child(), None, &[
67            cel_parser::parse("x").unwrap(),
68        ])), @r"
69        Ok(
70            Constant(
71                ConstantCompiledExpr {
72                    value: Bool(
73                        false,
74                    ),
75                },
76            ),
77        )
78        ");
79
80        compiler.add_variable("x", CompiledExpr::constant(CelValue::Null));
81
82        insta::assert_debug_snapshot!(Has.compile(CompilerCtx::new(compiler.child(), None, &[
83            cel_parser::parse("x").unwrap(),
84        ])), @r"
85        Ok(
86            Constant(
87                ConstantCompiledExpr {
88                    value: Bool(
89                        true,
90                    ),
91                },
92            ),
93        )
94        ");
95    }
96}