1use crate::{Status, body::Body, server::NamedService};
26use http::{Request, Response};
27use std::{
28 convert::Infallible,
29 fmt,
30 future::Future,
31 pin::Pin,
32 task::{Context, Poll},
33};
34use tower::{Service, ServiceExt};
35
36#[derive(Debug, Clone)]
38pub struct Routes {
39 router: axum::Router,
40}
41
42#[derive(Debug, Default, Clone)]
43pub struct RoutesBuilder {
45 routes: Option<Routes>,
46}
47
48impl RoutesBuilder {
49 pub fn add_service<S>(&mut self, svc: S) -> &mut Self
51 where
52 S: Service<Request<Body>, Error = Infallible>
53 + NamedService
54 + Clone
55 + Send
56 + Sync
57 + 'static,
58 S::Response: axum::response::IntoResponse,
59 S::Future: Send + 'static,
60 {
61 let routes = self.routes.take().unwrap_or_default();
62 self.routes.replace(routes.add_service(svc));
63 self
64 }
65
66 pub fn routes(self) -> Routes {
68 self.routes.unwrap_or_default()
69 }
70}
71
72impl Default for Routes {
73 fn default() -> Self {
74 Self {
75 router: axum::Router::new().fallback(unimplemented),
76 }
77 }
78}
79
80impl Routes {
81 pub fn new<S>(svc: S) -> Self
83 where
84 S: Service<Request<Body>, Error = Infallible>
85 + NamedService
86 + Clone
87 + Send
88 + Sync
89 + 'static,
90 S::Response: axum::response::IntoResponse,
91 S::Future: Send + 'static,
92 {
93 Self::default().add_service(svc)
94 }
95
96 pub fn builder() -> RoutesBuilder {
98 RoutesBuilder::default()
99 }
100
101 pub fn add_service<S>(mut self, svc: S) -> Self
103 where
104 S: Service<Request<Body>, Error = Infallible>
105 + NamedService
106 + Clone
107 + Send
108 + Sync
109 + 'static,
110 S::Response: axum::response::IntoResponse,
111 S::Future: Send + 'static,
112 {
113 self.router = self.router.route_service(
114 &format!("/{}/{{*rest}}", S::NAME),
115 svc.map_request(|req: Request<axum::body::Body>| req.map(Body::new)),
116 );
117 self
118 }
119
120 pub fn prepare(self) -> Self {
124 Self {
125 router: self.router.with_state(()),
126 }
127 }
128
129 pub fn into_axum_router(self) -> axum::Router {
131 self.router
132 }
133
134 pub fn axum_router_mut(&mut self) -> &mut axum::Router {
136 &mut self.router
137 }
138}
139
140impl From<Routes> for RoutesBuilder {
141 fn from(routes: Routes) -> Self {
142 Self {
143 routes: Some(routes),
144 }
145 }
146}
147
148impl From<axum::Router> for RoutesBuilder {
149 fn from(router: axum::Router) -> Self {
150 Self {
151 routes: Some(router.into()),
152 }
153 }
154}
155
156impl From<axum::Router> for Routes {
157 fn from(router: axum::Router) -> Self {
158 Self { router }
159 }
160}
161
162async fn unimplemented() -> Response<Body> {
163 let (parts, ()) = Status::unimplemented("").into_http::<()>().into_parts();
164 Response::from_parts(parts, Body::empty())
165}
166
167impl<B> Service<Request<B>> for Routes
168where
169 B: http_body::Body<Data = bytes::Bytes> + Send + 'static,
170 B::Error: Into<crate::BoxError>,
171{
172 type Response = Response<Body>;
173 type Error = Infallible;
174 type Future = RoutesFuture;
175
176 #[inline]
177 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
178 Service::<Request<B>>::poll_ready(&mut self.router, cx)
179 }
180
181 fn call(&mut self, req: Request<B>) -> Self::Future {
182 RoutesFuture(self.router.call(req))
183 }
184}
185
186pub struct RoutesFuture(axum::routing::future::RouteFuture<Infallible>);
187
188impl fmt::Debug for RoutesFuture {
189 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
190 f.debug_tuple("RoutesFuture").finish()
191 }
192}
193
194impl Future for RoutesFuture {
195 type Output = Result<Response<Body>, Infallible>;
196
197 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
198 Pin::new(&mut self.as_mut().0)
199 .poll(cx)
200 .map_ok(|res| res.map(Body::new))
201 }
202}