1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
extern crate iron;
use iron::middleware::{AfterMiddleware, BeforeMiddleware};
use iron::prelude::*;

use std::marker::PhantomData;

pub enum InspectRequest {}
pub enum InspectResult {}
pub enum InspectResponse {}
pub enum InspectError {}

pub struct Inspect<F, What> {
    f: F,
    _phantom: PhantomData<What>,
}

impl<F> Inspect<F, ()> {
    pub fn new(f: F) -> Inspect<F, InspectResult>
    where
        F: Fn(&Request, Result<&Response, &IronError>),
    {
        Inspect {
            f,
            _phantom: PhantomData,
        }
    }

    pub fn request(f: F) -> Inspect<F, InspectRequest>
    where
        F: Fn(&Request),
    {
        Inspect {
            f,
            _phantom: PhantomData,
        }
    }

    pub fn response(f: F) -> Inspect<F, InspectResponse>
    where
        F: Fn(&Request, &Response),
    {
        Inspect {
            f,
            _phantom: PhantomData,
        }
    }

    pub fn error(f: F) -> Inspect<F, InspectError>
    where
        F: Fn(&Request, &IronError),
    {
        Inspect {
            f,
            _phantom: PhantomData,
        }
    }
}

impl<F> BeforeMiddleware for Inspect<F, InspectRequest>
where
    F: Send + Sync + 'static,
    F: Fn(&Request),
{
    fn before(&self, req: &mut Request) -> IronResult<()> {
        (self.f)(req);
        Ok(())
    }
}

impl<F> AfterMiddleware for Inspect<F, InspectResult>
where
    F: Send + Sync + 'static,
    F: Fn(&Request, Result<&Response, &IronError>),
{
    fn after(&self, req: &mut Request, res: Response) -> IronResult<Response> {
        (self.f)(req, Ok(&res));
        Ok(res)
    }

    fn catch(&self, req: &mut Request, err: IronError) -> IronResult<Response> {
        (self.f)(req, Err(&err));
        Err(err)
    }
}

impl<F> AfterMiddleware for Inspect<F, InspectResponse>
where
    F: Send + Sync + 'static,
    F: Fn(&Request, &Response),
{
    fn after(&self, req: &mut Request, res: Response) -> IronResult<Response> {
        (self.f)(req, &res);
        Ok(res)
    }
}

impl<F> AfterMiddleware for Inspect<F, InspectError>
where
    F: Send + Sync + 'static,
    F: Fn(&Request, &IronError),
{
    fn catch(&self, req: &mut Request, err: IronError) -> IronResult<Response> {
        (self.f)(req, &err);
        Err(err)
    }
}