@@ -10,19 +10,24 @@ use path_table::{PathTable, RouteMatch};
10
10
/// A core type for routing.
11
11
///
12
12
/// The `Router` type can be used to set up routes and resources, and to apply middleware.
13
- pub struct Router < Data > {
13
+ pub struct BaseRouter < Data > {
14
14
table : PathTable < ResourceData < Data > > ,
15
15
middleware_base : Vec < Arc < dyn Middleware < Data > + Send + Sync > > ,
16
16
default_handler : Arc < BoxedEndpoint < Data > > ,
17
17
}
18
18
19
+ pub struct SubRouter < Data > {
20
+ table : PathTable < ResourceData < Data > > ,
21
+ middleware_base : Vec < Arc < dyn Middleware < Data > + Send + Sync > > ,
22
+ }
23
+
19
24
pub ( crate ) struct RouteResult < ' a , Data > {
20
25
pub ( crate ) endpoint : & ' a BoxedEndpoint < Data > ,
21
26
pub ( crate ) params : Option < RouteMatch < ' a > > ,
22
27
pub ( crate ) middleware : & ' a [ Arc < dyn Middleware < Data > + Send + Sync > ] ,
23
28
}
24
29
25
- pub async fn base_default_handler ( ) -> http:: status:: StatusCode {
30
+ async fn base_default_handler ( ) -> http:: status:: StatusCode {
26
31
http:: status:: StatusCode :: NOT_FOUND
27
32
}
28
33
@@ -59,23 +64,19 @@ fn route_match_failure<'a, Data>(
59
64
}
60
65
}
61
66
62
- impl < Data : Clone + Send + Sync + ' static > Router < Data > {
63
- /// Create a new top-level router.
64
- pub ( crate ) fn new ( ) -> Router < Data > {
65
- Router {
66
- table : PathTable :: new ( ) ,
67
- middleware_base : Vec :: new ( ) ,
68
- default_handler : Arc :: new ( BoxedEndpoint :: new ( base_default_handler) ) ,
69
- }
70
- }
67
+ pub trait Router < Data : Clone + Send + Sync + ' static > {
68
+ fn at < ' a > ( & ' a mut self , path : & ' a str ) -> Resource < ' a , Data > ;
69
+
70
+ fn middleware ( & mut self , middleware : impl Middleware < Data > + ' static ) -> & mut Self ;
71
+ }
71
72
73
+ impl < Data : Clone + Send + Sync + ' static > Router < Data > for BaseRouter < Data > {
72
74
/// Add a new resource at `path`, relative to this router.
73
- pub fn at < ' a > ( & ' a mut self , path : & ' a str ) -> Resource < ' a , Data > {
75
+ fn at < ' a > ( & ' a mut self , path : & ' a str ) -> Resource < ' a , Data > {
74
76
let table = self . table . setup_table ( path) ;
75
77
Resource {
76
78
table,
77
79
middleware_base : & self . middleware_base ,
78
- default_handler : & self . default_handler ,
79
80
}
80
81
}
81
82
@@ -107,14 +108,44 @@ impl<Data: Clone + Send + Sync + 'static> Router<Data> {
107
108
/// router.at("").get(async || "B then A");
108
109
/// });
109
110
/// ```
110
- pub fn middleware ( & mut self , middleware : impl Middleware < Data > + ' static ) -> & mut Self {
111
+ fn middleware ( & mut self , middleware : impl Middleware < Data > + ' static ) -> & mut Self {
112
+ let middleware = Arc :: new ( middleware) ;
113
+ for resource in self . table . iter_mut ( ) {
114
+ resource. middleware . push ( middleware. clone ( ) ) ;
115
+ }
116
+ self . middleware_base . push ( middleware) ;
117
+ self
118
+ }
119
+ }
120
+
121
+ impl < Data : Clone + Send + Sync + ' static > Router < Data > for SubRouter < Data > {
122
+ fn at < ' a > ( & ' a mut self , path : & ' a str ) -> Resource < ' a , Data > {
123
+ let table = self . table . setup_table ( path) ;
124
+ Resource {
125
+ table,
126
+ middleware_base : & self . middleware_base ,
127
+ }
128
+ }
129
+
130
+ fn middleware ( & mut self , middleware : impl Middleware < Data > + ' static ) -> & mut Self {
111
131
let middleware = Arc :: new ( middleware) ;
112
132
for resource in self . table . iter_mut ( ) {
113
133
resource. middleware . push ( middleware. clone ( ) ) ;
114
134
}
115
135
self . middleware_base . push ( middleware) ;
116
136
self
117
137
}
138
+ }
139
+
140
+ impl < Data : Clone + Send + Sync + ' static > BaseRouter < Data > {
141
+ /// Create a new top-level router.
142
+ pub ( crate ) fn new ( ) -> BaseRouter < Data > {
143
+ BaseRouter {
144
+ table : PathTable :: new ( ) ,
145
+ middleware_base : Vec :: new ( ) ,
146
+ default_handler : Arc :: new ( BoxedEndpoint :: new ( base_default_handler) ) ,
147
+ }
148
+ }
118
149
119
150
pub fn set_default_handler < T : Endpoint < Data , U > , U > ( & mut self , ep : T ) -> & mut Self {
120
151
self . default_handler = Arc :: new ( BoxedEndpoint :: new ( ep) ) ;
@@ -148,7 +179,6 @@ impl<Data: Clone + Send + Sync + 'static> Router<Data> {
148
179
pub struct Resource < ' a , Data > {
149
180
table : & ' a mut PathTable < ResourceData < Data > > ,
150
181
middleware_base : & ' a Vec < Arc < dyn Middleware < Data > + Send + Sync > > ,
151
- default_handler : & ' a Arc < BoxedEndpoint < Data > > ,
152
182
}
153
183
154
184
struct ResourceData < Data > {
@@ -164,11 +194,10 @@ impl<'a, Data> Resource<'a, Data> {
164
194
/// the builder will be local to the subrouter and its descendents.
165
195
///
166
196
/// If resources are already present, they will be discarded.
167
- pub fn nest ( self , builder : impl FnOnce ( & mut Router < Data > ) ) {
168
- let mut subrouter = Router {
197
+ pub fn nest ( self , builder : impl FnOnce ( & mut SubRouter < Data > ) ) {
198
+ let mut subrouter = SubRouter {
169
199
table : PathTable :: new ( ) ,
170
200
middleware_base : self . middleware_base . clone ( ) ,
171
- default_handler : self . default_handler . clone ( ) ,
172
201
} ;
173
202
builder ( & mut subrouter) ;
174
203
* self . table = subrouter. table ;
@@ -253,7 +282,7 @@ mod tests {
253
282
}
254
283
255
284
async fn simulate_request < ' a , Data : Default + Clone + Send + Sync + ' static > (
256
- router : & ' a Router < Data > ,
285
+ router : & ' a BaseRouter < Data > ,
257
286
path : & ' a str ,
258
287
method : & ' a http:: Method ,
259
288
) -> Option < Response > {
@@ -281,7 +310,7 @@ mod tests {
281
310
}
282
311
283
312
fn route_middleware_count < Data : Clone + Send + Sync + ' static > (
284
- router : & Router < Data > ,
313
+ router : & BaseRouter < Data > ,
285
314
path : & str ,
286
315
method : & http:: Method ,
287
316
) -> Option < usize > {
@@ -291,7 +320,7 @@ mod tests {
291
320
292
321
#[ test]
293
322
fn simple_static ( ) {
294
- let mut router: Router < ( ) > = Router :: new ( ) ;
323
+ let mut router: BaseRouter < ( ) > = BaseRouter :: new ( ) ;
295
324
router. at ( "/" ) . get ( async || "/" ) ;
296
325
router. at ( "/foo" ) . get ( async || "/foo" ) ;
297
326
router. at ( "/foo/bar" ) . get ( async || "/foo/bar" ) ;
@@ -311,7 +340,7 @@ mod tests {
311
340
312
341
#[ test]
313
342
fn nested_static ( ) {
314
- let mut router: Router < ( ) > = Router :: new ( ) ;
343
+ let mut router: BaseRouter < ( ) > = BaseRouter :: new ( ) ;
315
344
router. at ( "/a" ) . get ( async || "/a" ) ;
316
345
router. at ( "/b" ) . nest ( |router| {
317
346
router. at ( "/" ) . get ( async || "/b" ) ;
@@ -357,7 +386,7 @@ mod tests {
357
386
358
387
#[ test]
359
388
fn multiple_methods ( ) {
360
- let mut router: Router < ( ) > = Router :: new ( ) ;
389
+ let mut router: BaseRouter < ( ) > = BaseRouter :: new ( ) ;
361
390
router
362
391
. at ( "/a" )
363
392
. nest ( |router| router. at ( "/b" ) . get ( async || "/a/b GET" ) ) ;
@@ -378,7 +407,7 @@ mod tests {
378
407
#[ test]
379
408
#[ should_panic]
380
409
fn duplicate_endpoint_fails ( ) {
381
- let mut router: Router < ( ) > = Router :: new ( ) ;
410
+ let mut router: BaseRouter < ( ) > = BaseRouter :: new ( ) ;
382
411
router
383
412
. at ( "/a" )
384
413
. nest ( |router| router. at ( "/b" ) . get ( async || "" ) ) ; // flattened into /a/b
@@ -387,7 +416,7 @@ mod tests {
387
416
388
417
#[ test]
389
418
fn simple_middleware ( ) {
390
- let mut router: Router < ( ) > = Router :: new ( ) ;
419
+ let mut router: BaseRouter < ( ) > = BaseRouter :: new ( ) ;
391
420
router. middleware ( passthrough_middleware) ;
392
421
router. at ( "/" ) . get ( async || "/" ) ;
393
422
router. at ( "/b" ) . nest ( |router| {
@@ -423,7 +452,7 @@ mod tests {
423
452
424
453
// The order of endpoint and middleware does not matter
425
454
// The order of subrouter and middleware DOES matter
426
- let mut router: Router < Data > = Router :: new ( ) ;
455
+ let mut router: BaseRouter < Data > = BaseRouter :: new ( ) ;
427
456
router. middleware ( Pusher ( 0 ) ) ;
428
457
router. at ( "/" ) . get ( async move |data : AppData < Data > | {
429
458
if ( data. 0 ) . 0 == [ 0 , 2 ] {
0 commit comments