/rust/registry/src/index.crates.io-1949cf8c6b5b557f/axum-0.7.9/src/handler/service.rs
Line | Count | Source |
1 | | use super::Handler; |
2 | | use crate::body::{Body, Bytes, HttpBody}; |
3 | | #[cfg(feature = "tokio")] |
4 | | use crate::extract::connect_info::IntoMakeServiceWithConnectInfo; |
5 | | use crate::response::Response; |
6 | | use crate::routing::IntoMakeService; |
7 | | use crate::BoxError; |
8 | | use http::Request; |
9 | | use std::{ |
10 | | convert::Infallible, |
11 | | fmt, |
12 | | marker::PhantomData, |
13 | | task::{Context, Poll}, |
14 | | }; |
15 | | use tower_service::Service; |
16 | | |
17 | | /// An adapter that makes a [`Handler`] into a [`Service`]. |
18 | | /// |
19 | | /// Created with [`Handler::with_state`] or [`HandlerWithoutStateExt::into_service`]. |
20 | | /// |
21 | | /// [`HandlerWithoutStateExt::into_service`]: super::HandlerWithoutStateExt::into_service |
22 | | pub struct HandlerService<H, T, S> { |
23 | | handler: H, |
24 | | state: S, |
25 | | _marker: PhantomData<fn() -> T>, |
26 | | } |
27 | | |
28 | | impl<H, T, S> HandlerService<H, T, S> { |
29 | | /// Get a reference to the state. |
30 | 0 | pub fn state(&self) -> &S { |
31 | 0 | &self.state |
32 | 0 | } |
33 | | |
34 | | /// Convert the handler into a [`MakeService`]. |
35 | | /// |
36 | | /// This allows you to serve a single handler if you don't need any routing: |
37 | | /// |
38 | | /// ```rust |
39 | | /// use axum::{ |
40 | | /// handler::Handler, |
41 | | /// extract::State, |
42 | | /// http::{Uri, Method}, |
43 | | /// response::IntoResponse, |
44 | | /// }; |
45 | | /// use std::net::SocketAddr; |
46 | | /// |
47 | | /// #[derive(Clone)] |
48 | | /// struct AppState {} |
49 | | /// |
50 | | /// async fn handler(State(state): State<AppState>) { |
51 | | /// // ... |
52 | | /// } |
53 | | /// |
54 | | /// let app = handler.with_state(AppState {}); |
55 | | /// |
56 | | /// # async { |
57 | | /// let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); |
58 | | /// axum::serve(listener, app.into_make_service()).await.unwrap(); |
59 | | /// # }; |
60 | | /// ``` |
61 | | /// |
62 | | /// [`MakeService`]: tower::make::MakeService |
63 | 0 | pub fn into_make_service(self) -> IntoMakeService<HandlerService<H, T, S>> { |
64 | 0 | IntoMakeService::new(self) |
65 | 0 | } |
66 | | |
67 | | /// Convert the handler into a [`MakeService`] which stores information |
68 | | /// about the incoming connection. |
69 | | /// |
70 | | /// See [`Router::into_make_service_with_connect_info`] for more details. |
71 | | /// |
72 | | /// ```rust |
73 | | /// use axum::{ |
74 | | /// handler::Handler, |
75 | | /// response::IntoResponse, |
76 | | /// extract::{ConnectInfo, State}, |
77 | | /// }; |
78 | | /// use std::net::SocketAddr; |
79 | | /// |
80 | | /// #[derive(Clone)] |
81 | | /// struct AppState {}; |
82 | | /// |
83 | | /// async fn handler( |
84 | | /// ConnectInfo(addr): ConnectInfo<SocketAddr>, |
85 | | /// State(state): State<AppState>, |
86 | | /// ) -> String { |
87 | | /// format!("Hello {addr}") |
88 | | /// } |
89 | | /// |
90 | | /// let app = handler.with_state(AppState {}); |
91 | | /// |
92 | | /// # async { |
93 | | /// let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); |
94 | | /// axum::serve( |
95 | | /// listener, |
96 | | /// app.into_make_service_with_connect_info::<SocketAddr>(), |
97 | | /// ).await.unwrap(); |
98 | | /// # }; |
99 | | /// ``` |
100 | | /// |
101 | | /// [`MakeService`]: tower::make::MakeService |
102 | | /// [`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info |
103 | | #[cfg(feature = "tokio")] |
104 | | pub fn into_make_service_with_connect_info<C>( |
105 | | self, |
106 | | ) -> IntoMakeServiceWithConnectInfo<HandlerService<H, T, S>, C> { |
107 | | IntoMakeServiceWithConnectInfo::new(self) |
108 | | } |
109 | | } |
110 | | |
111 | | #[test] |
112 | | fn traits() { |
113 | | use crate::test_helpers::*; |
114 | | assert_send::<HandlerService<(), NotSendSync, ()>>(); |
115 | | assert_sync::<HandlerService<(), NotSendSync, ()>>(); |
116 | | } |
117 | | |
118 | | impl<H, T, S> HandlerService<H, T, S> { |
119 | 0 | pub(super) fn new(handler: H, state: S) -> Self { |
120 | 0 | Self { |
121 | 0 | handler, |
122 | 0 | state, |
123 | 0 | _marker: PhantomData, |
124 | 0 | } |
125 | 0 | } Unexecuted instantiation: <axum::handler::service::HandlerService<tonic::service::router::unimplemented, ((),), ()>>::new Unexecuted instantiation: <axum::handler::service::HandlerService<_, _, _>>::new |
126 | | } |
127 | | |
128 | | impl<H, T, S> fmt::Debug for HandlerService<H, T, S> { |
129 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
130 | 0 | f.debug_struct("IntoService").finish_non_exhaustive() |
131 | 0 | } |
132 | | } |
133 | | |
134 | | impl<H, T, S> Clone for HandlerService<H, T, S> |
135 | | where |
136 | | H: Clone, |
137 | | S: Clone, |
138 | | { |
139 | 0 | fn clone(&self) -> Self { |
140 | 0 | Self { |
141 | 0 | handler: self.handler.clone(), |
142 | 0 | state: self.state.clone(), |
143 | 0 | _marker: PhantomData, |
144 | 0 | } |
145 | 0 | } Unexecuted instantiation: <axum::handler::service::HandlerService<tonic::service::router::unimplemented, ((),), ()> as core::clone::Clone>::clone Unexecuted instantiation: <axum::handler::service::HandlerService<_, _, _> as core::clone::Clone>::clone |
146 | | } |
147 | | |
148 | | impl<H, T, S, B> Service<Request<B>> for HandlerService<H, T, S> |
149 | | where |
150 | | H: Handler<T, S> + Clone + Send + 'static, |
151 | | B: HttpBody<Data = Bytes> + Send + 'static, |
152 | | B::Error: Into<BoxError>, |
153 | | S: Clone + Send + Sync, |
154 | | { |
155 | | type Response = Response; |
156 | | type Error = Infallible; |
157 | | type Future = super::future::IntoServiceFuture<H::Future>; |
158 | | |
159 | | #[inline] |
160 | 0 | fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { |
161 | | // `IntoService` can only be constructed from async functions which are always ready, or |
162 | | // from `Layered` which buffers in `<Layered as Handler>::call` and is therefore |
163 | | // also always ready. |
164 | 0 | Poll::Ready(Ok(())) |
165 | 0 | } Unexecuted instantiation: <axum::handler::service::HandlerService<tonic::service::router::unimplemented, ((),), ()> as tower_service::Service<http::request::Request<axum_core::body::Body>>>::poll_ready Unexecuted instantiation: <axum::handler::service::HandlerService<_, _, _> as tower_service::Service<http::request::Request<_>>>::poll_ready |
166 | | |
167 | 0 | fn call(&mut self, req: Request<B>) -> Self::Future { |
168 | | use futures_util::future::FutureExt; |
169 | | |
170 | 0 | let req = req.map(Body::new); |
171 | | |
172 | 0 | let handler = self.handler.clone(); |
173 | 0 | let future = Handler::call(handler, req, self.state.clone()); |
174 | 0 | let future = future.map(Ok as _); |
175 | | |
176 | 0 | super::future::IntoServiceFuture::new(future) |
177 | 0 | } Unexecuted instantiation: <axum::handler::service::HandlerService<tonic::service::router::unimplemented, ((),), ()> as tower_service::Service<http::request::Request<axum_core::body::Body>>>::call Unexecuted instantiation: <axum::handler::service::HandlerService<_, _, _> as tower_service::Service<http::request::Request<_>>>::call |
178 | | } |
179 | | |
180 | | // for `axum::serve(listener, handler)` |
181 | | #[cfg(all(feature = "tokio", any(feature = "http1", feature = "http2")))] |
182 | | const _: () = { |
183 | | use crate::serve::IncomingStream; |
184 | | |
185 | | impl<H, T, S> Service<IncomingStream<'_>> for HandlerService<H, T, S> |
186 | | where |
187 | | H: Clone, |
188 | | S: Clone, |
189 | | { |
190 | | type Response = Self; |
191 | | type Error = Infallible; |
192 | | type Future = std::future::Ready<Result<Self::Response, Self::Error>>; |
193 | | |
194 | | fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { |
195 | | Poll::Ready(Ok(())) |
196 | | } |
197 | | |
198 | | fn call(&mut self, _req: IncomingStream<'_>) -> Self::Future { |
199 | | std::future::ready(Ok(self.clone())) |
200 | | } |
201 | | } |
202 | | }; |