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