Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions docs/Routing/Match.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ newtype Match a

##### Instances
``` purescript
instance matchMatchClass :: MatchClass Match
instance matchFunctor :: Functor Match
instance matchAlt :: Alt Match
instance matchPlus :: Plus Match
instance matchAlternative :: Alternative Match
instance matchApply :: Apply Match
instance matchApplicative :: Applicative Match
MatchClass Match
Functor Match
Alt Match
Plus Match
Alternative Match
Apply Match
Applicative Match
```

#### `unMatch`
Expand Down
1 change: 1 addition & 0 deletions docs/Routing/Match/Class.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class (Alternative f) <= MatchClass f where
lit :: String -> f Unit
str :: f String
param :: String -> f String
params :: f (Map String String)
num :: f Number
bool :: f Boolean
fail :: forall a. String -> f a
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"homepage": "https://github.com/slamdata/purescript-routing",
"dependencies": {
"gulp": "^3.9.0",
"gulp-purescript": "^0.7.0",
"purescript": "^0.7.4"
"gulp-purescript": "^0.8.0",
"purescript": "^0.7.6"
}
}
22 changes: 14 additions & 8 deletions src/Routing/Match.purs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,14 @@ import Data.List (List(..), reverse)
import Control.Alt (Alt, (<|>))
import Control.Plus (Plus)
import Control.Alternative (Alternative)
import Control.Monad.Except
import Global (readFloat, isNaN)
import Data.Semiring.Free (Free(), free, runFree)
import Data.Foldable
import Data.Validation.Semiring


import qualified Data.Map as M
import qualified Data.String as S

import Routing.Parser
import Routing.Types
import Routing.Match.Class
import Routing.Match.Error
Expand All @@ -28,15 +25,16 @@ unMatch :: forall a. Match a -> (Route -> V (Free MatchError) (Tuple Route a))
unMatch (Match a) = a

instance matchMatchClass :: MatchClass Match where
lit input = Match $ \route ->
lit input = Match \route ->
case route of
Cons (Path i) rs | i == input ->
pure $ Tuple rs unit
Cons (Path _) rs ->
invalid $ free $ UnexpectedPath input
_ ->
invalid $ free ExpectedPathPart
num = Match $ \route ->

num = Match \route ->
case route of
Cons (Path input) rs ->
let res = readFloat input in
Expand All @@ -47,7 +45,7 @@ instance matchMatchClass :: MatchClass Match where
_ ->
invalid $ free ExpectedNumber

bool = Match $ \route ->
bool = Match \route ->
case route of
Cons (Path input) rs | input == "true" ->
pure $ Tuple rs true
Expand All @@ -56,14 +54,14 @@ instance matchMatchClass :: MatchClass Match where
_ ->
invalid $ free ExpectedBoolean

str = Match $ \route ->
str = Match \route ->
case route of
Cons (Path input) rs ->
pure $ Tuple rs input
_ ->
invalid $ free ExpectedString

param key = Match $ \route ->
param key = Match \route ->
case route of
Cons (Query map) rs ->
case M.lookup key map of
Expand All @@ -73,6 +71,14 @@ instance matchMatchClass :: MatchClass Match where
pure $ Tuple (Cons (Query <<< M.delete key $ map) rs) el
_ ->
invalid $ free ExpectedQuery

params = Match \route ->
case route of
Cons (Query map) rs ->
pure $ Tuple rs map
_ ->
invalid $ free ExpectedQuery

fail msg = Match \_ ->
invalid $ free $ Fail msg

Expand Down
20 changes: 20 additions & 0 deletions src/Routing/Match/Class.purs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,31 @@ module Routing.Match.Class where

import Prelude
import Control.Alternative (Alternative)
import Data.Map as M

class (Alternative f) <= MatchClass f where
-- | `lit x` will match exactly the path component `x`.
-- | For example, `lit "x"` matches `/x`.
lit :: String -> f Unit

-- | `str` matches any path string component.
-- | For example, `str` matches `/foo` as `"foo"`.
str :: f String

-- | `param p` matches a parameter assignment `q=v` within a query block.
-- | For example, `param "q"` matches `/?q=a&r=b` as `"a"`.
param :: String -> f String

-- | `params` matches an entire query block. For exmaple, `params`
-- | matches `/?q=a&r=b` as the map `{q : "a", r : "b"}`. Note that
-- | `lit "foo" *> params` does *not* match `/foo`, since a query component
-- | is *required*.
params :: f (M.Map String String)

-- | `num` matches any numerical path component.
num :: f Number

-- | `bool` matches any boolean path component.
bool :: f Boolean

fail :: forall a. String -> f a
20 changes: 10 additions & 10 deletions test/Test/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,30 @@ import Control.Monad.Eff.Console
import Control.Alt
import Control.Apply
import Data.List
import Data.Map as M


import Routing
import Routing.Match
import Routing.Match.Class

data FooBar = Foo Number | Bar Boolean String | Baz (List Number)
data FooBar = Foo Number (M.Map String String) | Bar Boolean String | Baz (List Number)

instance showFooBar :: Show FooBar where
show (Foo num) = "(Foo " <> show num <> " )"
show (Bar bool str) = "(Bar " <> show bool <> " " <> show str <> " )"
show (Baz lst) = "(Baz " <> show lst <> " )"
show (Foo num q) = "(Foo " <> show num <> " " <> show q <> ")"
show (Bar bool str) = "(Bar " <> show bool <> " " <> show str <> ")"
show (Baz lst) = "(Baz " <> show lst <> ")"

routing :: Match FooBar
routing =
Foo <$> (lit "foo" *> num)
<|>
Bar <$> (lit "bar" *> bool) <*> (param "baz")
<|>
Baz <$> (list num)
Foo <$> (lit "foo" *> num) <*> params
<|> Bar <$> (lit "bar" *> bool) <*> (param "baz")
<|> Baz <$> (list num)


main :: Eff (console :: CONSOLE) Unit
main = do
print $ matchHash routing "foo/12"
print $ matchHash routing "foo/12/?welp='hi'&b=false"
matches routing $ \old new -> void do
print old
print new