v_eval/lib.rs
1//! # v_eval
2//! Evaluate some expresions with context
3//!
4//! All are option by default
5//!
6//! ```rust
7//! use v_eval::{Value, Eval};
8//!
9//!# fn main() -> Result<(), ()> {
10//! let e = Eval::default()
11//! .insert("foo", "true")?
12//! .insert("string", "\"foo\"")?
13//! .insert("opt", "true")?
14//! .insert("bar", "false")?;
15//!
16//! assert_eq!(e.eval("foo != bar").unwrap(), Value::Bool(true));
17//! assert_eq!(
18//! e.eval("true && foo != bar && true").unwrap(),
19//! Value::Bool(true)
20//! );
21//!
22//! assert_eq!(e.eval("1.5.trunc()").unwrap(), Value::Int(1));
23//! assert_eq!(e.eval("50.log10().trunc() == 1").unwrap(), Value::Bool(true));
24//! assert_eq!(e.eval("1.log10()").unwrap(), Value::Float(1.0f64.log10()));
25//!# Ok(())
26//!# }
27//! ```
28//! ## Methods
29//! ### By default
30//! #### Option
31//! - `and`
32//! ```rust
33//!# use v_eval::{Value, Eval};
34//!# fn main() -> Result<(), ()> {
35//!# let e = Eval::default()
36//!# .insert("foo", "true")?
37//!# .insert("string", "\"foo\"")?
38//!# .insert("opt", "true")?
39//!# .insert("bar", "false")?;
40//!#
41//! assert_eq!(e.eval("foo.and(bar)").unwrap(), Value::Bool(false));
42//! assert_eq!(e.eval("not_exist.and(bar)"), None);
43//! assert_eq!(e.eval("1.and(2.0)").unwrap(), Value::Float(2.0));
44//!# Ok(())
45//!# }
46//! ```
47//! - `is_none`
48//! ```rust
49//!# use v_eval::{Value, Eval};
50//!# fn main() -> Result<(), ()> {
51//!# let e = Eval::default()
52//!# .insert("foo", "true")?
53//!# .insert("string", "\"foo\"")?
54//!# .insert("opt", "true")?
55//!# .insert("bar", "false")?;
56//!#
57//! assert_eq!(e.eval("foo.is_none()").unwrap(), Value::Bool(false));
58//! assert_eq!(e.eval("not_exist.is_none()").unwrap(), Value::Bool(true));
59//!# Ok(())
60//!# }
61//! ```
62//! - `is_some`
63//! ```rust
64//!# use v_eval::{Value, Eval};
65//!# fn main() -> Result<(), ()> {
66//!# let e = Eval::default()
67//!# .insert("foo", "true")?
68//!# .insert("string", "\"foo\"")?
69//!# .insert("opt", "true")?
70//!# .insert("bar", "false")?;
71//!#
72//! assert_eq!(e.eval("foo.is_some()").unwrap(), Value::Bool(true));
73//! assert_eq!(e.eval("not_exist.is_some()").unwrap(), Value::Bool(false));
74//!# Ok(())
75//!# }
76//! ```
77//! - `or`
78//! ```rust
79//!# use v_eval::{Value, Eval};
80//!# fn main() -> Result<(), ()> {
81//!# let e = Eval::default()
82//!# .insert("foo", "true")?
83//!# .insert("string", "\"foo\"")?
84//!# .insert("opt", "true")?
85//!# .insert("bar", "false")?;
86//!#
87//! assert_eq!(e.eval("foo.or(bar)").unwrap(), Value::Bool(true));
88//! assert_eq!(e.eval("None.or(bar)").unwrap(), Value::Bool(false));
89//! assert_eq!(e.eval("None.or(not_exist)"), None);
90//!# Ok(())
91//!# }
92//! ```
93//! - `xor`
94//! ```rust
95//!# use v_eval::{Value, Eval};
96//!# fn main() -> Result<(), ()> {
97//!# let e = Eval::default()
98//!# .insert("foo", "true")?
99//!# .insert("string", "\"foo\"")?
100//!# .insert("opt", "true")?
101//!# .insert("bar", "false")?;
102//!#
103//! assert_eq!(e.eval("not_exist.xor(opt)").unwrap(), Value::Bool(true));
104//! assert_eq!(e.eval("not_exist.xor(foo)").unwrap(), Value::Bool(true));
105//! assert_eq!(e.eval("bar.xor(None)").unwrap(), Value::Bool(false));
106//! assert_eq!(e.eval("bar.xor(foo)"), None);
107//!# Ok(())
108//!# }
109//! ```
110//!
111//! #### Dynamic type
112//! - `is_bool`
113//! ```rust
114//!# use v_eval::{Value, Eval};
115//!# fn main() -> Result<(), ()> {
116//!# let e = Eval::default()
117//!# .insert("foo", "true")?
118//!# .insert("string", "\"foo\"")?
119//!# .insert("opt", "true")?
120//!# .insert("bar", "false")?;
121//!#
122//! assert_eq!(e.eval("foo.is_bool()").unwrap(), Value::Bool(true));
123//! assert_eq!(e.eval("string.is_bool()").unwrap(), Value::Bool(false));
124//!# Ok(())
125//!# }
126//! ```
127//! - `is_float`
128//! ```rust
129//!# use v_eval::{Value, Eval};
130//!# fn main() -> Result<(), ()> {
131//!# let e = Eval::default()
132//!# .insert("foo", "true")?
133//!# .insert("string", "\"foo\"")?
134//!# .insert("opt", "true")?
135//!# .insert("bar", "false")?;
136//!#
137//! assert_eq!(e.eval("1.0.is_float()").unwrap(), Value::Bool(true));
138//! assert_eq!(e.eval("bar.is_float()").unwrap(), Value::Bool(false));
139//!# Ok(())
140//!# }
141//! ```
142//! - `is_int`
143//! ```rust
144//!# use v_eval::{Value, Eval};
145//!# fn main() -> Result<(), ()> {
146//!# let e = Eval::default()
147//!# .insert("foo", "true")?
148//!# .insert("string", "\"foo\"")?
149//!# .insert("opt", "true")?
150//!# .insert("bar", "false")?;
151//!#
152//! assert_eq!(e.eval("1.is_int()").unwrap(), Value::Bool(true));
153//! assert_eq!(e.eval("foo.is_int()").unwrap(), Value::Bool(false));
154//!# Ok(())
155//!# }
156//! ```
157//! - `is_range`
158//! ```rust
159//!# use v_eval::{Value, Eval};
160//!# fn main() -> Result<(), ()> {
161//!# let e = Eval::default()
162//!# .insert("foo", "true")?
163//!# .insert("string", "\"foo\"")?
164//!# .insert("opt", "true")?
165//!# .insert("bar", "false")?;
166//!#
167//! assert_eq!(e.eval("(0..10).is_range()").unwrap(), Value::Bool(true));
168//! assert_eq!(e.eval("bar.is_range()").unwrap(), Value::Bool(false));
169//!# Ok(())
170//!# }
171//! ```
172//! - `is_str`
173//! ```rust
174//!# use v_eval::{Value, Eval};
175//!# fn main() -> Result<(), ()> {
176//!# let e = Eval::default()
177//!# .insert("foo", "true")?
178//!# .insert("string", "\"foo\"")?
179//!# .insert("opt", "true")?
180//!# .insert("bar", "false")?;
181//!#
182//! assert_eq!(e.eval("foo.is_str()").unwrap(), Value::Bool(false));
183//! assert_eq!(e.eval("string.is_str()").unwrap(), Value::Bool(true));
184//!# Ok(())
185//!# }
186//! ```
187//! - `is_vec`
188//! ```rust
189//!# use v_eval::{Value, Eval};
190//!# fn main() -> Result<(), ()> {
191//!# let e = Eval::default()
192//!# .insert("foo", "true")?
193//!# .insert("string", "\"foo\"")?
194//!# .insert("opt", "true")?
195//!# .insert("bar", "false")?;
196//!#
197//! assert_eq!(e.eval("[1, 3, 4.0, true, foo].is_vec()").unwrap(), Value::Bool(true));
198//! assert_eq!(e.eval("foo.is_vec()").unwrap(), Value::Bool(false));
199//!# Ok(())
200//!# }
201//! ```
202//! - `is_same`
203//! ```rust
204//!# use v_eval::{Value, Eval};
205//!# fn main() -> Result<(), ()> {
206//!# let e = Eval::default()
207//!# .insert("foo", "true")?
208//!# .insert("string", "\"foo\"")?
209//!# .insert("opt", "true")?
210//!# .insert("bar", "false")?;
211//!#
212//! assert_eq!(e.eval("foo.is_same(bar)").unwrap(), Value::Bool(true));
213//! assert_eq!(e.eval("foo.is_same(false)").unwrap(), Value::Bool(true));
214//! assert_eq!(e.eval("foo.is_same(1)").unwrap(), Value::Bool(false));
215//!# Ok(())
216//!# }
217//! ```
218//!
219//! ### Slice (Str and Vec)
220//! - `len`
221//! ```rust
222//!# use v_eval::{Value, Eval};
223//!# fn main() -> Result<(), ()> {
224//!# let e = Eval::default()
225//!# .insert("foo", "true")?
226//!# .insert("string", "\"foo\"")?
227//!# .insert("opt", "true")?
228//!# .insert("bar", "false")?;
229//!#
230//! assert_eq!(e.eval("string.len()").unwrap(), Value::Int(3));
231//! assert_eq!(e.eval("[1, 2, 3, 4].len()").unwrap(), Value::Int(4));
232//!# Ok(())
233//!# }
234//! ```
235//! - `is_empty`
236//! ```rust
237//!# use v_eval::{Value, Eval};
238//!# fn main() -> Result<(), ()> {
239//!# let e = Eval::default()
240//!# .insert("foo", "true")?
241//!# .insert("string", "\"foo\"")?
242//!# .insert("opt", "true")?
243//!# .insert("bar", "false")?;
244//!#
245//! assert_eq!(e.eval("string.is_empty()").unwrap(), Value::Bool(false));
246//! assert_eq!(e.eval("[].is_empty()").unwrap(), Value::Bool(true));
247//! assert_eq!(e.eval("(0..0).is_empty()").unwrap(), Value::Bool(true));
248//!# Ok(())
249//!# }
250//! ```
251//! - `contains`
252//! ```rust
253//!# use v_eval::{Value, Eval};
254//!# fn main() -> Result<(), ()> {
255//!# let e = Eval::default()
256//!# .insert("foo", "true")?
257//!# .insert("string", "\"foo\"")?
258//!# .insert("opt", "true")?
259//!# .insert("bar", "false")?;
260//!#
261//! assert_eq!(e.eval("string.contains(\"oo\")").unwrap(), Value::Bool(true));
262//! assert_eq!(e.eval("[4, 1.0, true, \"foo\"].contains(1)").unwrap(), Value::Bool(true));
263//! assert_eq!(e.eval("(0..20).contains(0)").unwrap(), Value::Bool(true));
264//!# Ok(())
265//!# }
266//! ```
267//! - `starts_with`
268//! ```rust
269//!# use v_eval::{Value, Eval};
270//!# fn main() -> Result<(), ()> {
271//!# let e = Eval::default()
272//!# .insert("foo", "true")?
273//!# .insert("string", "\"foo\"")?
274//!# .insert("opt", "true")?
275//!# .insert("bar", "false")?;
276//!#
277//! assert_eq!(e.eval("string.starts_with(\"fo\")").unwrap(), Value::Bool(true));
278//! assert_eq!(e.eval("[1, 2, foo].starts_with([1])").unwrap(), Value::Bool(true));
279//! assert_eq!(e.eval("[not_exist, bar, foo].starts_with([None, false])").unwrap(), Value::Bool(true));
280//!# Ok(())
281//!# }
282//! ```
283//! - `ends_with`
284//! ```rust
285//!# use v_eval::{Value, Eval};
286//!# fn main() -> Result<(), ()> {
287//!# let e = Eval::default()
288//!# .insert("foo", "true")?
289//!# .insert("string", "\"foo\"")?
290//!# .insert("opt", "true")?
291//!# .insert("bar", "false")?;
292//!#
293//! assert_eq!(e.eval("string.ends_with(\"oo\")").unwrap(), Value::Bool(true));
294//! assert_eq!(e.eval("[1, 2, foo].ends_with([true])").unwrap(), Value::Bool(true));
295//! assert_eq!(e.eval("[not_exist, bar, foo].ends_with([false, true])").unwrap(), Value::Bool(true));
296//!# Ok(())
297//!# }
298//! ```
299//! ### Str
300//! - `eq_ignore_ascii_case`
301//! ```rust
302//!# use v_eval::{Value, Eval};
303//!# fn main() -> Result<(), ()> {
304//!# let e = Eval::default()
305//!# .insert("foo", "true")?
306//!# .insert("string", "\"foo\"")?
307//!# .insert("opt", "true")?
308//!# .insert("bar", "false")?;
309//!#
310//! assert_eq!(e.eval(r#"string.eq_ignore_ascii_case("FOO")"#).unwrap(), Value::Bool(true));
311//!# Ok(())
312//!# }
313//! ```
314//! - `find`
315//! ```rust
316//!# use v_eval::{Value, Eval};
317//!# fn main() -> Result<(), ()> {
318//!# let e = Eval::default()
319//!# .insert("foo", "true")?
320//!# .insert("string", "\"foo\"")?
321//!# .insert("opt", "true")?
322//!# .insert("bar", "false")?;
323//!#
324//! assert_eq!(e.eval(r#"string.find("o")"#).unwrap(), Value::Int(1));
325//!# Ok(())
326//!# }
327//! ```
328//! - `is_ascii`
329//! ```rust
330//!# use v_eval::{Value, Eval};
331//!# fn main() -> Result<(), ()> {
332//!# let e = Eval::default()
333//!# .insert("foo", "true")?
334//!# .insert("string", "\"foo\"")?
335//!# .insert("opt", "true")?
336//!# .insert("bar", "false")?;
337//!#
338//! assert_eq!(e.eval("string.is_ascii()").unwrap(), Value::Bool(true));
339//! assert_eq!(e.eval(r#""Grüße, Jürgen ❤".is_ascii()"#).unwrap(), Value::Bool(false));
340//!# Ok(())
341//!# }
342//! ```
343//! - `is_match`
344//! ```rust
345//!# use v_eval::{Value, Eval};
346//!# fn main() -> Result<(), ()> {
347//!# let e = Eval::default()
348//!# .insert("foo", "true")?
349//!# .insert("string", "\"foo\"")?
350//!# .insert("opt", "true")?
351//!# .insert("bar", "false")?;
352//!#
353//! assert_eq!(e.eval(r#""2020-04-28".is_match(r"^\d{4}-\d{2}-\d{2}$")"#).unwrap(), Value::Bool(true));
354//! assert_eq!(e.eval(r#"string.is_match(r"^\d{4}-\d{2}-\d{2}$")"#).unwrap(), Value::Bool(false));
355//!# Ok(())
356//!# }
357//! ```
358//! - `to_ascii_lowercase`
359//! ```rust
360//!# use v_eval::{Value, Eval};
361//!# fn main() -> Result<(), ()> {
362//!# let e = Eval::default()
363//!# .insert("foo", "true")?
364//!# .insert("string", "\"foo\"")?
365//!# .insert("opt", "true")?
366//!# .insert("bar", "false")?;
367//!#
368//! assert_eq!(e.eval(r#""FOO".to_ascii_lowercase() == string"#).unwrap(), Value::Bool(true));
369//!# Ok(())
370//!# }
371//! ```
372//! - `to_ascii_uppercase`
373//! ```rust
374//!# use v_eval::{Value, Eval};
375//!# fn main() -> Result<(), ()> {
376//!# let e = Eval::default()
377//!# .insert("foo", "true")?
378//!# .insert("string", "\"foo\"")?
379//!# .insert("opt", "true")?
380//!# .insert("bar", "false")?;
381//!#
382//! assert_eq!(e.eval(r#"string.to_ascii_uppercase() == "FOO""#).unwrap(), Value::Bool(true));
383//!# Ok(())
384//!# }
385//! ```
386//! - `to_lowercase`
387//! ```rust
388//!# use v_eval::{Value, Eval};
389//!# fn main() -> Result<(), ()> {
390//!# let e = Eval::default()
391//!# .insert("foo", "true")?
392//!# .insert("string", "\"foo\"")?
393//!# .insert("opt", "true")?
394//!# .insert("bar", "false")?;
395//!#
396//! assert_eq!(e.eval(r#""FOO".to_lowercase() == string"#).unwrap(), Value::Bool(true));
397//!# Ok(())
398//!# }
399//! ```
400//! - `to_uppercase`
401//! ```rust
402//!# use v_eval::{Value, Eval};
403//!# fn main() -> Result<(), ()> {
404//!# let e = Eval::default()
405//!# .insert("foo", "true")?
406//!# .insert("string", "\"foo\"")?
407//!# .insert("opt", "true")?
408//!# .insert("bar", "false")?;
409//!#
410//! assert_eq!(e.eval(r#"string.to_uppercase() == "FOO""#).unwrap(), Value::Bool(true));
411//!# Ok(())
412//!# }
413//! ```
414//! - `trim`
415//! ```rust
416//!# use v_eval::{Value, Eval};
417//!# fn main() -> Result<(), ()> {
418//!# let e = Eval::default()
419//!# .insert("foo", "true")?
420//!# .insert("string", "\"foo\"")?
421//!# .insert("opt", "true")?
422//!# .insert("bar", "false")?;
423//!#
424//! assert_eq!(e.eval(r#"" foo ".trim() == string"#).unwrap(), Value::Bool(true));
425//!# Ok(())
426//!# }
427//! ```
428//! - `trim_end`
429//! ```rust
430//!# use v_eval::{Value, Eval};
431//!# fn main() -> Result<(), ()> {
432//!# let e = Eval::default()
433//!# .insert("foo", "true")?
434//!# .insert("string", "\"foo\"")?
435//!# .insert("opt", "true")?
436//!# .insert("bar", "false")?;
437//!#
438//! assert_eq!(e.eval(r#""foo ".trim_end() == string"#).unwrap(), Value::Bool(true));
439//!# Ok(())
440//!# }
441//! ```
442//! - `trim_start`
443//! ```rust
444//!# use v_eval::{Value, Eval};
445//!# fn main() -> Result<(), ()> {
446//!# let e = Eval::default()
447//!# .insert("foo", "true")?
448//!# .insert("string", "\"foo\"")?
449//!# .insert("opt", "true")?
450//!# .insert("bar", "false")?;
451//!#
452//! assert_eq!(e.eval(r#"" foo".trim_start() == string"#).unwrap(), Value::Bool(true));
453//!# Ok(())
454//!# }
455//! ```
456//! - `rfind`
457//! ```rust
458//!# use v_eval::{Value, Eval};
459//!# fn main() -> Result<(), ()> {
460//!# let e = Eval::default()
461//!# .insert("foo", "true")?
462//!# .insert("string", "\"foo\"")?
463//!# .insert("opt", "true")?
464//!# .insert("bar", "false")?;
465//!#
466//! assert_eq!(e.eval(r#"string.rfind("o")"#).unwrap(), Value::Int(2));
467//!# Ok(())
468//!# }
469//! ```
470//! ### Vec
471//! - `first`
472//! ```rust
473//!# use v_eval::{Value, Eval};
474//!# fn main() -> Result<(), ()> {
475//!# let e = Eval::default()
476//!# .insert("foo", "true")?
477//!# .insert("string", "\"foo\"")?
478//!# .insert("opt", "true")?
479//!# .insert("bar", "false")?;
480//!#
481//! assert_eq!(e.eval(r#"[1, 2, 3].first()"#).unwrap(), Value::Int(1));
482//!# Ok(())
483//!# }
484//! ```
485//! - `get`
486//! ```rust
487//!# use v_eval::{Value, Eval};
488//!# fn main() -> Result<(), ()> {
489//!# let e = Eval::default()
490//!# .insert("foo", "true")?
491//!# .insert("string", "\"foo\"")?
492//!# .insert("opt", "true")?
493//!# .insert("bar", "false")?;
494//!#
495//! assert_eq!(e.eval(r#"[1, 2].get(1)"#).unwrap(), Value::Int(2));
496//! assert_eq!(e.eval(r#"[1, 2].get(2)"#), None);
497//!# Ok(())
498//!# }
499//! ```
500//! - `last`
501//! ```rust
502//!# use v_eval::{Value, Eval};
503//!# fn main() -> Result<(), ()> {
504//!# let e = Eval::default()
505//!# .insert("foo", "true")?
506//!# .insert("string", "\"foo\"")?
507//!# .insert("opt", "true")?
508//!# .insert("bar", "false")?;
509//!#
510//! assert_eq!(e.eval(r#"[1, 2].last()"#).unwrap(), Value::Int(2));
511//!# Ok(())
512//!# }
513//! ```
514//! ### Number (i64 and f64)
515//! > See [f64 Rust](https://doc.rust-lang.org/std/primitive.f64.html)
516//! - `abs`
517//! - `acos`
518//! - `acosh`
519//! - `asin`
520//! - `asinh`
521//! - `atan2`
522//! - `atan`
523//! - `atanh`
524//! - `cbrt`
525//! - `ceil`
526//! - `cos`
527//! - `cosh`
528//! - `exp2`
529//! - `exp_m1`
530//! - `exp`
531//! - `floor`
532//! - `fract`
533//! - `hypot`
534//! - `ln_1p`
535//! - `ln`
536//! - `log10`
537//! - `log2`
538//! - `log`
539//! - `max`
540//! - `min`
541//! - `powf`
542//! - `powi`
543//! - `recip`
544//! - `round`
545//! - `signum`
546//! - `sin`
547//! - `sinh`
548//! - `sqrt`
549//! - `tan`
550//! - `tanh`
551//! - `to_degrees`
552//! - `to_radians`
553//! - `trunc`
554//! ```rust
555//!# use v_eval::{Value, Eval};
556//!# fn main() -> Result<(), ()> {
557//!# let e = Eval::default()
558//!# .insert("foo", "true")?
559//!# .insert("string", "\"foo\"")?
560//!# .insert("opt", "true")?
561//!# .insert("bar", "false")?;
562//!#
563//! assert_eq!(e.eval("1.5.trunc()").unwrap(), Value::Int(1));
564//!# Ok(())
565//!# }
566//! ```
567//!
568//!
569use std::collections::BTreeMap;
570
571use syn::parse_str;
572
573mod method;
574mod operator;
575mod reflect;
576mod value;
577
578pub use self::{reflect::eval, value::Value};
579
580/// Evaluator with context
581pub struct Eval(BTreeMap<String, syn::Expr>);
582
583impl Default for Eval {
584 fn default() -> Self {
585 Self(BTreeMap::new())
586 }
587}
588
589impl Eval {
590 pub fn new(c: BTreeMap<String, syn::Expr>) -> Self {
591 Self(c)
592 }
593
594 /// Parse and insert in context name - syn::Expr
595 pub fn insert(mut self, k: &str, v: &str) -> Result<Self, ()> {
596 let e = parse_str::<syn::Expr>(v).map_err(|_| ())?;
597 self.0.insert(k.to_owned(), e);
598
599 Ok(self)
600 }
601
602 /// Remove key in context
603 pub fn remove(mut self, k: &str) -> Self {
604 self.0.remove(k);
605
606 self
607 }
608
609 /// Evaluate expression with current context
610 pub fn eval(&self, src: &str) -> Option<Value> {
611 parse_str::<syn::Expr>(src)
612 .ok()
613 .and_then(|src| eval(&self.0, &src))
614 }
615}
616
617#[cfg(test)]
618mod test {
619 use super::*;
620
621 #[allow(clippy::cognitive_complexity)]
622 #[test]
623 fn test() -> Result<(), ()> {
624 let e = Eval::default()
625 .insert("foo", "true")?
626 .insert("fon", "1")?
627 .insert("s", r#""foo""#)?
628 .insert("arr", "[1, 2]")?
629 .insert("bar", "false")?;
630
631 assert_eq!(e.eval("foo != bar").unwrap(), Value::Bool(true));
632 assert_eq!(
633 e.eval("true && foo != bar && true").unwrap(),
634 Value::Bool(true)
635 );
636 assert_eq!(e.eval("1 == 1 != bar").unwrap(), Value::Bool(true));
637 assert_eq!(e.eval("1 == 1 + 1 == bar").unwrap(), Value::Bool(true));
638 assert_eq!(e.eval("0..1").unwrap(), Value::Range(0..1));
639 assert_eq!(e.eval("(0..1) == (0..1)").unwrap(), Value::Bool(true));
640 assert_eq!(e.eval("0..2 * (1 + 1)").unwrap(), Value::Range(0..4));
641 assert_eq!(
642 e.eval("fon + 1..fon + 2 * (1 + 1)").unwrap(),
643 Value::Range(2..5)
644 );
645 assert_eq!(
646 e.eval("fon + 1..fon + 2 * (1 + 1)").unwrap(),
647 Value::Range(2..5)
648 );
649 assert_eq!(e.eval(r#""foo" == s"#).unwrap(), Value::Bool(true));
650 assert_eq!(e.eval(r#""bar" != s"#).unwrap(), Value::Bool(true));
651 assert_eq!(e.eval("s").unwrap(), Value::Str("foo".into()));
652 assert_eq!(
653 e.eval("[foo, true]").unwrap(),
654 Value::Vec(vec![Value::Bool(true), Value::Bool(true)])
655 );
656 assert_eq!(
657 e.eval("[foo, 1]").unwrap(),
658 Value::Vec(vec![Value::Bool(true), Value::Int(1)])
659 );
660 assert_eq!(
661 e.eval("[foo, [1, 2]]").unwrap(),
662 Value::Vec(vec![
663 Value::Bool(true),
664 Value::Vec(vec![Value::Int(1), Value::Int(2)])
665 ])
666 );
667 assert_eq!(
668 e.eval(r#""foo" * 2 * 2"#).unwrap(),
669 Value::Str("foofoofoofoo".into())
670 );
671 assert_eq!(
672 e.eval(r#""foo" * (2 * 2 - 1 + 1)"#).unwrap(),
673 Value::Str("foofoofoofoo".into())
674 );
675 assert_eq!(
676 e.eval(r#"("foo" + "bar") * 2"#).unwrap(),
677 Value::Str("foobarfoobar".into())
678 );
679 assert_eq!(
680 e.eval(r#"("bar" + s * 2) * 2"#).unwrap(),
681 Value::Str("barfoofoobarfoofoo".into())
682 );
683
684 assert_eq!(e.eval("[foo, 1][1]").unwrap(), Value::Int(1));
685 assert_eq!(e.eval("&[0, 1][1]").unwrap(), Value::Int(1));
686
687 assert_eq!(e.eval("arr[1]").unwrap(), Value::Int(2));
688
689 assert_eq!(e.eval("arr[1] + 1").unwrap(), Value::Int(3));
690
691 assert_eq!(e.eval("2 * arr[1] + 1").unwrap(), Value::Int(5));
692
693 assert!(e.eval("arr[2]").is_none());
694 assert!(e.eval("[foo, 1][2]").is_none());
695
696 assert_eq!(e.eval(r#""bar"[0..1]"#).unwrap(), Value::Str("b".into()));
697
698 assert_eq!(
699 e.eval(r#"("bar" * 2)[3..4]"#).unwrap(),
700 Value::Str("b".into())
701 );
702
703 assert_eq!(
704 e.eval("[foo, [1, 2]]").unwrap().to_string(),
705 "[true,[1,2,],]"
706 );
707
708 assert_eq!(e.eval(r#""foo""#).unwrap().to_string(), r#""foo""#,);
709 assert_eq!(e.eval("0..1").unwrap().to_string(), "0..1");
710
711 assert_eq!(e.eval("1.log10()").unwrap(), Value::Float(1.0f64.log10()));
712
713 assert_eq!(
714 e.eval("1.log10() + 2.0").unwrap(),
715 Value::Float(1.0f64.log10() + 2.0)
716 );
717
718 assert_eq!(e.eval("&[true, not_exist]"), None);
719 assert_eq!(e.eval("&[true, None]"), None);
720 assert_eq!(e.eval("&[\"foo\", None, None]"), None);
721 assert_eq!(e.eval("not_exist"), None);
722 assert_eq!(e.eval(r#"&[ "foo", self.s]"#), None);
723
724 assert_eq!(e.eval("s.contains(\"oo\")").unwrap(), Value::Bool(true));
725 assert_eq!(e.eval("arr.starts_with([1])").unwrap(), Value::Bool(true));
726 assert_eq!(
727 e.eval("[None].starts_with([None])").unwrap(),
728 Value::Bool(true)
729 );
730 Ok(())
731 }
732
733 #[test]
734 fn test_opt() {
735 let e = Eval::default();
736 assert_eq!(e.eval("1.log10()").unwrap(), Value::Float(1.0f64.log10()));
737 assert_eq!(
738 e.eval("None.or(1.log10())"),
739 Some(Value::Float(1.0f64.log10()))
740 );
741 }
742}