gotham/router/response/
finalizer.rs1use std::collections::HashMap;
5use std::pin::Pin;
6use std::sync::Arc;
7
8use futures_util::future::{self, FutureExt};
9use hyper::{Body, Response, StatusCode};
10use log::trace;
11
12use crate::handler::HandlerFuture;
13use crate::state::{request_id, State};
14
15use crate::router::response::extender::ResponseExtender;
16
17#[derive(Clone)]
22pub struct ResponseFinalizer {
23 data: Arc<HashMap<StatusCode, Box<dyn ResponseExtender<Body> + Send + Sync>>>,
24}
25
26pub struct ResponseFinalizerBuilder {
28 data: HashMap<StatusCode, Box<dyn ResponseExtender<Body> + Send + Sync>>,
29}
30
31impl ResponseFinalizerBuilder {
32 pub(in crate::router) fn new() -> Self {
34 let handlers = HashMap::new();
35 ResponseFinalizerBuilder { data: handlers }
36 }
37
38 pub fn add(
40 &mut self,
41 status_code: StatusCode,
42 extender: Box<dyn ResponseExtender<Body> + Send + Sync>,
43 ) {
44 trace!(" adding response extender for {}", status_code);
45 self.data.insert(status_code, extender);
46 }
47
48 pub fn finalize(self) -> ResponseFinalizer {
50 ResponseFinalizer {
51 data: Arc::new(self.data),
52 }
53 }
54}
55
56impl ResponseFinalizer {
57 pub fn finalize(&self, mut state: State, mut res: Response<Body>) -> Pin<Box<HandlerFuture>> {
60 match self.data.get(&res.status()) {
61 Some(extender) => {
62 trace!(
63 "[{}] invoking {} response extender",
64 request_id(&state),
65 res.status()
66 );
67 extender.extend(&mut state, &mut res);
68 }
69 None => {
70 trace!(
71 "[{}] no response extender for {}",
72 request_id(&state),
73 res.status()
74 );
75 }
76 }
77
78 future::ok((state, res)).boxed()
79 }
80}