cala_cel_interpreter/context/
mod.rs1mod decimal;
2mod package;
3mod timestamp;
4
5use std::{borrow::Cow, collections::HashMap};
6
7use crate::{builtins, cel_type::CelType, error::*, value::*};
8
9use package::CelPackage;
10
11const SELF_PACKAGE_NAME: Cow<'static, str> = Cow::Borrowed("self");
12
13type CelFunction = Box<dyn Fn(Vec<CelValue>) -> Result<CelValue, CelError> + Sync>;
14pub(crate) type CelMemberFunction =
15 Box<dyn Fn(&CelValue, Vec<CelValue>) -> Result<CelValue, CelError> + Sync>;
16
17#[derive(Debug)]
18pub struct CelContext {
19 idents: HashMap<Cow<'static, str>, ContextItem>,
20}
21
22impl CelContext {
23 pub fn add_variable(&mut self, name: impl Into<Cow<'static, str>>, value: impl Into<CelValue>) {
24 self.idents
25 .insert(name.into(), ContextItem::Value(value.into()));
26 }
27
28 pub fn new() -> Self {
29 let mut idents = HashMap::new();
30 idents.insert(
31 Cow::Borrowed("date"),
32 ContextItem::Function(Box::new(builtins::date)),
33 );
34 idents.insert(
35 Cow::Borrowed("uuid"),
36 ContextItem::Function(Box::new(builtins::uuid)),
37 );
38 idents.insert(
39 Cow::Borrowed("decimal"),
40 ContextItem::Package(&decimal::CEL_PACKAGE),
41 );
42
43 idents.insert(
44 Cow::Borrowed("timestamp"),
45 ContextItem::Package(×tamp::CEL_PACKAGE),
46 );
47
48 Self { idents }
49 }
50
51 pub(crate) fn lookup_ident(&self, name: &str) -> Result<&ContextItem, CelError> {
52 self.idents
53 .get(name)
54 .ok_or_else(|| CelError::UnknownIdent(name.to_string()))
55 }
56
57 pub(crate) fn lookup_member_fn(
58 &self,
59 value: &CelValue,
60 name: &str,
61 ) -> Result<&CelMemberFunction, CelError> {
62 let package_name = CelType::from(value).package_name();
63 let package = if let Some(ContextItem::Package(package)) = self.idents.get(package_name) {
64 package
65 } else {
66 return Err(CelError::UnknownPackage(package_name));
67 };
68
69 package.lookup_member(value, name)
70 }
71}
72impl Default for CelContext {
73 fn default() -> Self {
74 Self::new()
75 }
76}
77
78pub(crate) enum ContextItem {
79 Value(CelValue),
80 Function(CelFunction),
81 Package(&'static CelPackage),
82}
83
84impl std::fmt::Debug for ContextItem {
85 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
86 match self {
87 ContextItem::Value(val) => write!(f, "Value({val:?})"),
88 ContextItem::Function(_) => write!(f, "Function"),
89 ContextItem::Package(_) => write!(f, "Package"),
90 }
91 }
92}