@@ -165,19 +165,21 @@ impl Router {
165165 /// by matching wildcard patterns with the longest matching prefix.
166166 pub fn route < ' path , ' router : ' path > (
167167 & ' router self ,
168- p : & ' path str ,
168+ path : & ' path str ,
169169 ) -> Result < RouteMatch < ' router , ' path > > {
170170 let best_match = self
171171 . 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 }" ) ) ?;
174174
175175 let route_handler = best_match. handler ( ) ;
176176
177177 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+ } ,
181183 } )
182184 }
183185}
@@ -220,66 +222,106 @@ impl fmt::Display for ParsedRoute {
220222
221223/// A routing match for a URL.
222224pub 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 > ,
229226}
230227
231228impl < ' router , ' path > RouteMatch < ' router , ' path > {
232229 /// A synthetic match as if the given path was matched against the wildcard route.
233230 /// Used in service chaining.
234231 pub fn synthetic ( component_id : String , path : String ) -> Self {
235232 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+ } ,
244242 }
245243 }
246244
247245 /// The matched component.
248246 pub fn component_id ( & self ) -> & str {
249- & self . route_handler . component_id
247+ & self . inner . route_handler ( ) . component_id
250248 }
251249
252250 /// The matched route, as originally written in the manifest, combined with the base.
253251 pub fn based_route ( & self ) -> & str {
254- & self . route_handler . based_route
252+ & self . inner . route_handler ( ) . based_route
255253 }
256254
257255 /// The matched route, excluding any trailing wildcard, combined with the base.
258256 pub fn based_route_or_prefix ( & self ) -> String {
259- self . route_handler
257+ self . inner
258+ . route_handler ( )
260259 . based_route
261260 . strip_suffix ( "/..." )
262- . unwrap_or ( & self . route_handler . based_route )
261+ . unwrap_or ( & self . inner . route_handler ( ) . based_route )
263262 . to_string ( )
264263 }
265264
266265 /// The matched route, as originally written in the manifest.
267266 pub fn raw_route ( & self ) -> & str {
268- & self . route_handler . raw_route
267+ & self . inner . route_handler ( ) . raw_route
269268 }
270269
271270 /// The matched route, excluding any trailing wildcard.
272271 pub fn raw_route_or_prefix ( & self ) -> String {
273- self . route_handler
272+ self . inner
273+ . route_handler ( )
274274 . raw_route
275275 . strip_suffix ( "/..." )
276- . unwrap_or ( & self . route_handler . raw_route )
276+ . unwrap_or ( & self . inner . route_handler ( ) . raw_route )
277277 . to_string ( )
278278 }
279279
280280 /// The named wildcards captured from the path, if any
281281 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 {
283325 return HashMap :: new ( ) ;
284326 } ;
285327 best_match
@@ -291,15 +333,16 @@ impl<'router, 'path> RouteMatch<'router, 'path> {
291333
292334 /// The trailing wildcard part of the path, if any
293335 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) ,
297344 } ;
298345
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- } ;
303346 best_match
304347 . captures ( )
305348 . wildcard ( )
0 commit comments