1#[cfg(feature = "strings")]
46pub mod strings;
47
48#[cfg(feature = "lists")]
49pub mod lists;
50
51#[cfg(feature = "sets")]
52pub mod sets;
53
54#[cfg(feature = "regex_funcs")]
55pub mod regex_funcs;
56
57#[cfg(feature = "urls")]
58pub mod urls;
59
60#[cfg(feature = "ip")]
61pub mod ip;
62
63#[cfg(feature = "semver_funcs")]
64pub mod semver_funcs;
65
66#[cfg(feature = "format")]
67pub mod format;
68
69#[cfg(feature = "quantity")]
70pub mod quantity;
71
72#[cfg(feature = "jsonpatch")]
73pub mod jsonpatch;
74
75#[cfg(feature = "named_format")]
76pub mod named_format;
77
78#[cfg(feature = "math")]
79pub mod math;
80
81#[cfg(feature = "encoders")]
82pub mod encoders;
83
84#[cfg(feature = "validation")]
85pub mod escaping;
86
87#[cfg(feature = "validation")]
88pub mod values;
89
90#[cfg(feature = "validation")]
91pub mod compilation;
92
93#[cfg(feature = "validation")]
94pub mod validation;
95
96mod dispatch;
97mod value_ops;
98
99pub fn register_all(ctx: &mut cel::Context<'_>) {
101 #[cfg(feature = "strings")]
102 strings::register(ctx);
103
104 #[cfg(feature = "lists")]
105 lists::register(ctx);
106
107 #[cfg(feature = "sets")]
108 sets::register(ctx);
109
110 #[cfg(feature = "regex_funcs")]
111 regex_funcs::register(ctx);
112
113 #[cfg(feature = "urls")]
114 urls::register(ctx);
115
116 #[cfg(feature = "ip")]
117 ip::register(ctx);
118
119 #[cfg(feature = "semver_funcs")]
120 semver_funcs::register(ctx);
121
122 #[cfg(feature = "format")]
123 format::register(ctx);
124
125 #[cfg(feature = "quantity")]
126 quantity::register(ctx);
127
128 #[cfg(feature = "jsonpatch")]
129 jsonpatch::register(ctx);
130
131 #[cfg(feature = "named_format")]
132 named_format::register(ctx);
133
134 #[cfg(feature = "math")]
135 math::register(ctx);
136
137 #[cfg(feature = "encoders")]
138 encoders::register(ctx);
139
140 dispatch::register(ctx);
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147
148 #[allow(unused_imports)]
149 use std::sync::Arc;
150
151 use cel::{Context, Program, Value};
152
153 #[allow(dead_code)]
154 fn eval(expr: &str) -> Value {
155 let mut ctx = Context::default();
156 register_all(&mut ctx);
157 Program::compile(expr).unwrap().execute(&ctx).unwrap()
158 }
159
160 #[test]
161 #[cfg(feature = "strings")]
162 fn test_integration_strings() {
163 assert_eq!(
164 eval("'hello'.charAt(1)"),
165 Value::String(Arc::new("e".into()))
166 );
167 assert_eq!(
168 eval("'HELLO'.lowerAscii()"),
169 Value::String(Arc::new("hello".into()))
170 );
171 assert_eq!(
172 eval("' hello '.trim()"),
173 Value::String(Arc::new("hello".into()))
174 );
175 }
176
177 #[test]
178 #[cfg(feature = "lists")]
179 fn test_integration_lists() {
180 assert_eq!(eval("[1, 2, 3].isSorted()"), Value::Bool(true));
181 assert_eq!(eval("[3, 1, 2].isSorted()"), Value::Bool(false));
182 assert_eq!(eval("[1, 2, 3].sum()"), Value::Int(6));
183 }
184
185 #[test]
186 #[cfg(feature = "sets")]
187 fn test_integration_sets() {
188 assert_eq!(eval("sets.contains([1, 2, 3], [1, 2])"), Value::Bool(true));
189 assert_eq!(eval("sets.intersects([1, 2], [2, 3])"), Value::Bool(true));
190 }
191
192 #[test]
193 #[cfg(feature = "regex_funcs")]
194 fn test_integration_regex() {
195 assert_eq!(
196 eval("'hello world'.find('[a-z]+')"),
197 Value::String(Arc::new("hello".into()))
198 );
199 }
200
201 #[test]
202 #[cfg(feature = "strings")]
203 fn test_dispatch_index_of_string() {
204 assert_eq!(eval("'hello world'.indexOf('world')"), Value::Int(6));
205 assert_eq!(eval("'hello'.indexOf('x')"), Value::Int(-1));
206 }
207
208 #[test]
209 #[cfg(feature = "lists")]
210 fn test_dispatch_index_of_list() {
211 assert_eq!(eval("[1, 2, 3].indexOf(2)"), Value::Int(1));
212 assert_eq!(eval("[1, 2, 3].indexOf(4)"), Value::Int(-1));
213 }
214
215 #[test]
216 #[cfg(feature = "strings")]
217 fn test_dispatch_last_index_of_string() {
218 assert_eq!(eval("'abcabc'.lastIndexOf('abc')"), Value::Int(3));
219 }
220
221 #[test]
222 #[cfg(feature = "lists")]
223 fn test_dispatch_last_index_of_list() {
224 assert_eq!(eval("[1, 2, 3, 2].lastIndexOf(2)"), Value::Int(3));
225 }
226
227 #[test]
228 #[cfg(feature = "format")]
229 fn test_integration_format() {
230 assert_eq!(
231 eval("'hello %s'.format(['world'])"),
232 Value::String(Arc::new("hello world".into()))
233 );
234 assert_eq!(
235 eval("'%d items'.format([5])"),
236 Value::String(Arc::new("5 items".into()))
237 );
238 }
239
240 #[test]
241 #[cfg(feature = "semver_funcs")]
242 fn test_integration_semver() {
243 assert_eq!(eval("isSemver('1.2.3')"), Value::Bool(true));
244 assert_eq!(eval("semver('1.2.3').major()"), Value::Int(1));
245 assert_eq!(
246 eval("semver('2.0.0').isGreaterThan(semver('1.0.0'))"),
247 Value::Bool(true)
248 );
249 }
250}