module_util/evaluator/acyclic/
mod.rs1use std::collections::HashSet;
4use std::hash::Hash;
5
6use super::{Evaluator, Imports};
7
8#[derive(Debug, Clone)]
13pub struct Acyclic<E>
14where
15 E: Evaluator,
16{
17 evaluator: E,
18 evaluated: HashSet<E::Id>,
19}
20
21impl<E> Acyclic<E>
22where
23 E: Evaluator,
24{
25 pub fn new(evaluator: E) -> Self {
27 Self {
28 evaluator,
29 evaluated: HashSet::new(),
30 }
31 }
32}
33
34impl<E> Default for Acyclic<E>
35where
36 E: Evaluator + Default,
37{
38 fn default() -> Self {
39 Self::new(Default::default())
40 }
41}
42
43impl<E> Acyclic<E>
44where
45 E: Evaluator,
46 E::Id: Eq + Hash,
47{
48 pub fn evaluated(&self, id: &E::Id) -> bool {
53 self.evaluated.contains(id)
54 }
55
56 pub fn get(&self) -> &E {
58 &self.evaluator
59 }
60
61 pub fn get_mut(&mut self) -> &mut E {
63 &mut self.evaluator
64 }
65}
66
67impl<E> Evaluator for Acyclic<E>
68where
69 E: Evaluator,
70 E::Id: Clone + Eq + Hash,
71{
72 type Id = E::Id;
73 type Module = E::Module;
74 type Error = E::Error;
75
76 fn is_empty(&self) -> bool {
77 self.evaluator.is_empty()
78 }
79
80 fn next(&mut self) -> Option<Self::Id> {
81 loop {
82 match self.evaluator.next() {
83 Some(x) if self.evaluated(&x) => continue,
84 Some(x) => break Some(x),
85 None => break None,
86 }
87 }
88 }
89
90 fn eval(
91 &mut self,
92 id: Self::Id,
93 imports: Imports<Self::Id>,
94 module: Self::Module,
95 ) -> Result<(), Self::Error> {
96 if self.evaluated(&id) {
97 return Ok(());
98 }
99
100 let r = self.evaluator.eval(id.clone(), imports, module);
101 if r.is_ok() {
102 self.evaluated.insert(id);
103 }
104
105 r
106 }
107
108 fn finish(self) -> Option<Self::Module> {
109 self.evaluator.finish()
110 }
111}