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