1use std::{convert::Infallible, fmt};
2
3use crate::extract::Request;
4use crate::util::AxumMutex;
5use tower::Service;
6
7use crate::{
8 handler::Handler,
9 routing::{future::RouteFuture, Route},
10 Router,
11};
12
13pub(crate) struct BoxedIntoRoute<S, E>(AxumMutex<Box<dyn ErasedIntoRoute<S, E>>>);
14
15impl<S> BoxedIntoRoute<S, Infallible>
16where
17 S: Clone + Send + Sync + 'static,
18{
19 pub(crate) fn from_handler<H, T>(handler: H) -> Self
20 where
21 H: Handler<T, S>,
22 T: 'static,
23 {
24 Self(AxumMutex::new(Box::new(MakeErasedHandler {
25 handler,
26 into_route: |handler, state| Route::new(Handler::with_state(handler, state)),
27 })))
28 }
29}
30
31impl<S, E> BoxedIntoRoute<S, E> {
32 pub(crate) fn map<F, E2>(self, f: F) -> BoxedIntoRoute<S, E2>
33 where
34 S: 'static,
35 E: 'static,
36 F: FnOnce(Route<E>) -> Route<E2> + Clone + Send + 'static,
37 E2: 'static,
38 {
39 BoxedIntoRoute(AxumMutex::new(Box::new(Map {
40 inner: self.0.into_inner().unwrap(),
41 layer: Box::new(f),
42 })))
43 }
44
45 pub(crate) fn into_route(self, state: S) -> Route<E> {
46 self.0.into_inner().unwrap().into_route(state)
47 }
48}
49
50impl<S, E> Clone for BoxedIntoRoute<S, E> {
51 fn clone(&self) -> Self {
52 Self(AxumMutex::new(self.0.lock().unwrap().clone_box()))
53 }
54}
55
56impl<S, E> fmt::Debug for BoxedIntoRoute<S, E> {
57 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58 f.debug_tuple("BoxedIntoRoute").finish()
59 }
60}
61
62pub(crate) trait ErasedIntoRoute<S, E>: Send {
63 fn clone_box(&self) -> Box<dyn ErasedIntoRoute<S, E>>;
64
65 fn into_route(self: Box<Self>, state: S) -> Route<E>;
66
67 #[allow(dead_code)]
68 fn call_with_state(self: Box<Self>, request: Request, state: S) -> RouteFuture<E>;
69}
70
71pub(crate) struct MakeErasedHandler<H, S> {
72 pub(crate) handler: H,
73 pub(crate) into_route: fn(H, S) -> Route,
74}
75
76impl<H, S> ErasedIntoRoute<S, Infallible> for MakeErasedHandler<H, S>
77where
78 H: Clone + Send + 'static,
79 S: 'static,
80{
81 fn clone_box(&self) -> Box<dyn ErasedIntoRoute<S, Infallible>> {
82 Box::new(self.clone())
83 }
84
85 fn into_route(self: Box<Self>, state: S) -> Route {
86 (self.into_route)(self.handler, state)
87 }
88
89 fn call_with_state(self: Box<Self>, request: Request, state: S) -> RouteFuture<Infallible> {
90 self.into_route(state).call(request)
91 }
92}
93
94impl<H, S> Clone for MakeErasedHandler<H, S>
95where
96 H: Clone,
97{
98 fn clone(&self) -> Self {
99 Self {
100 handler: self.handler.clone(),
101 into_route: self.into_route,
102 }
103 }
104}
105
106#[allow(dead_code)]
107pub(crate) struct MakeErasedRouter<S> {
108 pub(crate) router: Router<S>,
109 pub(crate) into_route: fn(Router<S>, S) -> Route,
110}
111
112impl<S> ErasedIntoRoute<S, Infallible> for MakeErasedRouter<S>
113where
114 S: Clone + Send + Sync + 'static,
115{
116 fn clone_box(&self) -> Box<dyn ErasedIntoRoute<S, Infallible>> {
117 Box::new(self.clone())
118 }
119
120 fn into_route(self: Box<Self>, state: S) -> Route {
121 (self.into_route)(self.router, state)
122 }
123
124 fn call_with_state(self: Box<Self>, request: Request, state: S) -> RouteFuture<Infallible> {
125 self.router.call_with_state(request, state)
126 }
127}
128
129impl<S> Clone for MakeErasedRouter<S>
130where
131 S: Clone,
132{
133 fn clone(&self) -> Self {
134 Self {
135 router: self.router.clone(),
136 into_route: self.into_route,
137 }
138 }
139}
140
141pub(crate) struct Map<S, E, E2> {
142 pub(crate) inner: Box<dyn ErasedIntoRoute<S, E>>,
143 pub(crate) layer: Box<dyn LayerFn<E, E2>>,
144}
145
146impl<S, E, E2> ErasedIntoRoute<S, E2> for Map<S, E, E2>
147where
148 S: 'static,
149 E: 'static,
150 E2: 'static,
151{
152 fn clone_box(&self) -> Box<dyn ErasedIntoRoute<S, E2>> {
153 Box::new(Self {
154 inner: self.inner.clone_box(),
155 layer: self.layer.clone_box(),
156 })
157 }
158
159 fn into_route(self: Box<Self>, state: S) -> Route<E2> {
160 (self.layer)(self.inner.into_route(state))
161 }
162
163 fn call_with_state(self: Box<Self>, request: Request, state: S) -> RouteFuture<E2> {
164 (self.layer)(self.inner.into_route(state)).call(request)
165 }
166}
167
168pub(crate) trait LayerFn<E, E2>: FnOnce(Route<E>) -> Route<E2> + Send {
169 fn clone_box(&self) -> Box<dyn LayerFn<E, E2>>;
170}
171
172impl<F, E, E2> LayerFn<E, E2> for F
173where
174 F: FnOnce(Route<E>) -> Route<E2> + Clone + Send + 'static,
175{
176 fn clone_box(&self) -> Box<dyn LayerFn<E, E2>> {
177 Box::new(self.clone())
178 }
179}