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