In the route syntax, allow trailing backslashes to indicate line continuation.

This commit is contained in:
Jason Whittle 2018-10-08 16:38:02 -04:00
parent 6a9bcc292d
commit 4e4efd1627
3 changed files with 27 additions and 3 deletions

View File

@ -65,7 +65,7 @@ parseRoutesNoCheck = QuasiQuoter
-- invalid input. -- invalid input.
resourcesFromString :: String -> [ResourceTree String] resourcesFromString :: String -> [ResourceTree String]
resourcesFromString = resourcesFromString =
fst . parse 0 . filter (not . all (== ' ')) . lines . filter (/= '\r') fst . parse 0 . filter (not . all (== ' ')) . foldr lineContinuations [] . lines . filter (/= '\r')
where where
parse _ [] = ([], []) parse _ [] = ([], [])
parse indent (thisLine:otherLines) parse indent (thisLine:otherLines)
@ -285,3 +285,10 @@ dropBracket str@('{':x) = case break (== '}') x of
_ -> error $ "Unclosed bracket ('{'): " ++ str _ -> error $ "Unclosed bracket ('{'): " ++ str
dropBracket x = x dropBracket x = x
-- If this line ends with a backslash, concatenate it together with the next line.
lineContinuations :: String -> [String] -> [String]
lineContinuations this [] = [this]
lineContinuations this below@(next:rest) = case unsnoc this of
Just (this', '\\') -> (this'++next):rest
_ -> this:below
where unsnoc s = if null s then Nothing else Just (init s, last s)

View File

@ -17,7 +17,7 @@ import Test.HUnit ((@?=))
import Data.Text (Text, pack, unpack, singleton) import Data.Text (Text, pack, unpack, singleton)
import Yesod.Routes.Class hiding (Route) import Yesod.Routes.Class hiding (Route)
import qualified Yesod.Routes.Class as YRC import qualified Yesod.Routes.Class as YRC
import Yesod.Routes.Parse (parseRoutesNoCheck, parseTypeTree, TypeTree (..)) import Yesod.Routes.Parse (parseRoutesFile, parseRoutesNoCheck, parseTypeTree, TypeTree (..))
import Yesod.Routes.Overlap (findOverlapNames) import Yesod.Routes.Overlap (findOverlapNames)
import Yesod.Routes.TH hiding (Dispatch) import Yesod.Routes.TH hiding (Dispatch)
import Language.Haskell.TH.Syntax import Language.Haskell.TH.Syntax
@ -219,11 +219,17 @@ main = hspec $ do
it "routes to subparam" $ disp "PUT" ["subparam", "6", "q"] it "routes to subparam" $ disp "PUT" ["subparam", "6", "q"]
@?= (pack "subparam 6 q", Just $ SubparamR 6 $ ParamRoute 'q') @?= (pack "subparam 6 q", Just $ SubparamR 6 $ ParamRoute 'q')
describe "parsing" $ do describe "route parsing" $ do
it "subsites work" $ do it "subsites work" $ do
parseRoute ([pack "subsite", pack "foo"], [(pack "bar", pack "baz")]) @?= parseRoute ([pack "subsite", pack "foo"], [(pack "bar", pack "baz")]) @?=
Just (SubsiteR $ MySubRoute ([pack "foo"], [(pack "bar", pack "baz")])) Just (SubsiteR $ MySubRoute ([pack "foo"], [(pack "bar", pack "baz")]))
describe "routing table parsing" $ do
it "recognizes trailing backslashes as line continuation directives" $ do
let routes :: [ResourceTree String]
routes = $(parseRoutesFile "test/fixtures/routes_with_line_continuations")
length routes @?= 3
describe "overlap checking" $ do describe "overlap checking" $ do
it "catches overlapping statics" $ do it "catches overlapping statics" $ do
let routes :: [ResourceTree String] let routes :: [ResourceTree String]

View File

@ -0,0 +1,11 @@
-- This fixture to test line continuations is in a separate file
-- because when I put it in an in-line quasi-quotation, the compiler
-- performed the line continuations processing itself.
/foo1 \
Foo1
/foo2 Foo2
/foo3 \
Foo3 \
GET POST \
!foo