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_advV
I 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 ...
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-thingand succeed. In the second, it will see/fooand commit toFooR. If theFooRroute fails to parse, then we get a 404 error, even though/foo/other-thingis 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 returnsMaybe Application. IfJust, then we had a match. IfNothing, then we continue to the next route parse.Right now, the code generation creates a
helperfunction which has a catch-all match on the route fragment andnotFoundon 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 returningJust res. So something like,