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