Skip to main content

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}