pub struct EventInterceptor<T: Event<E>, E>(/* private fields */);
Implementations§
Source§impl<T: Event<E>, E> EventInterceptor<T, E>
impl<T: Event<E>, E> EventInterceptor<T, E>
Sourcepub fn new(event: T) -> EventInterceptor<T, E>
pub fn new(event: T) -> EventInterceptor<T, E>
Examples found in repository?
examples/todo.rs (line 95)
88 fn handle(self: Box<Self>, mut context: Context<()>) -> Box<Future<Item = Context<()>, Error = ()>> {
89 {
90 let db = context.coeffects.get::<Db<AppState>>().unwrap();
91 match db.borrow().mode {
92 Mode::Menu => {
93 let interceptors: Vec<Box<Interceptor<Error = ()>>> = vec![
94 Box::new(EmptyInputHandler(Mode::Quitting)),
95 Box::new(EventInterceptor::new(MenuInput))
96 ];
97 context.queue.extend(interceptors);
98 },
99 Mode::Adding => {
100 let interceptors: Vec<Box<Interceptor<Error = ()>>> = vec![
101 Box::new(EmptyInputHandler(Mode::Menu)),
102 Box::new(EventInterceptor::new(AddTodo))
103 ];
104 context.queue.extend(interceptors);
105 },
106 Mode::Removing => {
107 let interceptors: Vec<Box<Interceptor<Error = ()>>> = vec![
108 Box::new(EmptyInputHandler(Mode::Menu)),
109 Box::new(ParseIndex),
110 Box::new(EventInterceptor::new(RemoveTodo))
111 ];
112 context.queue.extend(interceptors);
113 },
114 Mode::Marking => {
115 let interceptors: Vec<Box<Interceptor<Error = ()>>> = vec![
116 Box::new(EmptyInputHandler(Mode::Menu)),
117 Box::new(ParseIndex),
118 Box::new(EventInterceptor::new(ToggleMark))
119 ];
120 context.queue.extend(interceptors);
121 },
122 Mode::Quitting => context.queue.push_back(Box::new(EventInterceptor::new(Quit(0))) as Box<Interceptor<Error = ()>>),
123 }
124 }
125 let input = *self;
126 context.coeffects.insert(input);
127 context.next()
128 }
129}
130
131struct NonEmptyInput(String);
132
133struct EmptyInputHandler(Mode);
134
135impl Interceptor for EmptyInputHandler {
136 type Error = ();
137
138 fn before(&self, mut context: Context<()>) -> Box<Future<Item = Context<()>, Error = ()>> {
139 match context.coeffects.remove::<Input>().unwrap().0.as_ref() {
140 "" => {
141 context.queue.clear();
142 let db = context.coeffects.get::<Db<AppState>>().unwrap();
143 let mode = self.0;
144 context.effects.push(Box::new(db.mutate(move |state: &mut AppState| state.mode = mode)));
145 let dispatcher = context.coeffects.get::<Dispatcher<()>>().unwrap();
146 context.effects.push(dispatcher.dispatch(ShowMenu));
147 },
148 input => {
149 context.coeffects.insert(NonEmptyInput(input.to_string()));
150 }
151 };
152
153 context.next()
154 }
155}
156
157struct Index(Result<usize, RemoveError<std::num::ParseIntError>>);
158
159struct ParseIndex;
160
161impl Interceptor for ParseIndex {
162 type Error = ();
163
164 fn before(&self, mut context: Context<()>) -> Box<Future<Item = Context<()>, Error = ()>> {
165 let max = {
166 let db = context.coeffects.get::<Db<AppState>>().unwrap();
167 db.borrow().todos.len()
168 };
169 let index_res = context.coeffects.remove::<NonEmptyInput>().unwrap()
170 .0.parse::<isize>()
171 .map_err(RemoveError::ParseError)
172 .and_then(|index| {
173 if index >= 0 && (index as usize) < max {
174 Ok(index as usize)
175 } else {
176 Err(RemoveError::OutOfRange(index))
177 }
178 });
179 context.coeffects.insert(Index(index_res));
180 context.next()
181 }
182}
183
184struct MenuInput;
185
186impl Event<()> for MenuInput {
187 fn handle(self: Box<Self>, mut context: Context<()>) -> Box<Future<Item = Context<()>, Error = ()>> {
188 {
189 let input = context.coeffects.get::<NonEmptyInput>().unwrap();
190 let next_mode = match input.0.as_ref() {
191 "1" => {
192 let dispatcher = context.coeffects.get::<Dispatcher<()>>().unwrap();
193 context.effects.push(dispatcher.dispatch(ShowTodos));
194 Mode::Menu
195 },
196 "2" => Mode::Adding,
197 "3" => Mode::Marking,
198 "4" => Mode::Removing,
199 _ => Mode::Menu,
200 };
201 let db = context.coeffects.get::<Db<AppState>>().unwrap();
202 context.effects.push(Box::new(db.mutate(move |state: &mut AppState| state.mode = next_mode)));
203 }
204 context.next()
205 }
206}
207
208struct ShowTodos;
209
210impl Event<()> for ShowTodos {
211 fn handle(self: Box<Self>, mut context: Context<()>) -> Box<Future<Item = Context<()>, Error = ()>> {
212 {
213 let db = context.coeffects.get::<Db<AppState>>().unwrap();
214 context.effects.push(Box::new(Print(format!("\nTODO:"))));
215 let todos = &db.borrow().todos;
216 if 0 == todos.len() {
217 context.effects.push(Box::new(Print(" Nothing to do.".to_string())));
218 }
219 for (i, todo) in todos.iter().enumerate() {
220 let status = if todo.0 { "✔" } else { " " };
221 context.effects.push(Box::new(Print(format!(" - {}: [{}] {}", i, status, todo.1))));
222 }
223 context.effects.push(Box::new(Print("".to_string())));
224 }
225 context.next()
226 }
227}
228
229struct AddTodo;
230
231impl Event<()> for AddTodo {
232 fn handle(self: Box<Self>, mut context: Context<()>) -> Box<Future<Item = Context<()>, Error = ()>> {
233 {
234 let input = context.coeffects.remove::<NonEmptyInput>().unwrap().0;
235 let db = context.coeffects.get::<Db<AppState>>().unwrap();
236 context.effects.push(Box::new(db.mutate(move |state: &mut AppState| state.todos.push((false, input)))));
237 }
238 context.next()
239 }
240}
241
242struct RemoveTodo;
243
244#[derive(Debug)]
245enum RemoveError<E> {
246 ParseError(E),
247 OutOfRange(isize),
248}
249
250impl Event<()> for RemoveTodo {
251 fn handle(self: Box<Self>, mut context: Context<()>) -> Box<Future<Item = Context<()>, Error = ()>> {
252 {
253 let index_res = context.coeffects.remove::<Index>().unwrap().0;
254 let db = context.coeffects.get::<Db<AppState>>().unwrap();
255 match index_res {
256 Ok(index) => {
257 context.effects.push(Box::new(db.mutate(move |state: &mut AppState| {
258 state.todos.remove(index);
259 })));
260 },
261 Err(e) => {
262 context.effects.push(Box::new(Print(format!("Error removing: {:?}", e))))
263 },
264 };
265 }
266 context.next()
267 }
268}
269
270struct ToggleMark;
271
272impl Event<()> for ToggleMark {
273 fn handle(self: Box<Self>, mut context: Context<()>) -> Box<Future<Item = Context<()>, Error = ()>> {
274 {
275 let index_res = context.coeffects.remove::<Index>().unwrap().0;
276 let db = context.coeffects.get::<Db<AppState>>().unwrap();
277 match index_res {
278 Ok(index) => {
279 context.effects.push(Box::new(db.mutate(move |state: &mut AppState| {
280 let todo = state.todos.get_mut(index).unwrap();
281 todo.0 = ! todo.0;
282 })));
283 },
284 Err(e) => {
285 context.effects.push(Box::new(Print(format!("Error marking: {:?}", e))))
286 },
287 };
288 }
289 context.next()
290 }
291}
292
293struct ShowPrompt;
294
295impl Event<()> for ShowPrompt {
296 fn handle(self: Box<Self>, mut context: Context<()>) -> Box<Future<Item = Context<()>, Error = ()>> {
297 {
298 let db = context.coeffects.get::<Db<AppState>>().unwrap();
299 let dispatcher = context.coeffects.get::<Dispatcher<()>>().unwrap();
300 match db.borrow().mode {
301 Mode::Menu => context.effects.push(dispatcher.dispatch(ShowMenu)),
302 Mode::Adding => {
303 context.effects.push(dispatcher.dispatch(ShowTodos));
304 },
305 Mode::Removing => {
306 context.effects.push(dispatcher.dispatch(ShowTodos));
307 },
308 Mode::Marking => {
309 context.effects.push(dispatcher.dispatch(ShowTodos));
310 },
311 Mode::Quitting => {
312 context.queue.push_back(Box::new(EventInterceptor::new(Quit(0))) as Box<Interceptor<Error = ()>>);
313 }
314 }
315 }
316 context.next()
317 }
Trait Implementations§
Source§impl<E: 'static, T: Event<E>> Interceptor for EventInterceptor<T, E>
impl<E: 'static, T: Event<E>> Interceptor for EventInterceptor<T, E>
Auto Trait Implementations§
impl<T, E> !Freeze for EventInterceptor<T, E>
impl<T, E> !RefUnwindSafe for EventInterceptor<T, E>
impl<T, E> Send for EventInterceptor<T, E>
impl<T, E> !Sync for EventInterceptor<T, E>
impl<T, E> Unpin for EventInterceptor<T, E>
impl<T, E> UnwindSafe for EventInterceptor<T, E>where
E: UnwindSafe,
T: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more