@@ -165,19 +165,21 @@ impl Router {
165
165
/// by matching wildcard patterns with the longest matching prefix.
166
166
pub fn route < ' path , ' router : ' path > (
167
167
& ' router self ,
168
- p : & ' path str ,
168
+ path : & ' path str ,
169
169
) -> Result < RouteMatch < ' router , ' path > > {
170
170
let best_match = self
171
171
. router
172
- . best_match ( p )
173
- . ok_or_else ( || anyhow ! ( "Cannot match route for path {p }" ) ) ?;
172
+ . best_match ( path )
173
+ . ok_or_else ( || anyhow ! ( "Cannot match route for path {path }" ) ) ?;
174
174
175
175
let route_handler = best_match. handler ( ) ;
176
176
177
177
Ok ( RouteMatch {
178
- route_handler : Cow :: Borrowed ( route_handler) ,
179
- best_match : Some ( ( p, best_match) ) ,
180
- trailing_wildcard : None ,
178
+ inner : RouteMatchKind :: Real {
179
+ route_handler,
180
+ best_match,
181
+ path,
182
+ } ,
181
183
} )
182
184
}
183
185
}
@@ -220,66 +222,106 @@ impl fmt::Display for ParsedRoute {
220
222
221
223
/// A routing match for a URL.
222
224
pub struct RouteMatch < ' router , ' path > {
223
- /// The route handler that matched the path.
224
- route_handler : Cow < ' router , RouteHandler > ,
225
- /// An optional best match for the path.
226
- best_match : Option < ( & ' path str , routefinder:: Match < ' router , ' path , RouteHandler > ) > ,
227
- /// An optional trailing wildcard part of the path used by the synthetic match.
228
- trailing_wildcard : Option < String > ,
225
+ inner : RouteMatchKind < ' router , ' path > ,
229
226
}
230
227
231
228
impl < ' router , ' path > RouteMatch < ' router , ' path > {
232
229
/// A synthetic match as if the given path was matched against the wildcard route.
233
230
/// Used in service chaining.
234
231
pub fn synthetic ( component_id : String , path : String ) -> Self {
235
232
Self {
236
- route_handler : Cow :: Owned ( RouteHandler {
237
- component_id,
238
- based_route : "/..." . into ( ) ,
239
- raw_route : "/..." . into ( ) ,
240
- parsed_based_route : ParsedRoute :: TrailingWildcard ( String :: new ( ) ) ,
241
- } ) ,
242
- best_match : None ,
243
- trailing_wildcard : Some ( path) ,
233
+ inner : RouteMatchKind :: Synthetic {
234
+ route_handler : RouteHandler {
235
+ component_id,
236
+ based_route : "/..." . into ( ) ,
237
+ raw_route : "/..." . into ( ) ,
238
+ parsed_based_route : ParsedRoute :: TrailingWildcard ( String :: new ( ) ) ,
239
+ } ,
240
+ trailing_wildcard : path,
241
+ } ,
244
242
}
245
243
}
246
244
247
245
/// The matched component.
248
246
pub fn component_id ( & self ) -> & str {
249
- & self . route_handler . component_id
247
+ & self . inner . route_handler ( ) . component_id
250
248
}
251
249
252
250
/// The matched route, as originally written in the manifest, combined with the base.
253
251
pub fn based_route ( & self ) -> & str {
254
- & self . route_handler . based_route
252
+ & self . inner . route_handler ( ) . based_route
255
253
}
256
254
257
255
/// The matched route, excluding any trailing wildcard, combined with the base.
258
256
pub fn based_route_or_prefix ( & self ) -> String {
259
- self . route_handler
257
+ self . inner
258
+ . route_handler ( )
260
259
. based_route
261
260
. strip_suffix ( "/..." )
262
- . unwrap_or ( & self . route_handler . based_route )
261
+ . unwrap_or ( & self . inner . route_handler ( ) . based_route )
263
262
. to_string ( )
264
263
}
265
264
266
265
/// The matched route, as originally written in the manifest.
267
266
pub fn raw_route ( & self ) -> & str {
268
- & self . route_handler . raw_route
267
+ & self . inner . route_handler ( ) . raw_route
269
268
}
270
269
271
270
/// The matched route, excluding any trailing wildcard.
272
271
pub fn raw_route_or_prefix ( & self ) -> String {
273
- self . route_handler
272
+ self . inner
273
+ . route_handler ( )
274
274
. raw_route
275
275
. strip_suffix ( "/..." )
276
- . unwrap_or ( & self . route_handler . raw_route )
276
+ . unwrap_or ( & self . inner . route_handler ( ) . raw_route )
277
277
. to_string ( )
278
278
}
279
279
280
280
/// The named wildcards captured from the path, if any
281
281
pub fn named_wildcards ( & self ) -> HashMap < String , String > {
282
- let Some ( ( _, best_match) ) = & self . best_match else {
282
+ self . inner . named_wildcards ( )
283
+ }
284
+
285
+ /// The trailing wildcard part of the path, if any
286
+ pub fn trailing_wildcard ( & self ) -> String {
287
+ self . inner . trailing_wildcard ( )
288
+ }
289
+ }
290
+
291
+ /// The kind of route match that was made.
292
+ ///
293
+ /// Can either be real based on the routefinder or synthetic based on hardcoded results.
294
+ enum RouteMatchKind < ' router , ' path > {
295
+ /// A synthetic match as if the given path was matched against the wildcard route.
296
+ Synthetic {
297
+ /// The route handler that matched the path.
298
+ route_handler : RouteHandler ,
299
+ /// The trailing wildcard part of the path
300
+ trailing_wildcard : String ,
301
+ } ,
302
+ /// A real match.
303
+ Real {
304
+ /// The route handler that matched the path.
305
+ route_handler : & ' router RouteHandler ,
306
+ /// The best match for the path.
307
+ best_match : routefinder:: Match < ' router , ' path , RouteHandler > ,
308
+ /// The path that was matched.
309
+ path : & ' path str ,
310
+ } ,
311
+ }
312
+
313
+ impl < ' router , ' path > RouteMatchKind < ' router , ' path > {
314
+ /// The route handler that matched the path.
315
+ fn route_handler ( & self ) -> & RouteHandler {
316
+ match self {
317
+ RouteMatchKind :: Synthetic { route_handler, .. } => route_handler,
318
+ RouteMatchKind :: Real { route_handler, .. } => route_handler,
319
+ }
320
+ }
321
+
322
+ /// The named wildcards captured from the path, if any
323
+ pub fn named_wildcards ( & self ) -> HashMap < String , String > {
324
+ let Self :: Real { best_match, .. } = & self else {
283
325
return HashMap :: new ( ) ;
284
326
} ;
285
327
best_match
@@ -291,15 +333,16 @@ impl<'router, 'path> RouteMatch<'router, 'path> {
291
333
292
334
/// The trailing wildcard part of the path, if any
293
335
pub fn trailing_wildcard ( & self ) -> String {
294
- // If we have a trailing wildcard, return it.
295
- if let Some ( wildcard) = & self . trailing_wildcard {
296
- return wildcard. clone ( ) ;
336
+ let ( best_match, path) = match self {
337
+ // If we have a synthetic match, we already have the trailing wildcard.
338
+ Self :: Synthetic {
339
+ trailing_wildcard, ..
340
+ } => return trailing_wildcard. clone ( ) ,
341
+ Self :: Real {
342
+ best_match, path, ..
343
+ } => ( best_match, path) ,
297
344
} ;
298
345
299
- // Otherwise, we need to extract it from the best match if we have it.
300
- let Some ( ( path, best_match) ) = & self . best_match else {
301
- return String :: new ( ) ;
302
- } ;
303
346
best_match
304
347
. captures ( )
305
348
. wildcard ( )
0 commit comments