tinc_build/codegen/cel/functions/
uint.rs1use syn::parse_quote;
2use tinc_cel::CelValue;
3
4use super::Function;
5use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr};
6use crate::codegen::cel::types::CelType;
7
8#[derive(Debug, Clone, Default)]
9pub(crate) struct UInt;
10
11impl Function for UInt {
12 fn name(&self) -> &'static str {
13 "uint"
14 }
15
16 fn syntax(&self) -> &'static str {
17 "<this>.uint()"
18 }
19
20 fn compile(&self, ctx: CompilerCtx) -> Result<CompiledExpr, CompileError> {
21 let Some(this) = ctx.this else {
22 return Err(CompileError::syntax("missing this", self));
23 };
24
25 if !ctx.args.is_empty() {
26 return Err(CompileError::syntax("takes no arguments", self));
27 }
28
29 match this.into_cel()? {
30 CompiledExpr::Constant(ConstantCompiledExpr { value }) => Ok(CompiledExpr::Constant(ConstantCompiledExpr {
31 value: CelValue::cel_to_uint(value)?,
32 })),
33 CompiledExpr::Runtime(RuntimeCompiledExpr { expr, .. }) => Ok(CompiledExpr::Runtime(RuntimeCompiledExpr {
34 ty: CelType::CelValue,
35 expr: parse_quote!(::tinc::__private::cel::CelValue::cel_to_uint(#expr)?),
36 })),
37 }
38 }
39}
40
41#[cfg(test)]
42#[cfg(feature = "prost")]
43#[cfg_attr(coverage_nightly, coverage(off))]
44mod tests {
45 use syn::parse_quote;
46 use tinc_cel::CelValue;
47
48 use crate::codegen::cel::compiler::{CompiledExpr, Compiler, CompilerCtx};
49 use crate::codegen::cel::functions::{Function, UInt};
50 use crate::codegen::cel::types::CelType;
51 use crate::types::{ProtoType, ProtoTypeRegistry, ProtoValueType};
52
53 #[test]
54 fn test_uint_syntax() {
55 let registry = ProtoTypeRegistry::new(crate::Mode::Prost, crate::extern_paths::ExternPaths::new(crate::Mode::Prost));
56 let compiler = Compiler::new(®istry);
57 insta::assert_debug_snapshot!(UInt.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#"
58 Err(
59 InvalidSyntax {
60 message: "missing this",
61 syntax: "<this>.uint()",
62 },
63 )
64 "#);
65
66 insta::assert_debug_snapshot!(UInt.compile(CompilerCtx::new(compiler.child(), Some(CompiledExpr::constant(CelValue::String("13".into()))), &[])), @r"
67 Ok(
68 Constant(
69 ConstantCompiledExpr {
70 value: Number(
71 U64(
72 13,
73 ),
74 ),
75 },
76 ),
77 )
78 ");
79
80 insta::assert_debug_snapshot!(UInt.compile(CompilerCtx::new(compiler.child(), Some(CompiledExpr::constant(CelValue::List(Default::default()))), &[
81 cel_parser::parse("1 + 1").unwrap(), ])), @r#"
83 Err(
84 InvalidSyntax {
85 message: "takes no arguments",
86 syntax: "<this>.uint()",
87 },
88 )
89 "#);
90 }
91
92 #[test]
93 #[cfg(not(valgrind))]
94 fn test_uint_runtime() {
95 let registry = ProtoTypeRegistry::new(crate::Mode::Prost, crate::extern_paths::ExternPaths::new(crate::Mode::Prost));
96 let compiler = Compiler::new(®istry);
97
98 let string_value =
99 CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ProtoValueType::String)), parse_quote!(input));
100
101 let output = UInt
102 .compile(CompilerCtx::new(compiler.child(), Some(string_value), &[]))
103 .unwrap();
104
105 insta::assert_snapshot!(postcompile::compile_str!(
106 postcompile::config! {
107 test: true,
108 dependencies: vec![
109 postcompile::Dependency::version("tinc", "*"),
110 ],
111 },
112 quote::quote! {
113 fn to_int(input: &str) -> Result<::tinc::__private::cel::CelValue<'_>, ::tinc::__private::cel::CelError<'_>> {
114 Ok(#output)
115 }
116
117 #[test]
118 fn test_to_int() {
119 assert_eq!(to_int("55").unwrap(), ::tinc::__private::cel::CelValueConv::conv(55));
120 }
121 },
122 ));
123 }
124}