1use std::{
6 cell::{Cell, RefCell},
7 rc::Rc,
8};
9
10use crate::{
11 context,
12 extract::{
13 context::FilterContext, extractability, AlreadyExtracted, Exclusive, FromContext,
14 FromContextOnce,
15 },
16 BoxFuture,
17};
18
19use super::{
20 dynamic_exchange::DynamicExchange, entity::EntityState, request::InvalidRequestState,
21 response::InvalidResponseState, IntoBodyState, RequestBodyState, RequestData,
22 RequestHeadersState, RequestState, ResponseBodyState, ResponseHeadersState, ResponseState,
23};
24
25use super::{IntoBodyStreamState, RequestBodyStreamState, ResponseBodyStreamState};
26
27pub struct RequestContext {
28 parent: Rc<FilterContext>,
29 exchange: Rc<RefCell<DynamicExchange>>,
30}
31
32impl RequestContext {
33 pub(super) fn new(parent: Rc<FilterContext>, exchange: Rc<RefCell<DynamicExchange>>) -> Self {
34 Self { parent, exchange }
35 }
36
37 fn parent(&self) -> &FilterContext {
38 &self.parent
39 }
40}
41
42context!(RequestContext => FilterContext {RequestContext::parent});
43
44impl FromContextOnce<RequestContext> for RequestState {
45 type Error = InvalidRequestState;
46
47 type Future<'c> = BoxFuture<'c, Result<Self, Self::Error>>;
48
49 fn from_context_once(context: Exclusive<RequestContext>) -> Self::Future<'_> {
50 Box::pin(RequestState::new(context.exchange.clone()))
51 }
52}
53
54impl FromContextOnce<RequestContext> for RequestHeadersState {
55 type Error = InvalidRequestState;
56
57 type Future<'c> = BoxFuture<'c, Result<Self, Self::Error>>;
58
59 fn from_context_once(context: Exclusive<RequestContext>) -> Self::Future<'_> {
60 Box::pin(async {
61 Ok(RequestState::from_context_once(context)
62 .await?
63 .into_headers_state()
64 .await)
65 })
66 }
67}
68
69impl FromContextOnce<RequestContext> for RequestBodyState {
70 type Error = InvalidRequestState;
71
72 type Future<'c> = BoxFuture<'c, Result<Self, Self::Error>>;
73
74 fn from_context_once(context: Exclusive<RequestContext>) -> Self::Future<'_> {
75 Box::pin(async {
76 Ok(RequestState::from_context_once(context)
77 .await?
78 .into_body_state()
79 .await)
80 })
81 }
82}
83
84impl FromContextOnce<RequestContext> for RequestBodyStreamState {
85 type Error = InvalidRequestState;
86
87 type Future<'c> = BoxFuture<'c, Result<Self, Self::Error>>;
88
89 fn from_context_once(context: Exclusive<RequestContext>) -> Self::Future<'_> {
90 Box::pin(async {
91 Ok(RequestState::from_context_once(context)
92 .await?
93 .into_body_stream_state()
94 .await)
95 })
96 }
97}
98
99pub struct ResponseContext<D> {
100 parent: Rc<FilterContext>,
101 exchange: Rc<RefCell<DynamicExchange>>,
102 request_data: Cell<Option<RequestData<D>>>,
103}
104
105impl<D> ResponseContext<D> {
106 pub(super) fn new(
107 parent: Rc<FilterContext>,
108 exchange: Rc<RefCell<DynamicExchange>>,
109 request_data: RequestData<D>,
110 ) -> Self {
111 Self {
112 parent,
113 exchange,
114 request_data: Cell::new(Some(request_data)),
115 }
116 }
117
118 fn parent(&self) -> &FilterContext {
119 &self.parent
120 }
121}
122
123context!(<D> ResponseContext<D> => FilterContext {ResponseContext::parent});
124
125impl<D> FromContextOnce<ResponseContext<D>> for ResponseState {
126 type Error = InvalidResponseState;
127
128 type Future<'c>
129 = BoxFuture<'c, Result<Self, Self::Error>>
130 where
131 D: 'c;
132
133 fn from_context_once(context: Exclusive<ResponseContext<D>>) -> Self::Future<'_> {
134 Box::pin(ResponseState::new(context.exchange.clone()))
135 }
136}
137
138impl<D> FromContextOnce<ResponseContext<D>> for ResponseHeadersState {
139 type Error = InvalidResponseState;
140
141 type Future<'c>
142 = BoxFuture<'c, Result<Self, Self::Error>>
143 where
144 D: 'c;
145
146 fn from_context_once(context: Exclusive<ResponseContext<D>>) -> Self::Future<'_> {
147 Box::pin(async {
148 Ok(ResponseState::from_context_once(context)
149 .await?
150 .into_headers_state()
151 .await)
152 })
153 }
154}
155
156impl<D> FromContextOnce<ResponseContext<D>> for ResponseBodyState {
157 type Error = InvalidResponseState;
158
159 type Future<'c>
160 = BoxFuture<'c, Result<Self, Self::Error>>
161 where
162 D: 'c;
163
164 fn from_context_once(context: Exclusive<ResponseContext<D>>) -> Self::Future<'_> {
165 Box::pin(async {
166 Ok(ResponseState::from_context_once(context)
167 .await?
168 .into_body_state()
169 .await)
170 })
171 }
172}
173
174impl<D> FromContextOnce<ResponseContext<D>> for ResponseBodyStreamState {
175 type Error = InvalidResponseState;
176
177 type Future<'c>
178 = BoxFuture<'c, Result<Self, Self::Error>>
179 where
180 D: 'c;
181
182 fn from_context_once(context: Exclusive<ResponseContext<D>>) -> Self::Future<'_> {
183 Box::pin(async {
184 Ok(ResponseState::from_context_once(context)
185 .await?
186 .into_body_stream_state()
187 .await)
188 })
189 }
190}
191
192impl<D> FromContext<ResponseContext<D>, extractability::Transitive> for RequestData<D>
193where
194 D: 'static,
195{
196 type Error = AlreadyExtracted<RequestData<D>>;
197
198 fn from_context(context: &ResponseContext<D>) -> Result<Self, Self::Error> {
199 context
200 .request_data
201 .take()
202 .ok_or_else(AlreadyExtracted::default)
203 }
204}