1use futures::Future;
2use hyper;
3use hyper::header::HeaderName;
4use hyper::{Error, Request, Response, StatusCode, service::Service, body::Payload};
5use url::form_urlencoded;
6use std::default::Default;
7use std::io;
8use std::marker::PhantomData;
9use swagger::auth::{AuthData, Authorization, Bearer, Scopes};
10use swagger::context::ContextualPayload;
11use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString};
12use crate::Api;
13
14pub struct MakeAddContext<T, A> {
15 inner: T,
16 marker: PhantomData<A>,
17}
18
19impl<T, A, B, C, D> MakeAddContext<T, A>
20where
21 A: Default + Push<XSpanIdString, Result = B>,
22 B: Push<Option<AuthData>, Result = C>,
23 C: Push<Option<Authorization>, Result = D>,
24{
25 pub fn new(inner: T) -> MakeAddContext<T, A> {
26 MakeAddContext {
27 inner,
28 marker: PhantomData,
29 }
30 }
31}
32
33impl<'a, T, SC, A, B, C, D, E, ME, S, OB, F> hyper::service::MakeService<&'a SC> for
35 MakeAddContext<T, A>
36where
37 A: Default + Push<XSpanIdString, Result = B>,
38 B: Push<Option<AuthData>, Result = C>,
39 C: Push<Option<Authorization>, Result = D>,
40 D: Send + 'static,
41 T: hyper::service::MakeService<
42 &'a SC,
43 Error = E,
44 MakeError = ME,
45 Service = S,
46 ReqBody = ContextualPayload<hyper::Body, D>,
47 ResBody = OB,
48 Future = F
49 >,
50 S: Service<
51 Error = E,
52 ReqBody = ContextualPayload<hyper::Body, D>,
53 ResBody = OB> + 'static,
54 ME: swagger::ErrorBound,
55 E: swagger::ErrorBound,
56 F: Future<Item=S, Error=ME> + Send + 'static,
57 S::Future: Send,
58 OB: Payload,
59{
60 type ReqBody = hyper::Body;
61 type ResBody = OB;
62 type Error = E;
63 type MakeError = ME;
64 type Service = AddContext<S, A>;
65 type Future = Box<dyn Future<Item = Self::Service, Error = ME> + Send + 'static>;
66
67 fn make_service(&mut self, ctx: &'a SC) -> Self::Future {
68 Box::new(self.inner.make_service(ctx).map(|s| AddContext::new(s)))
69 }
70}
71
72pub struct AddContext<T, A> {
74 inner: T,
75 marker: PhantomData<A>,
76}
77
78impl<T, A, B, C, D> AddContext<T, A>
79where
80 A: Default + Push<XSpanIdString, Result = B>,
81 B: Push<Option<AuthData>, Result = C>,
82 C: Push<Option<Authorization>, Result = D>,
83 T: Service,
84{
85 pub fn new(inner: T) -> AddContext<T, A> {
86 AddContext {
87 inner,
88 marker: PhantomData,
89 }
90 }
91}
92
93impl<T, A, B, C, D> Service for AddContext<T, A>
94 where
95 A: Default + Push<XSpanIdString, Result=B>,
96 B: Push<Option<AuthData>, Result=C>,
97 C: Push<Option<Authorization>, Result=D>,
98 D: Send + 'static,
99 T: Service<ReqBody = ContextualPayload<hyper::Body, D>>,
100 T::Future: Future<Item=Response<T::ResBody>, Error=T::Error> + Send + 'static
101{
102 type ReqBody = hyper::Body;
103 type ResBody = T::ResBody;
104 type Error = T::Error;
105 type Future = Box<dyn Future<Item=Response<T::ResBody>, Error=T::Error> + Send + 'static>;
106
107 fn call(&mut self, req: Request<Self::ReqBody>) -> Self::Future {
108 let context = A::default().push(XSpanIdString::get_or_generate(&req));
109 let (head, body) = req.into_parts();
110 let headers = head.headers.clone();
111
112
113 let context = context.push(None::<AuthData>);
114 let context = context.push(None::<Authorization>);
115 let body = ContextualPayload {
116 inner: body,
117 context: context,
118 };
119
120 Box::new(self.inner.call(hyper::Request::from_parts(head, body)))
121 }
122}