1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//! Standard collections of variables.

use core::{cmp::Ordering, fmt};

use crate::{fns, Object, Value};

/// Commonly used constants and functions from the [`fns` module](fns).
///
/// # Contents
///
/// - `true` and `false` Boolean constants.
/// - Deferred initialization: [`defer`](fns::Defer).
/// - Control flow functions: [`if`](fns::If), [`while`](fns::While).
/// - Array functions: [`all`](fns::All), [`any`](fns::Any), [`filter`](fns::Filter), [`fold`](fns::Fold),
///   [`map`](fns::Map), [`merge`](fns::Merge), [`push`](fns::Push). Available both as free functions
///   and as fields in an `Array` object.
#[derive(Debug, Clone, Copy, Default)]
pub struct Prelude;

impl Prelude {
    /// Creates an iterator over contained values and the corresponding names.
    pub fn iter<T>() -> impl Iterator<Item = (&'static str, Value<T>)>
    where
        T: 'static + Clone,
    {
        let array_object: Object<T> = Self::array_functions::<T>().collect();
        [
            ("false", Value::Bool(false)),
            ("true", Value::Bool(true)),
            ("defer", Value::native_fn(fns::Defer)),
            ("if", Value::native_fn(fns::If)),
            ("while", Value::native_fn(fns::While)),
        ]
        .into_iter()
        .chain(Self::array_functions::<T>())
        .chain([("Array", array_object.into())])
    }

    fn array_functions<T>() -> impl Iterator<Item = (&'static str, Value<T>)>
    where
        T: 'static + Clone,
    {
        [
            ("all", Value::native_fn(fns::All)),
            ("any", Value::native_fn(fns::Any)),
            ("filter", Value::native_fn(fns::Filter)),
            ("fold", Value::native_fn(fns::Fold)),
            ("map", Value::native_fn(fns::Map)),
            ("merge", Value::native_fn(fns::Merge)),
            ("push", Value::native_fn(fns::Push)),
        ]
        .into_iter()
    }
}

/// Container for assertion functions: `assert`, `assert_eq` and `assert_fails`.
#[derive(Debug, Clone, Copy, Default)]
pub struct Assertions;

impl Assertions {
    /// Creates an iterator over contained values and the corresponding names.
    pub fn iter<T>() -> impl Iterator<Item = (&'static str, Value<T>)>
    where
        T: 'static + Clone + fmt::Display,
    {
        [
            ("assert", Value::native_fn(fns::Assert)),
            ("assert_eq", Value::native_fn(fns::AssertEq)),
            (
                "assert_fails",
                Value::native_fn(fns::AssertFails::default()),
            ),
        ]
        .into_iter()
    }
}

/// Container with the comparison functions: `cmp`, `min` and `max`.
#[derive(Debug, Clone, Copy, Default)]
pub struct Comparisons;

impl Comparisons {
    /// Creates an iterator over contained values and the corresponding names.
    pub fn iter<T>() -> impl Iterator<Item = (&'static str, Value<T>)> {
        [
            ("LESS", Value::opaque_ref(Ordering::Less)),
            ("EQUAL", Value::opaque_ref(Ordering::Equal)),
            ("GREATER", Value::opaque_ref(Ordering::Greater)),
            ("cmp", Value::native_fn(fns::Compare::Raw)),
            ("min", Value::native_fn(fns::Compare::Min)),
            ("max", Value::native_fn(fns::Compare::Max)),
        ]
        .into_iter()
    }
}