Skip to content

Commit a42d51a

Browse files
committed
Merge pull request #15 from cryogenian/ready/update
update
2 parents 7ee7113 + 71cc445 commit a42d51a

File tree

12 files changed

+95
-102
lines changed

12 files changed

+95
-102
lines changed

.travis.yml

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
language: node_js
22
node_js:
33
- 0.10
4-
env:
5-
- TAG=v0.7.0
64
install:
7-
- wget -O $HOME/purescript.tar.gz https://github.com/purescript/purescript/releases/download/$TAG/linux64.tar.gz
8-
- sudo tar zxvf $HOME/purescript.tar.gz -C /usr/local/bin purescript/psc{,i,-docs,-bundle} --strip-components=1
9-
- sudo chmod a+x /usr/local/bin/psc{,i,-docs,-bundle}
105
- npm install bower gulp -g
11-
- npm install && bower install
6+
- npm install && bower install
127
script:
13-
- gulp test-bundle
8+
- gulp

bower.json

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,18 @@
1818
"tests"
1919
],
2020
"dependencies": {
21-
"purescript-control": "^0.3.0",
22-
"purescript-transformers": "^0.6.1",
23-
"purescript-maps": "^0.4.0",
24-
"purescript-aff": "^0.11.0",
25-
"purescript-strings": "^0.5.2",
26-
"purescript-arrays": "^0.4.0",
27-
"purescript-lists": "^0.7.0",
28-
"purescript-monoid": "^0.3.0",
29-
"purescript-validation": "^0.2.0",
21+
"purescript-aff": "^0.13.0",
22+
"purescript-dom": "^0.2.6",
23+
"purescript-eff": "^0.1.1",
24+
"purescript-either": "^0.2.2",
25+
"purescript-globals": "^0.2.1",
26+
"purescript-lists": "^0.7.4",
27+
"purescript-maps": "^0.5.0",
28+
"purescript-maybe": "^0.3.4",
29+
"purescript-prelude": "^0.1.2",
3030
"purescript-semirings": "^0.2.0",
31-
"purescript-dom": "^0.1.2",
32-
"purescript-globals": "^0.2.0"
31+
"purescript-tuples": "^0.4.0",
32+
"purescript-validation": "^0.2.0"
3333
},
3434
"devDependencies": {
3535
"purescript-console": "^0.1.0"

docs/Routing/Match.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ instance matchApply :: Apply Match
1818
instance matchApplicative :: Applicative Match
1919
```
2020

21+
#### `unMatch`
22+
23+
``` purescript
24+
unMatch :: forall a. Match a -> Route -> V (Free MatchError) (Tuple Route a)
25+
```
26+
2127
#### `list`
2228

2329
``` purescript
@@ -39,7 +45,7 @@ runMatch :: forall a. Match a -> Route -> Either String a
3945
eitherMatch :: forall a b. Match (Either a b) -> Match b
4046
```
4147

42-
if we match something that can fail then we have to
48+
if we match something that can fail then we have to
4349
match `Either a b`. This function converts matching on such
4450
sum to matching on right subpart. Matching on left branch fails.
4551
i.e.
@@ -49,11 +55,11 @@ sortOfString :: String -> Either String Sort
4955
sortOfString "asc" = Right Asc
5056
sortOfString "desc" = Right Desc
5157
sortOfString _ = Left "incorrect sort"
52-
58+
5359
newtype Routing = Routing Sort
5460
routes :: Match Routing
5561
routes = (pure Routing) <*> (eitherMatch (sortOfString <$> var))
56-
62+
5763
```
5864

5965

docs/Routing/Types.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
``` purescript
66
data RoutePart
77
= Path String
8-
| Query (StrMap String)
8+
| Query (Map String String)
99
```
1010

1111
#### `Route`

gulpfile.js

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,7 @@
11
'use strict'
22

33
var gulp = require('gulp'),
4-
purescript = require('gulp-purescript'),
5-
runSequence = require('run-sequence');
6-
7-
function sequence() {
8-
var args = [].slice.apply(arguments);
9-
return function() {
10-
runSequence.apply(null, args);
11-
};
12-
}
4+
purescript = require('gulp-purescript');
135

146
var sources = [
157
'src/**/*.purs',
@@ -66,3 +58,5 @@ gulp.task('test-bundle', ['test-make'], function() {
6658
output: 'public/test.js'
6759
});
6860
});
61+
62+
gulp.task("default", ["test-bundle", "docs"]);

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"homepage": "https://github.com/slamdata/purescript-routing",
1919
"dependencies": {
2020
"gulp": "^3.9.0",
21-
"gulp-purescript": "^0.5.0",
22-
"run-sequence": "^1.1.1"
21+
"gulp-purescript": "^0.7.0",
22+
"purescript": "^0.7.4"
2323
}
2424
}

src/Routing.purs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,20 @@ module Routing (
1010
) where
1111

1212
import Prelude
13-
import Control.Monad.Eff
14-
import Control.Monad.Aff
15-
import Data.Maybe
16-
import Data.Either
17-
import Data.Tuple
13+
import Control.Monad.Eff (Eff())
14+
import Control.Monad.Aff (Aff(), makeAff)
15+
import Data.Maybe (Maybe(..))
16+
import Data.Either (Either(), either)
17+
import Data.Tuple (Tuple(..))
1818
import qualified Data.String.Regex as R
1919

2020
import Routing.Parser
2121
import Routing.Match
2222

2323

24-
foreign import decodeURIComponent :: String -> String
24+
foreign import decodeURIComponent :: String -> String
2525

26-
foreign import hashChanged :: forall e. (String -> String -> Eff e Unit) -> Eff e Unit
26+
foreign import hashChanged :: forall e. (String -> String -> Eff e Unit) -> Eff e Unit
2727

2828

2929
hashes :: forall e. (String -> String -> Eff e Unit) -> Eff e Unit
@@ -49,16 +49,16 @@ matches' decoder routing cb = hashes $ \old new ->
4949
matchesAff' :: forall e a. (String -> String) ->
5050
Match a -> Aff e (Tuple (Maybe a) a)
5151
matchesAff' decoder routing =
52-
makeAff \_ k -> do
52+
makeAff \_ k -> do
5353
matches' decoder routing \old new ->
5454
k $ Tuple old new
5555

5656
matchesAff :: forall e a. Match a -> Aff e (Tuple (Maybe a) a)
5757
matchesAff = matchesAff' decodeURIComponent
58-
58+
5959

6060
matchHash :: forall a. Match a -> String -> Either String a
6161
matchHash = matchHash' decodeURIComponent
6262

6363
matchHash' :: forall a. (String -> String) -> Match a -> String -> Either String a
64-
matchHash' decoder matcher hash = runMatch matcher $ parse decoder hash
64+
matchHash' decoder matcher hash = runMatch matcher $ parse decoder hash

src/Routing/Match.purs

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,31 @@
11
module Routing.Match where
22

33
import Prelude
4-
import Data.Either
5-
import Data.Tuple
6-
import Data.Maybe
7-
import Data.List
8-
import Control.Alt
9-
import Control.Plus
10-
import Control.Apply
11-
import Control.Alternative
12-
import Control.Monad.Error
13-
import qualified Data.StrMap as M
4+
import Data.Either (Either(..))
5+
import Data.Tuple (Tuple(..), snd)
6+
import Data.Maybe (Maybe(..))
7+
import Data.List (List(..), reverse)
8+
import Control.Alt (Alt, (<|>))
9+
import Control.Plus (Plus)
10+
import Control.Alternative (Alternative)
11+
import Control.Monad.Except
1412
import Global (readFloat, isNaN)
15-
import Data.Semiring.Free
13+
import Data.Semiring.Free (Free(), free, runFree)
1614
import Data.Foldable
17-
import qualified Data.Array as A
1815
import Data.Validation.Semiring
1916

17+
18+
import qualified Data.Map as M
19+
import qualified Data.String as S
20+
2021
import Routing.Parser
2122
import Routing.Types
2223
import Routing.Match.Class
2324
import Routing.Match.Error
2425

25-
newtype Match a = Match (Route -> V (Free MatchError) (Tuple Route a))
26+
newtype Match a = Match (Route -> V (Free MatchError) (Tuple Route a))
27+
unMatch :: forall a. Match a -> (Route -> V (Free MatchError) (Tuple Route a))
28+
unMatch (Match a) = a
2629

2730
instance matchMatchClass :: MatchClass Match where
2831
lit input = Match $ \route ->
@@ -35,21 +38,21 @@ instance matchMatchClass :: MatchClass Match where
3538
invalid $ free ExpectedPathPart
3639
num = Match $ \route ->
3740
case route of
38-
Cons (Path input) rs ->
41+
Cons (Path input) rs ->
3942
let res = readFloat input in
4043
if isNaN res then
4144
invalid $ free ExpectedNumber
4245
else
43-
pure $ Tuple rs res
46+
pure $ Tuple rs res
4447
_ ->
4548
invalid $ free ExpectedNumber
4649

4750
bool = Match $ \route ->
4851
case route of
4952
Cons (Path input) rs | input == "true" ->
50-
pure $ Tuple rs true
53+
pure $ Tuple rs true
5154
Cons (Path input) rs | input == "false" ->
52-
pure $ Tuple rs false
55+
pure $ Tuple rs false
5356
_ ->
5457
invalid $ free ExpectedBoolean
5558

@@ -80,24 +83,23 @@ instance matchFunctor :: Functor Match where
8083
instance matchAlt :: Alt Match where
8184
alt (Match r2e1) (Match r2e2) = Match $ \r -> do
8285
(r2e1 r) <|> (r2e2 r)
83-
86+
8487
instance matchPlus :: Plus Match where
8588
empty = Match $ const $ invalid one
8689

8790
instance matchAlternative :: Alternative Match
8891

8992
instance matchApply :: Apply Match where
90-
apply (Match r2a2b) (Match r2a) =
93+
apply (Match r2a2b) (Match r2a) =
9194
Match $ (\r -> runV (processFnErr r) processFnRes (r2a2b r))
92-
where processFnErr r err =
95+
where processFnErr r err =
9396
invalid $ err * runV id (const one) (r2a r)
9497
processFnRes (Tuple rs a2b) =
9598
runV invalid (\(Tuple rss a) -> pure $ Tuple rss (a2b a)) (r2a rs)
9699

97100
instance matchApplicative :: Applicative Match where
98101
pure a = Match \r -> pure $ Tuple r a
99102

100-
101103
-- | Matches list of matchers. Useful when argument can easy fail (not `str`)
102104
-- | returns `Match Nil` if no matches
103105
list :: forall a. Match a -> Match (List a)
@@ -109,22 +111,23 @@ list (Match r2a) =
109111
(const $ pure (Tuple r (reverse accum)))
110112
(\(Tuple rs a) -> go (Cons a accum) rs)
111113
(r2a r)
112-
114+
113115

114116

115117

116118
-- It groups `Free MatchError` -> [[MatchError]] -map with showMatchError ->
117-
-- [[String]] -fold with semicolon-> [String] -fold with newline-> String
119+
-- [[String]] -fold with semicolon-> [String] -fold with newline-> String
118120
runMatch :: forall a. Match a -> Route -> Either String a
119121
runMatch (Match fn) route =
120122
runV foldErrors (Right <<< snd) $ fn route
121-
where foldErrors errs = Left $
122-
foldl (\b a -> a <> "\n" <> b) "" do
123-
es <- reverse <$> runFree errs
124-
pure $ foldl (\b a -> a <> ";" <> b) "" $ showMatchError <$> es
123+
where
124+
foldErrors errs =
125+
Left $ foldl (\b a -> a <> "\n" <> b) "" do
126+
es <- reverse <$> runFree errs
127+
pure $ foldl (\b a -> a <> ";" <> b) "" $ showMatchError <$> es
125128

126129

127-
-- | if we match something that can fail then we have to
130+
-- | if we match something that can fail then we have to
128131
-- | match `Either a b`. This function converts matching on such
129132
-- | sum to matching on right subpart. Matching on left branch fails.
130133
-- | i.e.
@@ -134,16 +137,17 @@ runMatch (Match fn) route =
134137
-- | sortOfString "asc" = Right Asc
135138
-- | sortOfString "desc" = Right Desc
136139
-- | sortOfString _ = Left "incorrect sort"
137-
-- |
140+
-- |
138141
-- | newtype Routing = Routing Sort
139142
-- | routes :: Match Routing
140143
-- | routes = (pure Routing) <*> (eitherMatch (sortOfString <$> var))
141-
-- |
144+
-- |
142145
-- | ```
143146
eitherMatch :: forall a b. Match (Either a b) -> Match b
144147
eitherMatch (Match r2eab) = Match $ \r ->
145148
runV invalid runEither $ (r2eab r)
146-
where runEither (Tuple rs eit) =
147-
case eit of
148-
Left _ -> invalid $ free $ Fail "Nested check failed"
149-
Right res -> pure $ Tuple rs res
149+
where
150+
runEither (Tuple rs eit) =
151+
case eit of
152+
Left _ -> invalid $ free $ Fail "Nested check failed"
153+
Right res -> pure $ Tuple rs res

src/Routing/Match/Class.purs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module Routing.Match.Class where
22

33
import Prelude
4-
import Control.Alternative
4+
import Control.Alternative (Alternative)
55

66
class (Alternative f) <= MatchClass f where
77
lit :: String -> f Unit

src/Routing/Parser.purs

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,39 @@ module Routing.Parser (
22
parse
33
) where
44

5-
import Prelude
5+
import Prelude
66
import Control.MonadPlus (guard)
77
import Data.Maybe (Maybe(), fromMaybe)
88
import Data.Tuple (Tuple(..))
99
import Data.List (toList, List())
10-
import Data.Traversable (traverse)
11-
import qualified Data.StrMap as M
10+
import Data.Traversable (traverse)
11+
import qualified Data.Map as M
1212
import qualified Data.String as S
1313
import qualified Data.Array as A
1414

1515
import Routing.Types
1616

17-
18-
tryQuery :: RoutePart -> RoutePart
19-
tryQuery source@(Path string) = fromMaybe source $ do
20-
guard $ S.take 1 string == "?"
21-
Query <$> M.fromList <$> traverse part2tuple parts
22-
17+
-- | Parse part of hash. Will return `Query (Map String String)` for query
18+
-- | i.e. `"?foo=bar&bar=baz"` -->
19+
-- | `Query (fromList [Tuple "foo" "bar", Tuple "bar" "baz"])`
20+
parsePart :: String -> RoutePart
21+
parsePart str = fromMaybe (Path str) do
22+
guard $ S.take 1 str == "?"
23+
map (Query <<< M.fromList)
24+
$ traverse part2tuple parts
2325
where
2426
parts :: List String
25-
parts = toList $ S.split "&" $ S.drop 1 string
26-
27+
parts = toList $ S.split "&" $ S.drop 1 str
28+
2729
part2tuple :: String -> Maybe (Tuple String String)
2830
part2tuple input = do
2931
let keyVal = S.split "=" input
3032
guard $ A.length keyVal <= 2
3133
Tuple <$> (A.head keyVal) <*> (keyVal A.!! 1)
32-
33-
tryQuery q = q
3434

3535

3636
-- | Parse hash string to `Route` with `decoder` function
3737
-- | applied to every hash part (usually `decodeURIComponent`)
3838
parse :: (String -> String) -> String -> Route
3939
parse decoder hash =
40-
tryQuery <$>
41-
Path <$>
42-
decoder <$>
43-
toList (S.split "/" hash)
44-
40+
map ( decoder >>> parsePart ) $ toList (S.split "/" hash)

0 commit comments

Comments
 (0)