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<S = ()> {
28 parent: Rc<FilterContext>,
29 exchange: Rc<RefCell<DynamicExchange>>,
30 state: Rc<S>,
31}
32
33impl<S> RequestContext<S> {
34 pub(super) fn new(
35 parent: Rc<FilterContext>,
36 exchange: Rc<RefCell<DynamicExchange>>,
37 state: Rc<S>,
38 ) -> Self {
39 Self {
40 parent,
41 exchange,
42 state,
43 }
44 }
45
46 pub(super) fn state(&self) -> &Rc<S> {
47 &self.state
48 }
49
50 fn parent(&self) -> &FilterContext {
51 &self.parent
52 }
53}
54
55context!(<S> RequestContext<S> => FilterContext {RequestContext::parent});
56
57impl<S> FromContextOnce<RequestContext<S>> for RequestState {
58 type Error = InvalidRequestState;
59
60 type Future<'c>
61 = BoxFuture<'c, Result<Self, Self::Error>>
62 where
63 S: 'c;
64
65 fn from_context_once(context: Exclusive<RequestContext<S>>) -> Self::Future<'_> {
66 Box::pin(RequestState::new(context.exchange.clone()))
67 }
68}
69
70impl<S> FromContextOnce<RequestContext<S>> for RequestHeadersState {
71 type Error = InvalidRequestState;
72
73 type Future<'c>
74 = BoxFuture<'c, Result<Self, Self::Error>>
75 where
76 S: 'c;
77
78 fn from_context_once(context: Exclusive<RequestContext<S>>) -> Self::Future<'_> {
79 Box::pin(async {
80 Ok(RequestState::from_context_once(context)
81 .await?
82 .into_headers_state()
83 .await)
84 })
85 }
86}
87
88impl<S> FromContextOnce<RequestContext<S>> for RequestBodyState {
89 type Error = InvalidRequestState;
90
91 type Future<'c>
92 = BoxFuture<'c, Result<Self, Self::Error>>
93 where
94 S: 'c;
95
96 fn from_context_once(context: Exclusive<RequestContext<S>>) -> Self::Future<'_> {
97 Box::pin(async {
98 Ok(RequestState::from_context_once(context)
99 .await?
100 .into_body_state()
101 .await)
102 })
103 }
104}
105
106impl<S> FromContextOnce<RequestContext<S>> for RequestBodyStreamState {
107 type Error = InvalidRequestState;
108
109 type Future<'c>
110 = BoxFuture<'c, Result<Self, Self::Error>>
111 where
112 S: 'c;
113
114 fn from_context_once(context: Exclusive<RequestContext<S>>) -> Self::Future<'_> {
115 Box::pin(async {
116 Ok(RequestState::from_context_once(context)
117 .await?
118 .into_body_stream_state()
119 .await)
120 })
121 }
122}
123
124pub struct ResponseContext<D, S = ()> {
125 parent: Rc<FilterContext>,
126 exchange: Rc<RefCell<DynamicExchange>>,
127 request_data: Cell<Option<RequestData<D>>>,
128 state: Rc<S>,
129}
130
131impl<D, S> ResponseContext<D, S> {
132 pub(super) fn new(
133 parent: Rc<FilterContext>,
134 exchange: Rc<RefCell<DynamicExchange>>,
135 request_data: RequestData<D>,
136 state: Rc<S>,
137 ) -> Self {
138 Self {
139 parent,
140 exchange,
141 request_data: Cell::new(Some(request_data)),
142 state,
143 }
144 }
145
146 pub(super) fn state(&self) -> &Rc<S> {
147 &self.state
148 }
149
150 fn parent(&self) -> &FilterContext {
151 &self.parent
152 }
153}
154
155context!(<D, S> ResponseContext<D, S> => FilterContext {ResponseContext::parent});
156
157impl<D, S> FromContextOnce<ResponseContext<D, S>> for ResponseState {
158 type Error = InvalidResponseState;
159
160 type Future<'c>
161 = BoxFuture<'c, Result<Self, Self::Error>>
162 where
163 D: 'c,
164 S: 'c;
165
166 fn from_context_once(context: Exclusive<ResponseContext<D, S>>) -> Self::Future<'_> {
167 Box::pin(ResponseState::new(context.exchange.clone()))
168 }
169}
170
171impl<D, S> FromContextOnce<ResponseContext<D, S>> for ResponseHeadersState {
172 type Error = InvalidResponseState;
173
174 type Future<'c>
175 = BoxFuture<'c, Result<Self, Self::Error>>
176 where
177 D: 'c,
178 S: 'c;
179
180 fn from_context_once(context: Exclusive<ResponseContext<D, S>>) -> Self::Future<'_> {
181 Box::pin(async {
182 Ok(ResponseState::from_context_once(context)
183 .await?
184 .into_headers_state()
185 .await)
186 })
187 }
188}
189
190impl<D, S> FromContextOnce<ResponseContext<D, S>> for ResponseBodyState {
191 type Error = InvalidResponseState;
192
193 type Future<'c>
194 = BoxFuture<'c, Result<Self, Self::Error>>
195 where
196 D: 'c,
197 S: 'c;
198
199 fn from_context_once(context: Exclusive<ResponseContext<D, S>>) -> Self::Future<'_> {
200 Box::pin(async {
201 Ok(ResponseState::from_context_once(context)
202 .await?
203 .into_body_state()
204 .await)
205 })
206 }
207}
208
209impl<D, S> FromContextOnce<ResponseContext<D, S>> for ResponseBodyStreamState {
210 type Error = InvalidResponseState;
211
212 type Future<'c>
213 = BoxFuture<'c, Result<Self, Self::Error>>
214 where
215 D: 'c,
216 S: 'c;
217
218 fn from_context_once(context: Exclusive<ResponseContext<D, S>>) -> Self::Future<'_> {
219 Box::pin(async {
220 Ok(ResponseState::from_context_once(context)
221 .await?
222 .into_body_stream_state()
223 .await)
224 })
225 }
226}
227
228impl<D, S> FromContext<ResponseContext<D, S>, extractability::Transitive> for RequestData<D>
229where
230 D: 'static,
231{
232 type Error = AlreadyExtracted<RequestData<D>>;
233
234 fn from_context(context: &ResponseContext<D, S>) -> Result<Self, Self::Error> {
235 context
236 .request_data
237 .take()
238 .ok_or_else(AlreadyExtracted::default)
239 }
240}