tokio_interceptor/
effects.rs1use std::mem;
17use std::cell::RefCell;
18use std::marker::PhantomData;
19use std::rc::Rc;
20
21use futures::{future,Future};
22
23use super::{Context,Interceptor};
24
25pub trait Effect {
26 fn action(self: Box<Self>);
27}
28
29pub struct HandleEffects<E>(PhantomData<E>);
30
31impl<E> HandleEffects<E>
32{
33 pub fn new() -> HandleEffects<E> {
34 HandleEffects(PhantomData)
35 }
36}
37
38impl<E> Interceptor for HandleEffects<E>
39where E: 'static,
40{
41 type Error = E;
42
43 fn after(&self, mut context: Context<Self::Error>) -> Box<Future<Item = Context<Self::Error>,
44 Error = Self::Error>> {
45 let effects = mem::replace(&mut context.effects, vec![]);
46 for e in effects.into_iter() {
47 e.action();
48 }
49 Box::new(future::ok(context))
50 }
51}
52
53pub struct MutateState<S, F> {
54 state_ref: Option<Rc<RefCell<S>>>,
55 mutate: F,
56}
57
58impl<S, F> MutateState<S, F> {
59 pub fn new(state_ref: Rc<RefCell<S>>, mutate: F) -> MutateState<S, F> {
60 MutateState { state_ref: Some(state_ref), mutate }
61 }
62}
63
64impl<S, F> Effect for MutateState<S, F>
65where S: 'static,
66 F: 'static + FnOnce(&mut S)
67{
68 fn action(mut self: Box<Self>) {
69 let state_ref = self.state_ref.take().unwrap();
70 let mut state = state_ref.borrow_mut();
71 (self.mutate)(&mut state)
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 use Context;
80
81 use tests::State;
82
83 #[test]
84 fn test_effect_interceptor() {
85 let mut context: Context<()> = Context::new(vec![]);
86 let i: HandleEffects<()> = HandleEffects::new();
87
88 let state = Rc::new(RefCell::new(State(0)));
89 let e = MutateState::new(Rc::clone(&state), |state: &mut State| state.0 = 10);
90 context.effects.push(Box::new(e));
91 i.after(context);
92
93 assert_eq!(state.borrow().0, 10);
94 }
95}