anathema_value_resolver/
value.rs

1use std::borrow::Cow;
2use std::ops::{Deref, DerefMut};
3
4use anathema_state::{Color, Hex, PendingValue, SubTo, Subscriber, Type};
5use anathema_store::smallmap::SmallMap;
6use anathema_templates::Expression;
7
8use crate::attributes::ValueKey;
9use crate::expression::{ValueExpr, ValueResolutionContext, resolve_value};
10use crate::immediate::Resolver;
11use crate::{AttributeStorage, ResolverCtx};
12
13pub type Values<'bp> = SmallMap<ValueKey<'bp>, Value<'bp>>;
14
15pub fn resolve<'bp>(expr: &'bp Expression, ctx: &ResolverCtx<'_, 'bp>, sub: impl Into<Subscriber>) -> Value<'bp> {
16    let resolver = Resolver::new(ctx);
17    let value_expr = resolver.resolve(expr);
18    Value::new(value_expr, sub.into(), ctx.attribute_storage)
19}
20
21pub fn resolve_collection<'bp>(
22    expr: &'bp Expression,
23    ctx: &ResolverCtx<'_, 'bp>,
24    sub: impl Into<Subscriber>,
25) -> Collection<'bp> {
26    let value = resolve(expr, ctx, sub);
27    Collection(value)
28}
29
30#[derive(Debug)]
31pub struct Collection<'bp>(pub(crate) Value<'bp>);
32
33impl<'bp> Collection<'bp> {
34    pub fn reload(&mut self, attributes: &AttributeStorage<'bp>) {
35        self.0.reload(attributes)
36    }
37
38    pub fn len(&self) -> usize {
39        match &self.0.kind {
40            ValueKind::List(vec) => vec.len(),
41            ValueKind::DynList(value) => {
42                let Some(state) = value.as_state() else { return 0 };
43                let Some(list) = state.as_any_list() else { return 0 };
44                list.len()
45            }
46            ValueKind::Int(_)
47            | ValueKind::Float(_)
48            | ValueKind::Bool(_)
49            | ValueKind::Char(_)
50            | ValueKind::Hex(_)
51            | ValueKind::Color(_)
52            | ValueKind::Str(_)
53            | ValueKind::DynMap(_)
54            | ValueKind::Map
55            | ValueKind::Composite(_)
56            | ValueKind::Attributes
57            | ValueKind::Null => 0,
58        }
59    }
60}
61
62/// This is the final value for a node attribute / value.
63/// This should be evaluated fully for the `ValueKind`
64#[derive(Debug)]
65pub struct Value<'bp> {
66    pub(crate) expr: ValueExpr<'bp>,
67    pub(crate) sub: Subscriber,
68    pub(crate) kind: ValueKind<'bp>,
69    pub(crate) sub_to: SubTo,
70}
71
72impl<'bp> Value<'bp> {
73    pub fn new(expr: ValueExpr<'bp>, sub: Subscriber, attribute_storage: &AttributeStorage<'bp>) -> Self {
74        let mut sub_to = SubTo::Zero;
75        let mut ctx = ValueResolutionContext::new(attribute_storage, sub, &mut sub_to);
76        let kind = resolve_value(&expr, &mut ctx);
77
78        // NOTE
79        // This is a special edge case where the map or state is used
80        // as a final value `Option<ValueKind>`.
81        //
82        // This would only hold value in an if-statement:
83        // ```
84        // if state.opt_map
85        //     text "show this if there is a map"
86        // ```
87        match kind {
88            ValueKind::DynMap(pending) | ValueKind::Composite(pending) => {
89                pending.subscribe(ctx.sub);
90                ctx.sub_to.push(pending.sub_key());
91            }
92            _ => {}
93        }
94        Self {
95            expr,
96            sub,
97            kind,
98            sub_to,
99        }
100    }
101
102    pub fn truthiness(&self) -> bool {
103        // None         = false
104        // 0            = false
105        // Some("")     = false
106        // Some(0)      = false
107        // []           = false
108        // {}           = false
109        // Some(bool)   = bool
110        // _            = true
111
112        self.kind.truthiness()
113    }
114
115    #[doc(hidden)]
116    pub fn kind(&self) -> &ValueKind<'_> {
117        &self.kind
118    }
119
120    pub fn reload(&mut self, attribute_storage: &AttributeStorage<'bp>) {
121        self.sub_to.unsubscribe(self.sub);
122        let mut ctx = ValueResolutionContext::new(attribute_storage, self.sub, &mut self.sub_to);
123        self.kind = resolve_value(&self.expr, &mut ctx);
124    }
125
126    pub fn try_as<T>(&self) -> Option<T>
127    where
128        T: for<'a> TryFrom<&'a ValueKind<'a>>,
129    {
130        (&self.kind).try_into().ok()
131    }
132
133    pub fn strings<F>(&self, mut f: F)
134    where
135        F: FnMut(&str) -> bool,
136    {
137        self.kind.strings(&mut f);
138    }
139}
140
141impl Drop for Value<'_> {
142    fn drop(&mut self) {
143        self.sub_to.unsubscribe(self.sub);
144    }
145}
146
147impl<'a> Deref for Value<'a> {
148    type Target = ValueKind<'a>;
149
150    fn deref(&self) -> &Self::Target {
151        &self.kind
152    }
153}
154
155impl<'a> DerefMut for Value<'a> {
156    fn deref_mut(&mut self) -> &mut Self::Target {
157        &mut self.kind
158    }
159}
160
161/// This value can never be part of an evaluation chain, only the return value.
162/// It should only ever be the final type that is held by a `Value`, at
163/// the end of an evaluation
164#[derive(Debug, PartialEq, PartialOrd, Clone)]
165pub enum ValueKind<'bp> {
166    Int(i64),
167    Float(f64),
168    Bool(bool),
169    Char(char),
170    Hex(Hex),
171    Color(Color),
172    Str(Cow<'bp, str>),
173    Null,
174
175    // NOTE
176    // The map is the final value, and is never used as part
177    // of an index, for that reason the map doesn't hold any values.
178    Map,
179    // NOTE
180    // The attributes is the final value, and is never used as part
181    // of an index, for that reason the attributes doesn't hold any values.
182    Attributes,
183    List(Box<[ValueKind<'bp>]>),
184    DynList(PendingValue),
185    DynMap(PendingValue),
186    Composite(PendingValue),
187}
188
189impl ValueKind<'_> {
190    pub fn to_int(&self) -> Option<i64> {
191        match self.as_int() {
192            Some(val) => Some(val),
193            None => Some(self.as_float()? as i64),
194        }
195    }
196
197    pub fn as_int(&self) -> Option<i64> {
198        let ValueKind::Int(i) = self else { return None };
199        Some(*i)
200    }
201
202    pub fn as_float(&self) -> Option<f64> {
203        let ValueKind::Float(i) = self else { return None };
204        Some(*i)
205    }
206
207    pub fn as_bool(&self) -> Option<bool> {
208        let ValueKind::Bool(b) = self else { return None };
209        Some(*b)
210    }
211
212    pub fn as_char(&self) -> Option<char> {
213        let ValueKind::Char(i) = self else { return None };
214        Some(*i)
215    }
216
217    pub fn as_hex(&self) -> Option<Hex> {
218        let ValueKind::Hex(i) = self else { return None };
219        Some(*i)
220    }
221
222    pub fn as_color(&self) -> Option<Color> {
223        let ValueKind::Color(i) = self else { return None };
224        Some(*i)
225    }
226
227    pub fn as_str(&self) -> Option<&str> {
228        let ValueKind::Str(i) = &self else { return None };
229        Some(i)
230    }
231
232    pub fn strings<F>(&self, mut f: F)
233    where
234        F: FnMut(&str) -> bool,
235    {
236        self.internal_strings(&mut f);
237    }
238
239    fn internal_strings<F>(&self, f: &mut F) -> bool
240    where
241        F: FnMut(&str) -> bool,
242    {
243        match self {
244            ValueKind::Int(n) => f(&n.to_string()),
245            ValueKind::Float(n) => f(&n.to_string()),
246            ValueKind::Bool(b) => f(&b.to_string()),
247            ValueKind::Char(c) => f(&c.to_string()),
248            ValueKind::Hex(x) => f(&x.to_string()),
249            ValueKind::Color(col) => f(&col.to_string()),
250            ValueKind::Str(cow) => f(cow.as_ref()),
251            ValueKind::List(vec) => vec.iter().take_while(|val| val.internal_strings(f)).count() == vec.len(),
252            ValueKind::DynList(value) => dyn_string(*value, f),
253            ValueKind::DynMap(_) => f("<dyn map>"),
254            ValueKind::Map => f("<map>"),
255            ValueKind::Composite(_) => f("<composite>"),
256            ValueKind::Attributes => f("<attributes>"),
257            ValueKind::Null => true,
258        }
259    }
260
261    pub(crate) fn truthiness(&self) -> bool {
262        match self {
263            ValueKind::Int(0) | ValueKind::Float(0.0) | ValueKind::Bool(false) => false,
264            ValueKind::Str(cow) if cow.is_empty() => false,
265            ValueKind::Null => false,
266            ValueKind::List(list) if list.is_empty() => false,
267            ValueKind::DynList(list) => {
268                let Some(state) = list.as_state() else { return false };
269                let Some(state) = state.as_any_list() else { return false };
270                !state.is_empty()
271            }
272            ValueKind::DynMap(map) => {
273                let Some(state) = map.as_state() else { return false };
274                let Some(state) = state.as_any_map() else { return false };
275                !state.is_empty()
276            }
277            // ValueKind::Map => ??,
278            _ => true,
279        }
280    }
281}
282
283fn dyn_string<F>(value: PendingValue, f: &mut F) -> bool
284where
285    F: FnMut(&str) -> bool,
286{
287    let Some(state) = value.as_state() else { return true };
288    let Some(list) = state.as_any_list() else { return true };
289    for i in 0..list.len() {
290        let value = list.lookup(i).expect("the value exists");
291        let Some(state) = value.as_state() else { continue };
292        let should_continue = match value.type_info() {
293            Type::Int => f(&state.as_int().expect("type info dictates this").to_string()),
294            Type::Float => f(&state.as_float().expect("type info dictates this").to_string()),
295            Type::Char => f(&state.as_char().expect("type info dictates this").to_string()),
296            Type::String => f(state.as_str().expect("type info dictates this")),
297            Type::Bool => f(&state.as_bool().expect("type info dictates this").to_string()),
298            Type::Hex => f(&state.as_hex().expect("type info dictates this").to_string()),
299            Type::Map => f("<map>"),
300            Type::List => dyn_string(value, f),
301            Type::Composite => f(&state.as_hex().expect("type info dictates this").to_string()),
302            Type::Unit => f(""),
303            Type::Color => f(&state.as_color().expect("type info dictates this").to_string()),
304            Type::Maybe => panic!(),
305        };
306
307        if !should_continue {
308            return false;
309        }
310    }
311    true
312}
313
314// -----------------------------------------------------------------------------
315//   - From impls -
316// -----------------------------------------------------------------------------
317macro_rules! from_int {
318    ($int:ty) => {
319        impl From<$int> for ValueKind<'_> {
320            fn from(value: $int) -> Self {
321                ValueKind::Int(value as i64)
322            }
323        }
324    };
325}
326
327from_int!(i64);
328from_int!(i32);
329from_int!(i16);
330from_int!(i8);
331from_int!(u64);
332from_int!(u32);
333from_int!(u16);
334from_int!(u8);
335
336impl From<f64> for ValueKind<'_> {
337    fn from(value: f64) -> Self {
338        ValueKind::Float(value)
339    }
340}
341
342impl From<f32> for ValueKind<'_> {
343    fn from(value: f32) -> Self {
344        ValueKind::Float(value as f64)
345    }
346}
347
348impl From<bool> for ValueKind<'_> {
349    fn from(value: bool) -> Self {
350        ValueKind::Bool(value)
351    }
352}
353
354impl From<char> for ValueKind<'_> {
355    fn from(value: char) -> Self {
356        ValueKind::Char(value)
357    }
358}
359
360impl From<Hex> for ValueKind<'_> {
361    fn from(value: Hex) -> Self {
362        ValueKind::Hex(value)
363    }
364}
365
366impl From<Color> for ValueKind<'_> {
367    fn from(value: Color) -> Self {
368        ValueKind::Color(value)
369    }
370}
371
372impl<'bp, T> From<Vec<T>> for ValueKind<'bp>
373where
374    T: Into<ValueKind<'bp>>,
375{
376    fn from(value: Vec<T>) -> Self {
377        let list = value.into_iter().map(T::into).collect();
378        ValueKind::List(list)
379    }
380}
381
382impl<'a> From<&'a str> for ValueKind<'a> {
383    fn from(value: &'a str) -> Self {
384        ValueKind::Str(Cow::Borrowed(value))
385    }
386}
387
388impl From<String> for ValueKind<'_> {
389    fn from(value: String) -> Self {
390        ValueKind::Str(value.into())
391    }
392}
393
394// -----------------------------------------------------------------------------
395//   - Try From -
396// -----------------------------------------------------------------------------
397macro_rules! try_from_valuekind {
398    ($t:ty, $kind:ident) => {
399        impl TryFrom<&ValueKind<'_>> for $t {
400            type Error = ();
401
402            fn try_from(value: &ValueKind<'_>) -> Result<Self, Self::Error> {
403                match value {
404                    ValueKind::$kind(val) => Ok(*val),
405                    _ => Err(()),
406                }
407            }
408        }
409    };
410}
411
412macro_rules! try_from_valuekind_int {
413    ($t:ty, $kind:ident) => {
414        impl TryFrom<&ValueKind<'_>> for $t {
415            type Error = ();
416
417            fn try_from(value: &ValueKind<'_>) -> Result<Self, Self::Error> {
418                match value {
419                    ValueKind::$kind(val) => Ok(*val as $t),
420                    _ => Err(()),
421                }
422            }
423        }
424    };
425}
426
427try_from_valuekind!(i64, Int);
428try_from_valuekind!(f64, Float);
429try_from_valuekind!(bool, Bool);
430try_from_valuekind!(Hex, Hex);
431try_from_valuekind!(Color, Color);
432
433try_from_valuekind_int!(usize, Int);
434try_from_valuekind_int!(isize, Int);
435try_from_valuekind_int!(i32, Int);
436try_from_valuekind_int!(f32, Float);
437try_from_valuekind_int!(i16, Int);
438try_from_valuekind_int!(i8, Int);
439try_from_valuekind_int!(u32, Int);
440try_from_valuekind_int!(u64, Int);
441try_from_valuekind_int!(u16, Int);
442try_from_valuekind_int!(u8, Int);
443
444impl<'bp> TryFrom<&ValueKind<'bp>> for char {
445    type Error = ();
446
447    fn try_from(value: &ValueKind<'bp>) -> Result<Self, Self::Error> {
448        match value {
449            ValueKind::Char(c) => Ok(*c),
450            ValueKind::Str(s) => s.chars().next().ok_or(()),
451            _ => Err(()),
452        }
453    }
454}
455
456impl<'a, 'bp> TryFrom<&'a ValueKind<'bp>> for &'a str {
457    type Error = ();
458
459    fn try_from(value: &'a ValueKind<'bp>) -> Result<Self, Self::Error> {
460        match value {
461            ValueKind::Str(Cow::Borrowed(val)) => Ok(val),
462            ValueKind::Str(Cow::Owned(val)) => Ok(val.as_str()),
463            _ => Err(()),
464        }
465    }
466}
467
468#[cfg(test)]
469pub(crate) mod test {
470    use anathema_state::{Hex, Map, Maybe, States};
471    use anathema_templates::Variables;
472    use anathema_templates::expressions::{
473        add, and, boolean, chr, div, either, eq, float, greater_than, greater_than_equal, hex, ident, index, less_than,
474        less_than_equal, list, map, modulo, mul, neg, not, num, or, strlit, sub, text_segments,
475    };
476
477    use crate::ValueKind;
478    use crate::testing::setup;
479
480    #[test]
481    fn attribute_lookup() {
482        let expr = index(ident("attributes"), strlit("a"));
483        let int = num(123);
484
485        let mut states = States::new();
486        setup(&mut states, Default::default(), |test| {
487            test.set_attribute("a", &int);
488            let value = test.eval(&expr);
489            assert_eq!(123, value.as_int().unwrap());
490        });
491    }
492
493    #[test]
494    fn expr_list_dyn_index() {
495        let expr = index(list([1, 2, 3]), add(ident("index"), num(1)));
496
497        let mut states = States::new();
498        let mut globals = Variables::new();
499        globals.declare("index", 0);
500
501        setup(&mut states, globals, |test| {
502            let value = test.eval(&expr);
503            assert_eq!(2, value.as_int().unwrap());
504        });
505    }
506
507    #[test]
508    fn expr_list() {
509        let expr = index(list([1, 2, 3]), num(0));
510
511        let mut states = States::new();
512        setup(&mut states, Default::default(), |test| {
513            let value = test.eval(&expr);
514            assert_eq!(1, value.as_int().unwrap());
515        });
516    }
517
518    #[test]
519    fn either_index() {
520        // state[0] ? attributes[0]
521        let expr = either(
522            index(index(ident("state"), strlit("list")), num(0)),
523            index(index(ident("attributes"), strlit("list")), num(0)),
524        );
525
526        let list = list([strlit("from attribute")]);
527
528        let mut states = States::new();
529        setup(&mut states, Default::default(), |test| {
530            // Set list for attributes
531            test.set_attribute("list", &list);
532
533            // Evaluate the value.
534            // The state is not yet set so it will fall back to attributes
535            let mut value = test.eval(&expr);
536            assert_eq!("from attribute", value.as_str().unwrap());
537
538            // Set the state value
539            test.with_state(|state| state.list.push("from state"));
540
541            // The value now comes from the state
542            value.reload(&test.attributes);
543            assert_eq!("from state", value.as_str().unwrap());
544        });
545    }
546
547    #[test]
548    fn either_then_index() {
549        // (state ? attributes)[0]
550
551        let list = list([num(123)]);
552        let mut states = States::new();
553        setup(&mut states, Default::default(), |test| {
554            let expr = index(
555                either(
556                    index(ident("attributes"), strlit("list")),
557                    index(ident("state"), strlit("list")),
558                ),
559                num(0),
560            );
561
562            test.with_state(|state| state.list.push("a string"));
563            let value = test.eval(&expr);
564            assert_eq!("a string", value.as_str().unwrap());
565
566            test.set_attribute("list", &list);
567            let value = test.eval(&expr);
568            assert_eq!(123, value.as_int().unwrap());
569        });
570    }
571
572    #[test]
573    fn either_or() {
574        let mut states = States::new();
575        setup(&mut states, Default::default(), |test| {
576            test.with_state(|state| state.num.set(1));
577            test.with_state(|state| state.num_2.set(2));
578
579            // There is no c, so use b
580            let expr = either(
581                index(ident("state"), strlit("num_3")),
582                index(ident("state"), strlit("num_2")),
583            );
584            let value = test.eval(&expr);
585            assert_eq!(2, value.as_int().unwrap());
586
587            // There is a, so don't use b
588            let expr = either(
589                index(ident("state"), strlit("num")),
590                index(ident("state"), strlit("num_2")),
591            );
592            let value = test.eval(&expr);
593            assert_eq!(1, value.as_int().unwrap());
594        });
595    }
596
597    #[test]
598    fn mods() {
599        let mut states = States::new();
600        setup(&mut states, Default::default(), |test| {
601            test.with_state(|state| state.num.set(5));
602            let lookup = index(ident("state"), strlit("num"));
603            let expr = modulo(lookup, num(3));
604            let value = test.eval(&expr);
605            assert_eq!(2, value.as_int().unwrap());
606        });
607    }
608
609    #[test]
610    fn division() {
611        let mut states = States::new();
612        setup(&mut states, Default::default(), |test| {
613            test.with_state(|state| state.num.set(6));
614            let lookup = index(ident("state"), strlit("num"));
615            let expr = div(lookup, num(2));
616            let value = test.eval(&expr);
617            assert_eq!(3, value.as_int().unwrap());
618        });
619    }
620
621    #[test]
622    fn multiplication() {
623        let mut states = States::new();
624        setup(&mut states, Default::default(), |test| {
625            test.with_state(|state| state.num.set(2));
626            let lookup = index(ident("state"), strlit("num"));
627            let expr = mul(lookup, num(2));
628            let value = test.eval(&expr);
629            assert_eq!(4, value.as_int().unwrap());
630        });
631    }
632
633    #[test]
634    fn subtraction() {
635        let mut states = States::new();
636        setup(&mut states, Default::default(), |test| {
637            test.with_state(|state| state.num.set(1));
638            let lookup = index(ident("state"), strlit("num"));
639            let expr = sub(lookup, num(2));
640            let value = test.eval(&expr);
641            assert_eq!(-1, value.as_int().unwrap());
642        });
643    }
644
645    #[test]
646    fn addition() {
647        let mut states = States::new();
648        setup(&mut states, Default::default(), |test| {
649            test.with_state(|state| state.num.set(1));
650            let lookup = index(ident("state"), strlit("num"));
651            let expr = add(lookup, num(2));
652            let value = test.eval(&expr);
653            assert_eq!(3, value.as_int().unwrap());
654        });
655    }
656
657    #[test]
658    fn test_or() {
659        let mut states = States::new();
660        setup(&mut states, Default::default(), |test| {
661            let is_true = or(boolean(false), boolean(true));
662            let is_true = test.eval(&is_true);
663            assert!(is_true.as_bool().unwrap());
664        });
665    }
666
667    #[test]
668    fn test_and() {
669        let mut states = States::new();
670        setup(&mut states, Default::default(), |test| {
671            let is_true = and(boolean(true), boolean(true));
672            let is_true = test.eval(&is_true);
673            assert!(is_true.as_bool().unwrap());
674        });
675    }
676
677    #[test]
678    fn lte() {
679        let mut states = States::new();
680        setup(&mut states, Default::default(), |test| {
681            let is_true = less_than_equal(num(1), num(2));
682            let is_also_true = less_than_equal(num(1), num(1));
683            let is_true = test.eval(&is_true);
684            let is_also_true = test.eval(&is_also_true);
685            assert!(is_true.as_bool().unwrap());
686            assert!(is_also_true.as_bool().unwrap());
687        });
688    }
689
690    #[test]
691    fn lt() {
692        let mut states = States::new();
693        setup(&mut states, Default::default(), |test| {
694            let is_true = less_than(num(1), num(2));
695            let is_false = less_than(num(1), num(1));
696            let is_true = test.eval(&is_true);
697            let is_false = test.eval(&is_false);
698            assert!(is_true.as_bool().unwrap());
699            assert!(!is_false.as_bool().unwrap());
700        });
701    }
702
703    #[test]
704    fn gte() {
705        let mut states = States::new();
706        setup(&mut states, Default::default(), |test| {
707            let is_true = greater_than_equal(num(2), num(1));
708            let is_also_true = greater_than_equal(num(2), num(2));
709            let is_true = test.eval(&is_true);
710            let is_also_true = test.eval(&is_also_true);
711            assert!(is_true.as_bool().unwrap());
712            assert!(is_also_true.as_bool().unwrap());
713        });
714    }
715
716    #[test]
717    fn gt() {
718        let mut states = States::new();
719        setup(&mut states, Default::default(), |test| {
720            let is_true = greater_than(num(2), num(1));
721            let is_false = greater_than(num(2), num(2));
722            let is_true = test.eval(&is_true);
723            let is_false = test.eval(&is_false);
724            assert!(is_true.as_bool().unwrap());
725            assert!(!is_false.as_bool().unwrap());
726        });
727    }
728
729    #[test]
730    fn equality() {
731        let mut states = States::new();
732        setup(&mut states, Default::default(), |test| {
733            let is_true = eq(num(1), num(1));
734            let is_true = test.eval(&is_true);
735            let is_false = &not(eq(num(1), num(1)));
736            let is_false = test.eval(is_false);
737            assert!(is_true.as_bool().unwrap());
738            assert!(!is_false.as_bool().unwrap());
739        });
740    }
741
742    #[test]
743    fn neg_float() {
744        let mut states = States::new();
745        setup(&mut states, Default::default(), |test| {
746            let expr = neg(float(123.1));
747            let value = test.eval(&expr);
748            assert_eq!(-123.1, value.as_float().unwrap());
749        });
750    }
751
752    #[test]
753    fn neg_num() {
754        let mut states = States::new();
755        setup(&mut states, Default::default(), |test| {
756            let expr = neg(num(123));
757            let value = test.eval(&expr);
758            assert_eq!(-123, value.as_int().unwrap());
759        });
760    }
761
762    #[test]
763    fn not_true() {
764        let mut states = States::new();
765        setup(&mut states, Default::default(), |test| {
766            let expr = not(boolean(false));
767            let value = test.eval(&expr);
768            assert!(value.as_bool().unwrap());
769        });
770    }
771
772    #[test]
773    fn map_resolve() {
774        let mut states = States::new();
775        setup(&mut states, Default::default(), |test| {
776            let expr = map([("a", 123), ("b", 456)]);
777            let value = test.eval(&expr);
778            assert_eq!(ValueKind::Map, value.kind);
779        });
780    }
781
782    #[test]
783    fn optional_map_resolve() {
784        let mut states = States::new();
785        setup(&mut states, Default::default(), |test| {
786            // At first there is no map...
787            let expr = index(ident("state"), strlit("opt_map"));
788            let mut value = test.eval(&expr);
789            assert!(matches!(value.kind, ValueKind::Null));
790
791            // ... then we insert a map
792            test.with_state(|state| {
793                let map = Map::empty();
794                state.opt_map.set(Maybe::some(map));
795            });
796
797            value.reload(&test.attributes);
798            assert!(matches!(value.kind, ValueKind::DynMap(_)));
799        });
800    }
801
802    #[test]
803    fn str_resolve() {
804        // state[empty|full]
805        let mut states = States::new();
806        let mut globals = Variables::new();
807        globals.declare("full", "string");
808        setup(&mut states, globals, |test| {
809            let expr = index(ident("state"), either(ident("empty"), ident("full")));
810            test.with_state(|state| state.string.set("a string"));
811            let value = test.eval(&expr);
812            assert_eq!("a string", value.as_str().unwrap());
813        });
814    }
815
816    #[test]
817    fn state_string() {
818        let mut states = States::new();
819        setup(&mut states, Default::default(), |test| {
820            test.with_state(|state| state.string.set("a string"));
821            let expr = index(ident("state"), strlit("string"));
822            let value = test.eval(&expr);
823            assert_eq!("a string", value.as_str().unwrap());
824        });
825    }
826
827    #[test]
828    fn state_float() {
829        let mut states = States::new();
830        setup(&mut states, Default::default(), |test| {
831            let expr = index(ident("state"), strlit("float"));
832            test.with_state(|state| state.float.set(1.2));
833            let value = test.eval(&expr);
834            assert_eq!(1.2, value.as_float().unwrap());
835        });
836    }
837
838    #[test]
839    fn test_either() {
840        let mut states = States::new();
841        let mut globals = Variables::new();
842        globals.declare("missing", 111);
843        setup(&mut states, globals, |test| {
844            let expr = either(ident("missings"), num(2));
845            let value = test.eval(&expr);
846            assert_eq!(2, value.as_int().unwrap());
847        });
848    }
849
850    #[test]
851    fn test_hex() {
852        let mut states = States::new();
853        setup(&mut states, Default::default(), |test| {
854            let expr = hex((1, 2, 3));
855            let value = test.eval(&expr);
856            assert_eq!(Hex::from((1, 2, 3)), value.as_hex().unwrap());
857        });
858    }
859
860    #[test]
861    fn test_char() {
862        let mut states = States::new();
863        setup(&mut states, Default::default(), |test| {
864            let expr = chr('x');
865            let value = test.eval(&expr);
866            assert_eq!('x', value.as_char().unwrap());
867        });
868    }
869
870    #[test]
871    fn test_float() {
872        let mut states = States::new();
873        setup(&mut states, Default::default(), |test| {
874            let expr = float(123.123);
875            let value = test.eval(&expr);
876            assert_eq!(123.123, value.as_float().unwrap());
877        });
878    }
879
880    #[test]
881    fn test_int() {
882        let mut states = States::new();
883        setup(&mut states, Default::default(), |test| {
884            let expr = num(123);
885            let value = test.eval(&expr);
886            assert_eq!(123, value.as_int().unwrap());
887        });
888    }
889
890    #[test]
891    fn test_bool() {
892        let mut states = States::new();
893        setup(&mut states, Default::default(), |test| {
894            let expr = boolean(true);
895            let value = test.eval(&expr);
896            assert!(value.as_bool().unwrap());
897        });
898    }
899
900    #[test]
901    fn test_dyn_list() {
902        let mut states = States::new();
903        setup(&mut states, Default::default(), |test| {
904            test.with_state(|state| {
905                state.list.push("abc");
906                state.list.push("def");
907            });
908            let expr = index(index(ident("state"), strlit("list")), num(1));
909            let value = test.eval(&expr);
910            assert_eq!("def", value.as_str().unwrap());
911        });
912    }
913
914    #[test]
915    fn test_expression_map_state_key() {
916        let mut states = States::new();
917        setup(&mut states, Default::default(), |test| {
918            let expr = index(map([("value", 123)]), index(ident("state"), strlit("string")));
919            test.with_state(|state| state.string.set("value"));
920            let value = test.eval(&expr);
921            assert_eq!(123, value.as_int().unwrap());
922        });
923    }
924
925    #[test]
926    fn test_expression_map() {
927        let mut states = States::new();
928        setup(&mut states, Default::default(), |test| {
929            let expr = index(map([("value", 123)]), strlit("value"));
930            let value = test.eval(&expr);
931            assert_eq!(123, value.as_int().unwrap());
932        });
933    }
934
935    #[test]
936    fn test_state_lookup() {
937        let mut states = States::new();
938        setup(&mut states, Default::default(), |test| {
939            let expr = index(ident("state"), strlit("num"));
940            let value = test.eval(&expr);
941            assert_eq!(0, value.as_int().unwrap());
942        });
943    }
944
945    #[test]
946    fn test_nested_map() {
947        let mut states = States::new();
948        setup(&mut states, Default::default(), |test| {
949            let expr = index(index(ident("state"), strlit("map")), strlit("value"));
950            test.with_state(|state| state.map.to_mut().insert("value", 123));
951            let value = test.eval(&expr);
952            assert_eq!(123, value.as_int().unwrap());
953        });
954    }
955
956    // #[test]
957    // fn test_nested_maps() {
958    //     let mut states = States::new();
959    //     setup(&mut states, Default::default(), |test| {
960    //         let expr = index(
961    //             index(index(ident("state"), strlit("value")), strlit("value")),
962    //             strlit("value"),
963    //         );
964    //         let mut inner_map = Value::new(Map::empty());
965    //         let mut inner_inner_map = Value::new(Map::empty());
966    //         inner_inner_map.insert("value", 123);
967    //         inner_map.insert("value", inner_inner_map);
968
969    //         test.set_state("value", inner_map);
970    //         let value = test.eval(&*expr);
971    //         assert_eq!(123, value.as_int().unwrap());
972    //     });
973    // }
974
975    #[test]
976    fn stringify() {
977        let mut states = States::new();
978        setup(&mut states, Default::default(), |test| {
979            let expr = text_segments([strlit("hello"), strlit(" "), strlit("world")]);
980            let value = test.eval(&expr);
981            let mut actual = String::new();
982            value.strings(|st| {
983                actual.push_str(st);
984                true
985            });
986            assert_eq!("hello world", &actual);
987        });
988    }
989}