expectation_harness/
bindings.rs1use crate::driver::{Driver, Need, Progress, Screenshot};
13use expectation_model::text;
14use expectation_model::{Event, Value, Variable};
15use std::collections::HashMap;
16
17type Observer<W> = Box<dyn FnMut(&W) -> Value>;
18type Setter<W> = Box<dyn FnMut(&mut W, &Value)>;
19type Action<W> = Box<dyn FnMut(&mut W)>;
20type Advancer<W> = Box<dyn FnMut(&mut W) -> Progress>;
21type Shooter<W> = Box<dyn FnMut(&W) -> Screenshot>;
22
23pub struct Bindings<W> {
24 pub world: W,
25 observers: HashMap<String, Observer<W>>,
26 setters: HashMap<String, Setter<W>>,
27 arrangers: HashMap<String, Setter<W>>,
28 events: HashMap<String, Action<W>>,
29 reset: Option<Action<W>>,
30 settle: Option<Action<W>>,
31 advance: Option<Advancer<W>>,
32 screenshot: Option<Shooter<W>>,
33 needs: Vec<String>,
34 fresh: Vec<String>,
35}
36
37impl<W> Bindings<W> {
38 pub fn new(world: W) -> Self {
39 Bindings {
40 world,
41 observers: HashMap::new(),
42 setters: HashMap::new(),
43 arrangers: HashMap::new(),
44 events: HashMap::new(),
45 reset: None,
46 settle: None,
47 advance: None,
48 screenshot: None,
49 needs: vec![],
50 fresh: vec![],
51 }
52 }
53
54 pub fn fresh(mut self, services: &[&str]) -> Self {
56 self.fresh = services.iter().map(|s| s.to_string()).collect();
57 self
58 }
59
60 pub fn needs(mut self, services: &[&str]) -> Self {
62 self.needs = services.iter().map(|s| s.to_string()).collect();
63 self
64 }
65
66 pub fn observe<V: Into<Value>>(mut self, subject: &str, mut f: impl FnMut(&W) -> V + 'static) -> Self {
68 self.observers.insert(text::key(subject), Box::new(move |w| f(w).into()));
69 self
70 }
71
72 pub fn set(mut self, subject: &str, f: impl FnMut(&mut W, &Value) + 'static) -> Self {
75 self.setters.insert(text::key(subject), Box::new(f));
76 self
77 }
78
79 pub fn arrange(mut self, subject: &str, f: impl FnMut(&mut W, &Value) + 'static) -> Self {
81 self.arrangers.insert(text::key(subject), Box::new(f));
82 self
83 }
84
85 pub fn on(mut self, event: &str, f: impl FnMut(&mut W) + 'static) -> Self {
86 self.events.insert(text::key(event), Box::new(f));
87 self
88 }
89
90 pub fn on_reset(mut self, f: impl FnMut(&mut W) + 'static) -> Self {
91 self.reset = Some(Box::new(f));
92 self
93 }
94
95 pub fn on_settle(mut self, f: impl FnMut(&mut W) + 'static) -> Self {
96 self.settle = Some(Box::new(f));
97 self
98 }
99
100 pub fn on_advance(mut self, f: impl FnMut(&mut W) -> Progress + 'static) -> Self {
101 self.advance = Some(Box::new(f));
102 self
103 }
104
105 pub fn on_screenshot(mut self, f: impl FnMut(&W) -> Screenshot + 'static) -> Self {
106 self.screenshot = Some(Box::new(f));
107 self
108 }
109}
110
111fn unbound(what: &str, name: &str) -> String {
112 format!("nothing is bound to {what} `{name}`")
113}
114
115impl<W> Driver for Bindings<W> {
116 fn needs(&self) -> Vec<String> {
117 self.needs.clone()
118 }
119
120 fn fresh(&self) -> Vec<String> {
121 self.fresh.clone()
122 }
123
124 fn reset(&mut self) -> Result<(), String> {
125 if let Some(f) = &mut self.reset {
126 f(&mut self.world);
127 }
128 Ok(())
129 }
130
131 fn arrange(&mut self, var: &Variable, value: &Value) -> Result<(), String> {
132 let f = self.arrangers.get_mut(&var.key).or_else(|| self.setters.get_mut(&var.key));
133 f.map(|f| f(&mut self.world, value)).ok_or_else(|| unbound("arrange", &var.subject))
134 }
135
136 fn set(&mut self, var: &Variable, value: &Value) -> Result<(), String> {
137 let f = self.setters.get_mut(&var.key);
138 f.map(|f| f(&mut self.world, value)).ok_or_else(|| unbound("set", &var.subject))
139 }
140
141 fn perform(&mut self, event: &Event) -> Result<(), String> {
142 let f = self.events.get_mut(&event.key);
143 f.map(|f| f(&mut self.world)).ok_or_else(|| unbound("the event", &event.text))
144 }
145
146 fn observe(&mut self, var: &Variable) -> Result<Value, String> {
147 let f = self.observers.get_mut(&var.key);
148 f.map(|f| f(&self.world)).ok_or_else(|| unbound("observe", &var.subject))
149 }
150
151 fn settle(&mut self) {
152 if let Some(f) = &mut self.settle {
153 f(&mut self.world);
154 }
155 }
156
157 fn advance(&mut self) -> Progress {
158 self.advance.as_mut().map_or(Progress::Static, |f| f(&mut self.world))
159 }
160
161 fn screenshot(&mut self) -> Result<Option<Screenshot>, String> {
162 Ok(self.screenshot.as_mut().map(|f| f(&self.world)))
163 }
164
165 fn supports(&self, need: Need<'_>) -> bool {
166 match need {
167 Need::Arrange(v) => self.arrangers.contains_key(&v.key) || self.setters.contains_key(&v.key),
168 Need::Set(v) => self.setters.contains_key(&v.key),
169 Need::Perform(e) => self.events.contains_key(&e.key),
170 Need::Observe(v) => self.observers.contains_key(&v.key),
171 }
172 }
173}