-
Notifications
You must be signed in to change notification settings - Fork 381
Description
Suppose you have a route structure like,
[parseRoutes|
/foo FooR
/foo/bar FooBarR
/foo/bar/baz FooBarBazR
/foo/other-thing FooOtherThingR
|]You may want to make the first set a nested route, but not touch the second group for a bit.
[parseRoutes|
/foo FooR:
/bar FooBarR
/bar/baz FooBarBazR
/foo/other-thing FooOtherThingR
|]This route structure is actually semantically different from the first! In the first, if you try to parse /foo/other-thing, first it will try /foo, fail, then try /foo/bar/, fail, then try /foo/bar/baz/, fail, and then finally try /foo/other-thing and succeed. In the second, it will see /foo and commit to FooR. If the FooR route fails to parse, then we get a 404 error, even though /foo/other-thing is a route we should be able to accept.
I think we can get this working pretty easily- we just have to have the helper instead of returning Application, it returns Maybe Application. If Just, then we had a match. If Nothing, then we continue to the next route parse.
Right now, the code generation creates a helper function which has a catch-all match on the route fragment and notFound on it. From -ddump-splices,
helperChild0R_adwf _
= yesodRunner
(Data.Functor.void notFound) env_advU Nothing req_advVI think, instead, we want to make it return Maybe Application, and then do another pattern guard on that returning Just res. So something like,
instance YesodDispatch App where
yesodDispatch env req = helper (pathInfo req)
where
helper ("foo" : rest) | Just app <- helperFoo rest = app
where
helperFoo [] = Just $ yesodRunner ...
helperFoo ["bar"] = Just $ yesodRunner ...
helperFoo ["bar", "baz"] = Just $ yesodRunner ...
helperFoo _ = Nothing
helper ("foo" : "other-thing" : []) = yesodRunner ...