1use std::marker::PhantomData;
9use std::sync::Arc;
10use std::task::{Context, Poll};
11
12use http::{Request, Response};
13use paste::paste;
14use tower_service::Service;
15
16use super::Handler;
17use crate::macros::all_events;
18use crate::{Error, Event, RequestParser};
19
20mod future;
21
22#[allow(clippy::module_name_repetitions)]
23pub use future::{HandlerCall, WrapErrorFuture};
24
25#[must_use]
30#[derive(Debug, Clone, Copy)]
31pub struct Sink {
32 _priv: PhantomData<()>,
34}
35
36impl Sink {
37 fn new() -> Self {
38 Self { _priv: PhantomData }
39 }
40}
41
42impl<T> Service<T> for Sink {
43 type Response = ();
44 type Error = Error;
45 type Future = futures_util::future::Ready<Result<(), Error>>;
46
47 fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
48 Poll::Ready(Ok(()))
49 }
50
51 #[inline]
52 fn call(&mut self, _request: T) -> Self::Future {
53 futures_util::future::ready(Ok(()))
54 }
55}
56
57#[must_use]
64#[derive(Debug, Clone)]
65pub struct WithState<State, Service> {
66 state: Arc<State>,
67 service: Service,
68}
69
70impl<State, Srv> WithState<State, Srv> {
71 fn new(state: State, service: Srv) -> Self {
72 let state = Arc::new(state);
73 Self { state, service }
74 }
75
76 fn clone_state(&self) -> State
77 where
78 State: Clone,
79 {
80 State::clone(&*self.state)
81 }
82}
83
84impl<State, Srv> Service<Event> for WithState<State, Srv>
85where
86 Srv: Service<(State, Event)>,
87 State: Clone,
88{
89 type Response = Srv::Response;
90 type Error = Srv::Error;
91 type Future = Srv::Future;
92
93 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
94 self.service.poll_ready(cx)
95 }
96
97 #[inline]
98 fn call(&mut self, request: Event) -> Self::Future {
99 self.service.call((self.clone_state(), request))
100 }
101}
102
103impl<OState, State, Srv> Service<(OState, Event)> for WithState<State, Srv>
104where
105 Srv: Service<(State, Event)>,
106 State: Clone,
107{
108 type Response = Srv::Response;
109 type Error = Srv::Error;
110 type Future = Srv::Future;
111
112 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
113 self.service.poll_ready(cx)
114 }
115
116 #[inline]
117 fn call(&mut self, (_, request): (OState, Event)) -> Self::Future {
118 self.service.call((self.clone_state(), request))
119 }
120}
121
122macro_rules! all_event_service {
123 (
124 $( $e:ident ),*
125 ) => {
126 $( $crate::macros::event_service! {
127 #[doc = paste! { concat!(
128 "[`", stringify!([< $e:camel Payload >]), "`]をhandleする[`Service`]です。\n\n",
129 "[`Service`]: tower::Service\n",
130 "[`", stringify!([< $e:camel Payload >]), "`]: ",
131 "crate::payloads::", stringify!([< $e:camel Payload >]),
132 )}]
133 #[must_use]
134 #[derive(Debug, Clone)]
135 pub $e
136 } )*
137 };
138}
139
140all_events! {all_event_service}
141
142impl<Service> Handler<Service> {
143 fn new(parser: crate::RequestParser, service: Service) -> Self {
157 Self { service, parser }
158 }
159
160 pub fn with_state<State>(self, state: State) -> Handler<WithState<State, Service>> {
190 let Self { service, parser } = self;
191 Handler {
192 service: WithState::new(state, service),
193 parser,
194 }
195 }
196}
197
198impl RequestParser {
199 pub fn into_handler(self) -> Handler<Sink> {
203 Handler::new(self, Sink::new())
204 }
205}
206
207macro_rules! all_handler_on_events {
208 (
209 $( $e:ident ),*
210 ) => {
211 $crate::macros::handler_on_events! { $(
212 #[doc = paste! { concat!(
213 "[`", stringify!([< $e:camel Payload >]), "`]をhandleする[`Service`]を登録します。\n\n",
214 "引数の型`Service2`は`Service<Req>` traitを実装し、さらに以下の条件を満たす必要があります。\n\n",
215 "- [`Clone`]を実装している\n",
216 "- `Req`が次のうちいずれかと等しい\n",
217 " - [`", stringify!([< $e:camel Payload >]), "`]\n",
218 " - `(State, ", stringify!([< $e:camel Payload >]), ")` ",
219 "(`State`に関しては[`Handler::with_state`]を参照してください)\n",
220 "- `Service2::Response`が`()`と等しい\n",
221 "- `Service2::Error`が<code>Into<Box<dyn [Error] + [Send] + [Sync] + 'static>></code>を実装している\n\n",
222 "[`Service`]: tower::Service\n",
223 "[`", stringify!([< $e:camel Payload >]), "`]: ",
224 "crate::payloads::", stringify!([< $e:camel Payload >]), "\n",
225 "[`Clone`]: std::clone::Clone\n",
226 "[`Handler::with_state`]: crate::Handler::with_state\n",
227 "[Error]: std::error::Error\n",
228 "[Send]: std::marker::Send\n",
229 "[Sync]: std::marker::Sync\n",
230 ) } ]
231 pub $e;
232 )* }
233 };
234}
235
236all_events! {all_handler_on_events}
237
238impl<Srv, Body> Service<Request<Body>> for Handler<Srv>
239where
240 Srv: Service<Event, Response = (), Error = Error>,
241 Srv: Clone,
242 Body: http_body::Body,
243 Body::Error: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
244{
245 type Response = Response<String>;
246 type Error = Error;
247 type Future = HandlerCall<Body, Srv>;
248
249 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
250 self.service.poll_ready(cx).map_err(Error::handler)
251 }
252
253 fn call(&mut self, req: Request<Body>) -> Self::Future {
254 let parse_request = self.parser.parse_request(req);
255 let mut s = self.service.clone();
256 std::mem::swap(&mut self.service, &mut s);
258 HandlerCall::new(parse_request, s)
259 }
260}