-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRoutesParser.hs
75 lines (59 loc) · 1.55 KB
/
RoutesParser.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
module RoutesParser where
import Control.Applicative ((<$>))
import Data.Stream
import Text.ParserCombinators.Parsec hiding (parse)
import qualified Text.ParserCombinators.Parsec as Parsec
data Route
= Route
{ alias :: String
, pattern :: String
, methods :: [String]
}
deriving (Show)
spacesOrTabs :: Parser ()
spacesOrTabs =
skipMany1 (oneOf " \t")
parseMethod :: Parser String
parseMethod =
choice
[ try $ string "GET"
, try $ string "POST"
, try $ string "PUT"
, try $ string "DELETE"
, try $ string "SURF"
]
parseRoute :: Parser Route
parseRoute = do
-- alias mandatory, no leading spaces
alias <- many1 letter
spacesOrTabs
-- pattern mandatory
pattern <- many1 (choice [alphaNum, oneOf "/:"])
spacesOrTabs
-- must be at least one method defined for a route
methods <- parseMethod `sepBy1` spacesOrTabs
optional spacesOrTabs
return (Route alias pattern methods)
start :: Parser [Route]
start = do
-- parse all route lines
routes <- parseRoute `sepEndBy` eol
spaces
return routes
where eol = do
_ <- optional (char '\r')
_ <- char '\n'
return ()
{-
alias pattern methods
-----------------------------------------------
post /posts/:name GET SURF PUT DELETE
posts /posts POST
foobar /foo/bar/:car/:dar GET
-}
parse = Parsec.parse start "RoutesParser"
main = do
-- input <- readLn
-- print input
let input = "post /posts/:name GET SURF PUT DELETE\nposts /posts POST"
print (parse input)