1#![recursion_limit="100"]
94#![deny(missing_docs)]
95
96#![forbid(unsafe_code)]
97#[macro_use]
98extern crate quick_error;
99extern crate serde;
100extern crate serde_json;
101
102mod math;
103mod function;
104mod operator;
105mod node;
106mod tree;
107mod error;
108mod builtin;
109mod expr;
110
111pub use expr::ExecOptions;
112use function::ConstFunction;
113pub use serde_json::Value;
114pub use error::Error;
115pub use function::Function;
116pub use expr::Expr;
117
118use std::{collections::HashMap, rc::Rc, cell::RefCell};
119use serde_json::to_value as json_to_value;
120use serde::Serialize;
121
122pub fn to_value<S: Serialize>(v: S) -> Value {
124 json_to_value(v).unwrap()
125}
126
127pub type Context = HashMap<String, Value>;
129pub type Contexts = Vec<Context>;
131pub type Functions = HashMap<String, Function>;
133pub type ConstFunctions = HashMap<String, ConstFunction>;
135
136pub fn eval(expr: &str) -> Result<Value, Error> {
138 Expr::new(expr).compile()?.exec()
139}
140
141type Compiled = Box<dyn Fn(&[Context], &Functions, Rc<RefCell<ConstFunctions>>) -> Result<Value, Error>>;
142
143#[cfg(test)]
144mod tests {
145 use std::collections::HashMap;
146
147 use crate::to_value;
148 use crate::error::Error;
149 use crate::Expr;
150 use crate::tree::Tree;
151 use crate::Value;
152 use crate::eval;
153
154 #[test]
155 fn test_add() {
156 assert_eq!(eval("2 + 3"), Ok(to_value(5)));
157 }
158
159 #[test]
160 fn test_brackets_add() {
161 assert_eq!(eval("(2 + 3) + (3 + 5)"), Ok(to_value(13)));
162 }
163
164 #[test]
165 fn test_brackets_float_add() {
166 assert_eq!(eval("(2 + 3.2) + (3 + 5)"), Ok(to_value(13.2)));
167 }
168
169 #[test]
170 fn test_brackets_float_mul() {
171 assert_eq!(eval("(2 + 3.2) * 5"), Ok(to_value(26.0)));
172 }
173
174 #[test]
175 fn test_brackets_sub() {
176 assert_eq!(eval("(4 - 3) * 5"), Ok(to_value(5)));
177 }
178
179 #[test]
180 fn test_useless_brackets() {
181 assert_eq!(eval("2 + 3 + (5)"), Ok(to_value(10)));
182 }
183
184 #[test]
185 fn test_error_brackets_not_with_function() {
186 assert_eq!(eval("5 + ()"), Err(Error::BracketNotWithFunction));
187 }
188
189 #[test]
190 fn test_deep_brackets() {
191 assert_eq!(eval("(2 + (3 + 4) + (6 + (6 + 7)) + 5)"), Ok(to_value(33)));
192 }
193
194 #[test]
195 fn test_brackets_div() {
196 assert_eq!(eval("(4 / (2 + 2)) * 5"), Ok(to_value(5.0)));
197 }
198
199 #[test]
200 fn test_min() {
201 assert_eq!(eval("min(30, 5, 245, 20)"), Ok(to_value(5)));
202 }
203
204 #[test]
205 fn test_min_brackets() {
206 assert_eq!(
207 eval("(min(30, 5, 245, 20) * 10 + (5 + 5) * 5)"),
208 Ok(to_value(100))
209 );
210 }
211
212 #[test]
213 fn test_min_and_mul() {
214 assert_eq!(eval("min(30, 5, 245, 20) * 10"), Ok(to_value(50)));
215 }
216
217 #[test]
218 fn test_max() {
219 assert_eq!(eval("max(30, 5, 245, 20)"), Ok(to_value(245)));
220 }
221
222 #[test]
223 fn test_max_brackets() {
224 assert_eq!(
225 eval("(max(30, 5, 245, 20) * 10 + (5 + 5) * 5)"),
226 Ok(to_value(2500))
227 );
228 }
229
230 #[test]
231 fn test_max_and_mul() {
232 assert_eq!(eval("max(30, 5, 245, 20) * 10"), Ok(to_value(2450)));
233 }
234
235 #[test]
236 fn test_len_array() {
237 assert_eq!(eval("len(array(2, 3, 4, 5, 6))"), Ok(to_value(5)));
238 }
239
240 #[test]
241 fn test_null_and_number() {
242 assert_eq!(eval("hos != 0"), Ok(to_value(true)));
243 assert_eq!(eval("hos > 0"), Ok(to_value(false)));
244 }
245
246 #[test]
247 fn test_len_string() {
248 assert_eq!(eval("len('Hello world!')"), Ok(to_value(12)));
249 }
250
251 #[test]
252 fn test_len_object() {
253 let mut object = HashMap::new();
254 object.insert("field1", "value1");
255 object.insert("field2", "value2");
256 object.insert("field3", "value3");
257 assert_eq!(
258 Expr::new("len(object)").value("object", object).exec(),
259 Ok(to_value(3_i64))
260 );
261 }
262
263 #[test]
264 fn test_brackets_1() {
265 assert_eq!(eval("(5) + (min(3, 4, 5)) + 20"), Ok(to_value(28)));
266 }
267
268 #[test]
269 fn test_brackets_2() {
270 assert_eq!(eval("(((5) / 5))"), Ok(to_value(1.0)));
271 }
272
273 #[test]
274 fn test_string_add() {
275 assert_eq!(eval(r#""Hello"+", world!""#), Ok(to_value("Hello, world!")));
276 }
277
278 #[test]
279 fn test_equal() {
280 assert_eq!(eval("1 == 1"), Ok(to_value(true)));
281 }
282
283 #[test]
284 fn test_not_equal() {
285 assert_eq!(eval("1 != 2"), Ok(to_value(true)));
286 }
287
288 #[test]
289 fn test_multiple_equal() {
290 assert_eq!(eval("(1 == 2) == (2 == 3)"), Ok(to_value(true)));
291 }
292
293 #[test]
294 fn test_multiple_not_equal() {
295 assert_eq!(eval("(1 != 2) == (2 != 3)"), Ok(to_value(true)));
296 }
297
298 #[test]
299 fn test_greater_than() {
300 assert_eq!(eval("1 > 2"), Ok(to_value(false)));
301 assert_eq!(eval("2 > 1"), Ok(to_value(true)));
302 }
303
304 #[test]
305 fn test_less_than() {
306 assert_eq!(eval("2 < 1"), Ok(to_value(false)));
307 assert_eq!(eval("1 < 2"), Ok(to_value(true)));
308 }
309
310 #[test]
311 fn test_greater_and_less() {
312 assert_eq!(eval("(2 > 1) == (1 < 2)"), Ok(to_value(true)));
313 }
314
315 #[test]
316 fn test_ge() {
317 assert_eq!(eval("2 >= 1"), Ok(to_value(true)));
318 assert_eq!(eval("2 >= 2"), Ok(to_value(true)));
319 assert_eq!(eval("2 >= 3"), Ok(to_value(false)));
320 }
321
322 #[test]
323 fn test_le() {
324 assert_eq!(eval("2 <= 1"), Ok(to_value(false)));
325 assert_eq!(eval("2 <= 2"), Ok(to_value(true)));
326 assert_eq!(eval("2 <= 3"), Ok(to_value(true)));
327 }
328
329 #[test]
330 fn test_quotes() {
331 assert_eq!(eval(r#""1><2" + "3<>4""#), Ok(to_value("1><23<>4")));
332 assert_eq!(eval(r#""1==2" + "3--4""#), Ok(to_value("1==23--4")));
333 assert_eq!(eval(r#""1!=2" + "3>>4""#), Ok(to_value("1!=23>>4")));
334 assert_eq!(eval(r#""><1!=2" + "3>>4""#), Ok(to_value("><1!=23>>4")));
335 }
336
337 #[test]
338 fn test_single_quote() {
339 assert_eq!(eval(r#"'1><2' + '3<>4'"#), Ok(to_value("1><23<>4")));
340 assert_eq!(eval(r#"'1==2' + '3--4'"#), Ok(to_value("1==23--4")));
341 assert_eq!(eval(r#"'1!=2' + '3>>4'"#), Ok(to_value("1!=23>>4")));
342 assert_eq!(eval(r#"'!=1<>2' + '3>>4'"#), Ok(to_value("!=1<>23>>4")));
343 }
344
345 #[test]
346 fn test_single_and_double_quote() {
347 assert_eq!(
348 eval(r#"' """" ' + ' """" '"#),
349 Ok(to_value(r#" """" """" "#))
350 );
351 }
352
353 #[test]
354 fn test_double_and_single_quote() {
355 assert_eq!(
356 eval(r#"" '''' " + " '''' ""#),
357 Ok(to_value(r#" '''' '''' "#))
358 );
359 }
360
361 #[test]
362 fn test_array() {
363 assert_eq!(eval("array(1, 2, 3, 4)"), Ok(to_value(vec![1, 2, 3, 4])));
364 }
365
366 #[test]
367 fn test_range() {
368 assert_eq!(eval("0..5"), Ok(to_value(vec![0, 1, 2, 3, 4])));
369 }
370
371 #[test]
372 fn test_range_and_min() {
373 assert_eq!(eval("min(0..5)"), Ok(to_value(0)));
374 }
375
376 #[test]
377 fn test_rem_1() {
378 assert_eq!(eval("2 % 2"), Ok(to_value(0)));
379 }
380
381 #[test]
382 fn test_rem_2() {
383 assert_eq!(eval("5 % 56 % 5"), Ok(to_value(0)));
384 }
385
386 #[test]
387 fn test_rem_3() {
388 assert_eq!(eval("5.5 % 23"), Ok(to_value(5.5)));
389 }
390
391 #[test]
392 fn test_rem_4() {
393 assert_eq!(eval("23 % 5.5"), Ok(to_value(1.0)));
394 }
395
396 #[test]
397 fn test_and_1() {
398 assert_eq!(eval("3 > 2 && 2 > 1"), Ok(to_value(true)));
399 }
400
401 #[test]
402 fn test_and_2() {
403 assert_eq!(eval("3 == 2 && 2 == 1"), Ok(to_value(false)));
404 }
405
406 #[test]
407 fn test_and_3() {
408 assert_eq!(eval("3 > 2 && 2 == 1"), Ok(to_value(false)));
409 }
410
411 #[test]
412 fn test_or_1() {
413 assert_eq!(eval("3 > 2 || 2 > 1"), Ok(to_value(true)));
414 }
415
416 #[test]
417 fn test_or_2() {
418 assert_eq!(eval("3 < 2 || 2 < 1"), Ok(to_value(false)));
419 }
420
421 #[test]
422 fn test_or_3() {
423 assert_eq!(eval("3 > 2 || 2 < 1"), Ok(to_value(true)));
424 }
425
426 #[test]
427 fn test_or_4() {
428 assert_eq!(eval("3 < 2 || 2 > 1"), Ok(to_value(true)));
429 }
430
431 #[test]
432 fn test_not() {
433 assert_eq!(eval("!false"), Ok(to_value(true)));
434 assert_eq!(eval("!true"), Ok(to_value(false)));
435 assert_eq!(eval("!(1 != 2)"), Ok(to_value(false)));
436 assert_eq!(eval("!(1 == 2)"), Ok(to_value(true)));
437 assert_eq!(eval("!(1 == 2) == true"), Ok(to_value(true)));
438 }
439
440 #[test]
441 fn test_not_and_brackets() {
442 assert_eq!(eval("(!(1 == 2)) == true"), Ok(to_value(true)));
443 }
444
445 #[test]
446 fn test_object_access() {
447 let mut object = HashMap::new();
448 object.insert("foo", "Foo, hello world!");
449 object.insert("bar", "Bar, hello world!");
450 assert_eq!(
451 Expr::new("object.foo == 'Foo, hello world!'")
452 .value("object", object)
453 .exec(),
454 Ok(to_value(true))
455 );
456 }
457
458 #[test]
459 fn test_object_dynamic_access() {
460 let mut object = HashMap::new();
461 object.insert("foo", "Foo, hello world!");
462 object.insert("bar", "Bar, hello world!");
463 assert_eq!(
464 Expr::new("object['foo'] == 'Foo, hello world!'")
465 .value("object", object)
466 .exec(),
467 Ok(to_value(true))
468 );
469 }
470
471 #[test]
472 fn test_object_dynamic_access_2() {
473 let mut object = HashMap::new();
474 object.insert("foo", "Foo, hello world!");
475 object.insert("bar", "Bar, hello world!");
476 assert_eq!(
477 Expr::new("object[foo] == 'Foo, hello world!'")
478 .value("object", object)
479 .value("foo", "foo")
480 .exec(),
481 Ok(to_value(true))
482 );
483 }
484
485 #[test]
486 fn test_path() {
487 assert_eq!(Expr::new("array[2-2].foo[2-2]").exec(), Ok(Value::Null));
488 }
489
490 #[test]
491 fn test_array_access() {
492 let array = vec!["hello", "world", "!"];
493 assert_eq!(
494 Expr::new(
495 "array[1-1] == 'hello' && array[1] == 'world' && array[2] == '!'",
496 ).value("array", array)
497 .exec(),
498 Ok(to_value(true))
499 );
500 }
501
502 #[test]
503 fn test_builtin_is_empty() {
504 assert_eq!(
505 Expr::new("is_empty(array)")
506 .value("array", Vec::<String>::new())
507 .exec(),
508 Ok(to_value(true))
509 );
510 }
511
512 #[test]
513 fn test_builtin_min() {
514 assert_eq!(
515 Expr::new("min(array)")
516 .value("array", vec![23_i32, 34_i32, 45_i32, 2_i32])
517 .exec(),
518 Ok(to_value(2_i32))
519 );
520 }
521
522 #[test]
523 fn test_custom_function() {
524 assert_eq!(
525 Expr::new("output()")
526 .function(
527 "output",
528 |_| Ok(to_value("This is custom function's output")),
529 )
530 .exec(),
531 Ok(to_value("This is custom function's output"))
532 );
533 }
534
535 #[test]
536 fn test_error_start_with_non_value_operator() {
537 let mut tree = Tree {
538 raw: "+ + 5".to_owned(),
539 ..Default::default()
540 };
541
542 tree.parse_pos().unwrap();
543 tree.parse_operators().unwrap();
544
545 assert_eq!(tree.parse_node(), Err(Error::StartWithNonValueOperator));
546 }
547
548 #[test]
549 fn test_error_duplicate_operator() {
550 let mut tree = Tree {
551 raw: "5 + + 5".to_owned(),
552 ..Default::default()
553 };
554
555 tree.parse_pos().unwrap();
556 tree.parse_operators().unwrap();
557
558 assert_eq!(tree.parse_node(), Err(Error::DuplicateOperatorNode));
559 }
560
561 #[test]
562 fn test_error_duplicate_value() {
563 let mut tree = Tree {
564 raw: "2 + 6 5".to_owned(),
565 ..Default::default()
566 };
567
568 tree.parse_pos().unwrap();
569 tree.parse_operators().unwrap();
570
571 assert_eq!(tree.parse_node(), Err(Error::DuplicateValueNode));
572 }
573
574 #[test]
575 fn test_error_unpaired_brackets() {
576 let mut tree = Tree {
577 raw: "(2 + 3)) * 5".to_owned(),
578 ..Default::default()
579 };
580
581 tree.parse_pos().unwrap();
582
583 assert_eq!(tree.parse_operators(), Err(Error::UnpairedBrackets));
584 }
585
586 #[test]
587 fn test_error_comma() {
588 let mut tree = Tree {
589 raw: ", 2 + 5".to_owned(),
590 ..Default::default()
591 };
592
593 tree.parse_pos().unwrap();
594 tree.parse_operators().unwrap();
595
596 assert_eq!(tree.parse_node(), Err(Error::CommaNotWithFunction));
597 }
598
599 #[test]
600 fn test_eval_issue_2() {
601 assert_eq!(eval("2 * (4 + 0) + 4"), Ok(to_value(12)));
602 assert_eq!(eval("2 * (2 + 2) + (1 + 3)"), Ok(to_value(12)));
603 assert_eq!(eval("2 * (4) + (4)"), Ok(to_value(12)));
604 }
605
606 #[test]
607 fn test_eval_math_function(){
608 fn pow(v: Vec<Value>)->Result<Value, Error>{
609 let Some(base) = v.get(0) else {
610 return Err(Error::ArgumentsLess(2));
611 };
612 let Some(pow) = v.get(1) else {
613 return Err(Error::ArgumentsLess(2));
614 };
615 let Value::Number(base) = base else {
616 return Err(Error::ExpectedNumber);
617 };
618 let Value::Number(pow) = pow else {
619 return Err(Error::ExpectedNumber);
620 };
621 let Some(base) = base.as_i64() else {
622 return Err(Error::Custom("Must can into i64".into()));
623 };
624 let Some(pow) = pow.as_u64() else {
625 return Err(Error::Custom("Must can into u64".into()));
626 };
627 Ok(base.pow(pow as u32).into())
628 }
629 fn add2(v: Vec<Value>)->Result<Value, Error>{
630 let Some(base) = v.get(0) else {
631 return Err(Error::ArgumentsLess(1));
632 };
633 let Value::Number(base) = base else {
634 return Err(Error::ExpectedNumber);
635 };
636 let Some(base) = base.as_i64() else {
637 return Err(Error::Custom("Must can into i64".into()));
638 };
639 Ok((base + 2).into())
640 }
641 let e = Expr::new("add2(pow(2, 2) + pow(2, 2))").const_function("pow", pow).const_function("add2",add2);
642 assert_eq!(e.compile().unwrap().exec(), Ok(to_value(4 + 4 + 2)));
643 }
644}
645
646#[cfg(all(feature = "unstable", test))]
647mod benches {
648 extern crate test;
649 use resolver;
650 use tree::Tree;
651 use Expr;
652
653 #[bench]
654 fn bench_deep_brackets(b: &mut test::Bencher) {
655 b.iter(|| eval("(2 + (3 + 4) + (6 + (6 + 7)) + 5)"));
656 }
657
658 #[bench]
659 fn bench_parse_pos(b: &mut test::Bencher) {
660 let mut tree = Tree {
661 raw: "(2 + (3 + 4) + (6 + (6 + 7)) + 5)".to_owned(),
662 ..Default::default()
663 };
664
665 b.iter(|| tree.parse_pos().unwrap());
666 }
667
668 #[bench]
669 fn bench_parse_operators(b: &mut test::Bencher) {
670 let mut tree = Tree {
671 raw: "(2 + (3 + 4) + (6 + (6 + 7)) + 5)".to_owned(),
672 ..Default::default()
673 };
674
675 tree.parse_pos().unwrap();
676 b.iter(|| tree.parse_operators().unwrap());
677 }
678
679 #[bench]
680 fn bench_parse_nodes(b: &mut test::Bencher) {
681 let mut tree = Tree {
682 raw: "(2 + (3 + 4) + (6 + (6 + 7)) + 5)".to_owned(),
683 ..Default::default()
684 };
685
686 tree.parse_pos().unwrap();
687 tree.parse_operators().unwrap();
688 b.iter(|| tree.parse_node().unwrap());
689 }
690
691 #[bench]
692 fn bench_compile(b: &mut test::Bencher) {
693 b.iter(|| {
694 let mut tree = Tree {
695 raw: "(2 + (3 + 4) + (6 + (6 + 7)) + 5)".to_owned(),
696 ..Default::default()
697 };
698 tree.parse_pos().unwrap();
699 tree.parse_operators().unwrap();
700 tree.parse_node().unwrap();
701 tree.compile().unwrap();
702 });
703 }
704
705 #[bench]
706 fn bench_exec(b: &mut test::Bencher) {
707 let expr = Expr::new("(2 + (3 + 4) + (6 + (6 + 7)) + 5)")
708 .compile()
709 .unwrap();
710 b.iter(|| expr.exec().unwrap())
711 }
712
713 #[bench]
714 fn bench_eval(b: &mut test::Bencher) {
715 b.iter(|| eval("(2 + (3 + 4) + (6 + (6 + 7)) + 5)"));
716 }
717}