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
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
//! Provides interfaces and implementations for logic constructs that return values without accepting arguments, either via closure captures, global state, calculation or otherwise.

#[cfg(test)]
mod tests;

use std::rc::Rc;

/// An interface for immediate evaluation (without caching) for any types and cached (lazy) evaluation for types that implement `Clone`, including those that implement [`Copy`], integers and floats being the simplest examples.
pub trait Evaluator {
    /// The type that the evaluator evaluates to.
    type Output;
    /// Evaluates and returns the result. Because evaluators may possibly involve caching, a mutable borrow of `self` is required. Thus all evaluators must be mutable.
    /// # Panics
    /// Panicking of this function is not defined or restricted. Refer to the documentation of implementing structs for more information.
    fn eval(&mut self) -> Self::Output;
}

/// An interface for cached (lazy) evaluation for types that do not implement `Clone` (note that `Clone` is a supertrait of `Copy`).
pub trait RcEvaluator {
    /// The type that the evaluator evaluates to.
    type Output;
    /// Evaluates and returns a reference counter to the result. Because evaluators may possibly involve caching, a mutable borrow of `self` is required. Thus all evaluators must be mutable.
    /// # Panics
    /// Panicking of this function is not defined or restricted. Refer to the documentation of implementing structs for more information.
    fn eval(&mut self) -> Rc<Self::Output>;
}

/// Implements immediate evaluation via closures.
pub struct ImmEval<Out, Cl>
where Cl: FnMut() -> Out {
    closure: Cl
}
impl<Out, Cl> From<Cl> for ImmEval<Out, Cl>
where Cl: FnMut() -> Out {
    /// Constructs the evaluator from the specified closure.
    fn from(cl: Cl) -> Self {
        ImmEval {closure: cl}
    }
}
impl<Out, Cl> Evaluator for ImmEval<Out, Cl>
where Cl: FnMut() -> Out {
    type Output = Out;
    /// Evaluates and returns the result. Because evaluators may possibly involve caching, a mutable borrow of `self` is required by the [`Evaluator`](trait.Evaluator.html) trait, though immediate evaluators do not involve any.
    /// # Panics
    /// Panicking of this function is not defined or restricted and depends on the closure.
    fn eval(&mut self) -> Self::Output {
        (self.closure)()
    }
}

/// Implements cached (lazy) evaluation **of clonable types** via closures.
pub struct Eval<Out, Cl>
where Out: Clone, Cl: FnMut() -> Out {
    closure: Cl,
    last: Option<Out>
}
impl<Out, Cl> Eval<Out, Cl>
where Out: Clone, Cl: FnMut() -> Out {
    /// Invalidates the cached value, if there is one. If the evaluator was never used after creation or was recently `flush()`ed, does nothing.
    pub fn flush(&mut self) {
        self.last = None;
    }
}
impl<Out, Cl> From<Cl> for Eval<Out, Cl>
where Out: Clone, Cl: FnMut() -> Out {
    /// Constructs the evaluator from the specified closure.
    fn from(cl: Cl) -> Self {
        Eval {closure: cl, last: None}
    }
}
impl<Out, Cl> Evaluator for Eval<Out, Cl>
where Out: Clone, Cl: FnMut() -> Out {
    type Output = Out;
    /// Evaluates and returns the result. **This includes the overhead of cloning the value, because the internal cache must be preserved. If you need to move the result every time it is evaluated, use [`ImmEval`].**
    ///
    /// Because caching evaluators, as their name suggests, store the cached value inside themselves, a mutable borrow of `self` is required.
    /// # Panics
    /// Panicking of this function is not defined or restricted and depends on the closure.
    fn eval(&mut self) -> Self::Output {
        if self.last.is_none() {
            self.last = Option::from((self.closure)());
        }
        self.last.clone().unwrap()
    }
}

/// Implements cached (lazy) evaluation of clonable **and** non-clonable types via closures.
pub struct RcEval<Out, Cl>
where Cl: FnMut() -> Out {
    closure: Cl,
    last: Option<Rc<Out>>
}
impl<Out, Cl> RcEval<Out, Cl>
where Cl: FnMut() -> Out {
    /// Disowns the cached value (destroying it if there are no other owners), if there is one. If the evaluator was never used after creation or was recently `flush()`ed, does nothing.
    pub fn flush(&mut self) {
        self.last = None;
    }
}
impl<Out, Cl> From<Cl> for RcEval<Out, Cl>
where Cl: FnMut() -> Out {
    /// Constructs the evaluator from the specified closure.
    fn from(cl: Cl) -> Self {
        RcEval {closure: cl, last: None}
    }
}
impl<Out, Cl> RcEvaluator for RcEval<Out, Cl>
where Cl: FnMut() -> Out {
    type Output = Out;
    /// Evaluates and returns an [`std::rc::Rc`] to the result.
    ///
    /// Because caching evaluators, as their name suggests, store the cached value inside themselves, a mutable borrow of `self` is required.
    /// # Panics
    /// Panicking of this function is not defined or restricted and depends on the closure.
    fn eval(&mut self) -> Rc<Self::Output> {
        if self.last.is_none() {
            self.last = Option::from(Rc::from((self.closure)()));
        }
        self.last.clone().unwrap()
    }
}
impl<Out, Cl> Evaluator for RcEval<Out, Cl>
where Out: Clone, Cl: FnMut() -> Out {
    type Output = Out;
    /// Evaluates and returns the result. **This includes the overhead of cloning the value, because the internal cache must be preserved. If you need to move the result every time it is evaluated, use [`ImmEval`].**
    ///
    /// Because caching evaluators, as their name suggests, store the cached value inside themselves, a mutable borrow of `self` is required.
    /// # Panics
    /// Panicking of this function is not defined or restricted and depends on the closure.
    fn eval(&mut self) -> Self::Output {
        if self.last.is_none() {
            self.last = Option::from(Rc::from((self.closure)()));
        }
        Out::clone(&self.last.clone().unwrap())
    }
}

/// Implements dummy evaluation of clonable **and** non-clonable types: every time the `eval()` method is called, a fixed value is returned.
pub struct DummyEval<Out> {
    value: Out
}
impl<Out> From<Out> for DummyEval<Out> {
    /// Constructs the evaluator from the specified dummy value.
    fn from(value: Out) -> Self {
        DummyEval {value}
    }
}
impl<Out> Evaluator for DummyEval<Out>
where Out: Clone {
    type Output = Out;
    /// Evaluates and returns the result. **This includes the overhead of cloning the value, because the fixed value must be preserved.**
    ///
    /// Because caching evaluators, as their name suggests, store the cached value inside themselves, a mutable borrow of `self` is required.
    /// # Panics
    /// May panic only if cloning of the inner value panics.
    fn eval(&mut self) -> Self::Output {
        self.value.clone()
    }
}/*
impl<Out> RcEvaluator for DummyEval<Out> {
    type Output = Out;
    /// Evaluates and returns an [`std::rc::Rc`] to the result. Because evaluators may possibly involve caching, a mutable borrow of `self` is required by the [`Evaluator`](trait.Evaluator.html) trait, though dummy evaluators obviously do not involve any, as no values are produced during evaluation.
    /// # Panics
    /// Guaranteed to never panic.
    fn eval(&mut self) -> Rc<Self::Output> {
        uuh dunno?
    }
}*/