7
7
8
8
use std:: convert:: Infallible ;
9
9
use std:: marker:: PhantomData ;
10
- use std:: pin:: Pin ;
11
10
use std:: task:: { Context , Poll } ;
12
11
13
- use futures:: future:: { BoxFuture , Ready as ReadyFuture } ;
14
- use futures:: ready;
15
- use http:: { Request , Response , StatusCode } ;
12
+ use futures:: future:: Ready as ReadyFuture ;
13
+ use http:: { Request , Response } ;
16
14
use paste:: paste;
17
15
use tower:: Service ;
18
16
19
17
use super :: Handler ;
20
18
use crate :: macros:: all_events;
21
19
use crate :: { Error , Event , RequestParser } ;
22
20
23
- pin_project_lite:: pin_project! {
24
- /// <code>impl Future<Output = Result<(), [Error]>></code>
25
- ///
26
- /// `F: Future<Output = Result<(), E>>`を受け取り、エラー型`E`を[`Error`]に変換した[`Future`]を返します。
27
- /// 以下のコードと同様です。
28
- ///
29
- /// ```ignore
30
- /// use futures::{TryFutureExt};
31
- ///
32
- /// async fn f() -> Result<(), E> { ... }
33
- ///
34
- /// let wrap_error = f().map_err(|e| -> traq_bot_http::Error { ... });
35
- /// ```
36
- ///
37
- /// [`Future`]: std::future::Future
38
- /// [`Error`]: crate::Error
39
- #[ must_use]
40
- #[ project = WrapErrorFutureProject ]
41
- #[ derive( Debug ) ]
42
- pub struct WrapErrorFuture <F , E > {
43
- _error: PhantomData <E >,
44
- #[ pin]
45
- inner: F ,
46
- }
47
- }
48
-
49
- impl < F , E > std:: future:: Future for WrapErrorFuture < F , E >
50
- where
51
- F : std:: future:: Future < Output = Result < ( ) , E > > ,
52
- E : Into < Box < dyn std:: error:: Error + Send + Sync + ' static > > ,
53
- {
54
- type Output = crate :: error:: Result < ( ) > ;
21
+ mod future;
55
22
56
- fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
57
- let s = self . project ( ) ;
58
- let res = ready ! ( s. inner. poll( cx) ) ;
59
- Poll :: Ready ( res. map_err ( Error :: handler) )
60
- }
61
- }
23
+ #[ allow( clippy:: module_name_repetitions) ]
24
+ pub use future:: { HandlerCall , WrapErrorFuture } ;
62
25
63
26
/// handleされなかった[`Event`]の受け皿となる[`Service`]です。
64
27
///
@@ -195,27 +158,22 @@ impl<Service> Handler<Service> {
195
158
/// 新しくイベントハンドラを作成します。`service`は以下の条件を満たす必要があります。
196
159
///
197
160
/// - <code>[Service]<[Event]></code>, [`Clone`]を実装している
198
- /// - [`'static`]
199
161
/// - `Service::Response`が`()`と等しい
200
162
/// - `Service::Error`が<code>Into<Box<dyn [Error] + [Send] + [Sync] + 'static>></code>を実装している
201
- /// - `Service::Future`が[`Send`]を実装している
202
163
///
203
164
/// [Service]: tower::Service
204
165
/// [Event]: crate::Event
205
166
/// [`Clone`]: std::clone::Clone
206
- /// [`'static`]: https://doc.rust-lang.org/rust-by-example/scope/lifetime/static_lifetime.html#trait-bound
207
167
/// [Error]: std::error::Error
208
168
/// [Send]: std::marker::Send
209
169
/// [Sync]: std::marker::Sync
210
- /// [`Send`]: std::marker::Send
211
170
pub fn new ( parser : crate :: RequestParser , service : Service ) -> Self {
212
171
Self { service, parser }
213
172
}
214
173
215
174
/// イベントハンドラに`State`を追加します。`State`は以下の条件を満たす必要があります。
216
175
///
217
- /// - [`Clone`], [`Send`]を実装している
218
- /// - [`'static`]
176
+ /// - [`Clone`]を実装している
219
177
///
220
178
/// # Example
221
179
///
@@ -241,8 +199,6 @@ impl<Service> Handler<Service> {
241
199
/// ```
242
200
///
243
201
/// [`Clone`]: std::clone::Clone
244
- /// [`Send`]: std::marker::Send
245
- /// [`'static`]: https://doc.rust-lang.org/rust-by-example/scope/lifetime/static_lifetime.html#trait-bound
246
202
pub fn with_state < State > ( self , state : State ) -> Handler < WithState < State , Service > > {
247
203
let Self { service, parser } = self ;
248
204
Handler {
@@ -269,24 +225,22 @@ macro_rules! all_handler_on_events {
269
225
#[ doc = paste! { concat!(
270
226
"[`" , stringify!( [ < $e: camel Payload >] ) , "`]をhandleする[`Service`]を登録します。\n \n " ,
271
227
"引数の型`Service2`は`Service<Req>` traitを実装し、さらに以下の条件を満たす必要があります。\n \n " ,
272
- "- [`Clone`], [`Send`]を実装している\n " ,
273
- "- [`'static`]\n " ,
228
+ "- [`Clone`]を実装している\n " ,
274
229
"- `Req`が次のうちいずれかと等しい\n " ,
275
230
" - [`" , stringify!( [ < $e: camel Payload >] ) , "`]\n " ,
276
231
" - `(" , stringify!( [ < $e: camel Payload >] ) , ",)`\n " ,
277
232
" - `(State, " , stringify!( [ < $e: camel Payload >] ) , ")` " ,
278
233
"(`State`に関しては[`Handler::with_state`]を参照してください)\n " ,
279
234
"- `Service2::Response`が`()`と等しい\n " ,
280
- "- `Service2::Error`が<code>Into<Box<dyn [Error] + Send + Sync + 'static>></code>を実装している\n " ,
281
- "- `Service2::Future`が[`Send`]を実装している\n \n " ,
235
+ "- `Service2::Error`が<code>Into<Box<dyn [Error] + [Send] + [Sync] + 'static>></code>を実装している\n \n " ,
282
236
"[`Service`]: tower::Service\n " ,
283
237
"[`" , stringify!( [ < $e: camel Payload >] ) , "`]: " ,
284
238
"crate::payloads::" , stringify!( [ < $e: camel Payload >] ) , "\n " ,
285
239
"[`Clone`]: std::clone::Clone\n " ,
286
- "[`Send`]: std::marker::Send\n " ,
287
- "[`'static`]: https://doc.rust-lang.org/rust-by-example/scope/lifetime/static_lifetime.html#trait-bound\n " ,
288
240
"[`Handler::with_state`]: crate::Handler::with_state\n " ,
289
241
"[Error]: std::error::Error\n " ,
242
+ "[Send]: std::marker::Send\n " ,
243
+ "[Sync]: std::marker::Sync\n " ,
290
244
) } ]
291
245
pub $e;
292
246
) * }
@@ -297,35 +251,25 @@ all_events! {all_handler_on_events}
297
251
298
252
impl < Srv , Body > Service < Request < Body > > for Handler < Srv >
299
253
where
300
- Srv : Service < Event , Response = ( ) > + Send + ' static ,
254
+ Srv : Service < Event , Response = ( ) > ,
301
255
Srv : Clone ,
302
256
Srv :: Error : Into < Box < dyn std:: error:: Error + Send + Sync + ' static > > ,
303
- Srv :: Future : Send ,
304
- Body : http_body:: Body + Send + ' static ,
305
- Body :: Data : Send ,
257
+ Body : http_body:: Body ,
306
258
Body :: Error : Into < Box < dyn std:: error:: Error + Send + Sync + ' static > > ,
307
259
{
308
260
type Response = Response < String > ;
309
261
type Error = Error ;
310
- type Future = BoxFuture < ' static , Result < Self :: Response , Self :: Error > > ;
262
+ type Future = HandlerCall < Body , Srv > ;
311
263
312
264
fn poll_ready ( & mut self , cx : & mut Context < ' _ > ) -> Poll < Result < ( ) , Self :: Error > > {
313
265
self . service . poll_ready ( cx) . map_err ( Error :: handler)
314
266
}
315
267
316
268
fn call ( & mut self , req : Request < Body > ) -> Self :: Future {
317
- // FIXME: このclone消せる
318
- // req.parts.headersからEventKindはasyncなしに判定できるので
319
- let mut s = self . clone ( ) ;
269
+ let parse_request = self . parser . parse_request ( req) ;
270
+ let mut s = self . service . clone ( ) ;
320
271
// https://docs.rs/tower/latest/tower/trait.Service.html#be-careful-when-cloning-inner-services
321
- std:: mem:: swap ( self , & mut s) ;
322
- Box :: pin ( async move {
323
- let event = s. parser . parse_request ( req) . await ?;
324
- s. service . call ( event) . await . map_err ( Error :: handler) ?;
325
- Response :: builder ( )
326
- . status ( StatusCode :: NO_CONTENT )
327
- . body ( String :: new ( ) )
328
- . map_err ( Error :: handler)
329
- } )
272
+ std:: mem:: swap ( & mut self . service , & mut s) ;
273
+ HandlerCall :: new ( parse_request, s)
330
274
}
331
275
}
0 commit comments