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
//! Defines functionality for extending a Response.

use crate::state::{request_id, State};
use hyper::body::HttpBody;
use hyper::{Body, Response};
use log::trace;
use std::panic::RefUnwindSafe;

/// Extend the `Response` based on current `State` and `Response` data.
pub trait StaticResponseExtender: RefUnwindSafe {
    /// The type of the response body. Almost always `hyper::Body`.
    type ResBody: HttpBody;

    /// Extend the response.
    fn extend(state: &mut State, response: &mut Response<Self::ResBody>);
}

/// Allow complex types to extend the `Response` based on current `State` and `Response` data.
pub trait ResponseExtender<B>: RefUnwindSafe {
    /// Extend the Response
    fn extend(&self, state: &mut State, response: &mut Response<B>);
}

impl<F, B> ResponseExtender<B> for F
where
    F: Fn(&mut State, &mut Response<B>) + Send + Sync + RefUnwindSafe,
{
    fn extend(&self, state: &mut State, res: &mut Response<B>) {
        trace!(
            "[{}] running closure based response extender",
            request_id(state)
        );
        self(state, res);
    }
}

/// An extender that does not alter the response.
///
/// This is likely to only be useful in documentation or example code.
pub struct NoopResponseExtender;

impl StaticResponseExtender for NoopResponseExtender {
    type ResBody = Body;

    fn extend(state: &mut State, _res: &mut Response<Body>) {
        trace!(
            "[{}] NoopResponseExtender invoked, does not make any changes to Response",
            request_id(state)
        );
        trace!("[{}] no response body, no change made", request_id(state));
    }
}

impl ResponseExtender<Body> for NoopResponseExtender {
    fn extend(&self, state: &mut State, _res: &mut Response<Body>) {
        trace!(
            "[{}] NoopResponseExtender invoked on instance, does not make any changes to Response",
            request_id(state)
        );
        trace!("[{}] no response body, no change made", request_id(state));
    }
}