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::types::ProtoTypeRegistry;
41
42    #[test]
43    fn test_has_syntax() {
44        let registry = ProtoTypeRegistry::new(crate::Mode::Prost, crate::extern_paths::ExternPaths::new(crate::Mode::Prost));
45        let mut compiler = Compiler::new(&registry);
46        insta::assert_debug_snapshot!(Has.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#"
47        Err(
48            InvalidSyntax {
49                message: "invalid arguments",
50                syntax: "has(<field accessor>)",
51            },
52        )
53        "#);
54
55        insta::assert_debug_snapshot!(Has.compile(CompilerCtx::new(compiler.child(), Some(CompiledExpr::constant(CelValue::String("hi".into()))), &[])), @r#"
56        Err(
57            InvalidSyntax {
58                message: "function has no this",
59                syntax: "has(<field accessor>)",
60            },
61        )
62        "#);
63
64        insta::assert_debug_snapshot!(Has.compile(CompilerCtx::new(compiler.child(), None, &[
65            cel_parser::parse("x").unwrap(),
66        ])), @r"
67        Ok(
68            Constant(
69                ConstantCompiledExpr {
70                    value: Bool(
71                        false,
72                    ),
73                },
74            ),
75        )
76        ");
77
78        compiler.add_variable("x", CompiledExpr::constant(CelValue::Null));
79
80        insta::assert_debug_snapshot!(Has.compile(CompilerCtx::new(compiler.child(), None, &[
81            cel_parser::parse("x").unwrap(),
82        ])), @r"
83        Ok(
84            Constant(
85                ConstantCompiledExpr {
86                    value: Bool(
87                        true,
88                    ),
89                },
90            ),
91        )
92        ");
93    }
94}