tokio_interceptor/
coeffects.rs1use std::any::Any;
17use std::marker::PhantomData;
18use std::rc::Rc;
19use std::sync::Arc;
20
21use futures::{future,Future};
22
23use super::{Context,Interceptor};
24
25pub trait Coeffect: Any {}
26
27impl<C: Coeffect + ?Sized> Coeffect for Arc<C> {}
28impl<C: Coeffect + ?Sized> Coeffect for Rc<C> {}
29impl<C: Coeffect + ?Sized> Coeffect for Box<C> {}
30
31pub trait NewCoeffect {
32 type Instance: Coeffect;
33
34 fn new_coeffect(&self) -> Self::Instance;
35}
36
37#[derive(Default)]
38pub struct InjectCoeffect<C, E>(C, PhantomData<E>);
39
40impl<C, E> InjectCoeffect<C, E>
41{
42 pub fn new(new_coeffect: C) -> InjectCoeffect<C, E> {
43 InjectCoeffect(new_coeffect, PhantomData)
44 }
45}
46
47impl<C, E> Interceptor for InjectCoeffect<C, E>
48where C: NewCoeffect,
49 E: 'static,
50{
51 type Error = E;
52
53 fn before(&self, mut context: Context<Self::Error>) -> Box<Future<Item = Context<Self::Error>,
54 Error = Self::Error>> {
55 context.coeffects.insert(self.0.new_coeffect());
56 Box::new(future::ok(context))
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 use std::rc::Rc;
65
66 use tests::{State,StateHolder};
67
68 #[test]
69 fn test_coeffect_interceptor() {
70 let context: Context<()> = Context::new(vec![]);
71 let state_holder = StateHolder(Rc::new(State(101)));
72 let i = InjectCoeffect::<StateHolder, ()>::new(state_holder);
73 let new_ctx = i.before(context).wait().unwrap();
74 assert_eq!(State(101), **new_ctx.coeffects.get::<Rc<State>>().unwrap());
75 }
76}