git.iko.soy/typeable/http-api-data
on master help sign in
toSinglePiece -> toRoutePiece

toMultiPiece -> toRouteMultiPiece but still maintain deprecated names add QuickCheck tests

commitcc3e430fe3573612624c02e4b81cde98a95dcce8 authorGreg Weber <greg@gregweber.info> dateMon 19 Sep 2011, 05:07 (15 years ago) parent14951c2
3 files changed+155−4
Web/PathPieces.hs+71−3 path-pieces.cabal+14−1 test/main.hs+70
Web/PathPieces.hs+71−3
@@ -1,7 +1,9 @@
1−{-# LANGUAGE FlexibleInstances #-}
2−{-# LANGUAGE TypeSynonymInstances #-}
1+{-# LANGUAGE FlexibleInstances, TypeSynonymInstances #-}
32module Web.PathPieces
4− ( SinglePiece (..)
3+ ( RoutePiece (..)
4+ , RouteMultiPiece (..)
5+ -- * Deprecated
6+ , SinglePiece (..)
57 , MultiPiece (..)
68 ) where
79
@@ -10,30 +12,92 @@ import qualified Data.Text as S
1012import qualified Data.Text.Lazy as L
1113import qualified Data.Text.Read
1214
15+class RoutePiece s where
16+ fromRoutePiece :: S.Text -> Maybe s
17+ toRoutePiece :: s -> S.Text
18+
19+instance RoutePiece String where
20+ fromRoutePiece s = if S.null s then Nothing else Just (S.unpack s)
21+ toRoutePiece = S.pack
22+
23+instance RoutePiece S.Text where
24+ fromRoutePiece s = if S.null s then Nothing else Just s
25+ toRoutePiece = id
26+
27+instance RoutePiece L.Text where
28+ fromRoutePiece s = if S.null s then Nothing else Just (L.fromChunks [s])
29+ toRoutePiece = S.concat . L.toChunks
30+
31+instance RoutePiece Integer where
32+ fromRoutePiece s =
33+ case Data.Text.Read.decimal s of
34+ Right (i, _) -> Just i
35+ Left _ -> Nothing
36+ toRoutePiece = S.pack . show
37+
38+instance RoutePiece Int where
39+ fromRoutePiece s =
40+ case Data.Text.Read.decimal s of
41+ Right (i, _) -> Just i
42+ Left _ -> Nothing
43+ toRoutePiece = S.pack . show
44+
45+instance RoutePiece Int64 where
46+ fromRoutePiece s =
47+ case Data.Text.Read.decimal s of
48+ Right (i, _) -> Just i
49+ Left _ -> Nothing
50+ toRoutePiece = S.pack . show
51+
52+
53+class RouteMultiPiece s where
54+ fromRouteMultiPiece :: [S.Text] -> Maybe s
55+ toRouteMultiPiece :: s -> [S.Text]
56+
57+instance RouteMultiPiece [String] where
58+ fromRouteMultiPiece = Just . map S.unpack
59+ toRouteMultiPiece = map S.pack
60+
61+instance RouteMultiPiece [S.Text] where
62+ fromRouteMultiPiece = Just
63+ toRouteMultiPiece = id
64+
65+instance RouteMultiPiece [L.Text] where
66+ fromRouteMultiPiece = Just . map (L.fromChunks . return)
67+ toRouteMultiPiece = map $ S.concat . L.toChunks
68+
69+
70+-- | deprecated api
1371class SinglePiece s where
1472 fromSinglePiece :: S.Text -> Maybe s
1573 toSinglePiece :: s -> S.Text
74+
1675instance SinglePiece String where
1776 fromSinglePiece s = if S.null s then Nothing else Just (S.unpack s)
1877 toSinglePiece = S.pack
78+
1979instance SinglePiece S.Text where
2080 fromSinglePiece s = if S.null s then Nothing else Just s
2181 toSinglePiece = id
82+
2283instance SinglePiece L.Text where
2384 fromSinglePiece s = if S.null s then Nothing else Just (L.fromChunks [s])
2485 toSinglePiece = S.concat . L.toChunks
86+
2587instance SinglePiece Integer where
2688 fromSinglePiece s =
2789 case Data.Text.Read.decimal s of
2890 Right (i, _) -> Just i
2991 Left _ -> Nothing
3092 toSinglePiece = S.pack . show
93+
3194instance SinglePiece Int where
3295 fromSinglePiece s =
3396 case Data.Text.Read.decimal s of
3497 Right (i, _) -> Just i
3598 Left _ -> Nothing
3699 toSinglePiece = S.pack . show
100+
37101instance SinglePiece Int64 where
38102 fromSinglePiece s =
39103 case Data.Text.Read.decimal s of
@@ -41,15 +105,19 @@ instance SinglePiece Int64 where
41105 Left _ -> Nothing
42106 toSinglePiece = S.pack . show
43107
108+
44109class MultiPiece s where
45110 fromMultiPiece :: [S.Text] -> Maybe s
46111 toMultiPiece :: s -> [S.Text]
112+
47113instance MultiPiece [String] where
48114 fromMultiPiece = Just . map S.unpack
49115 toMultiPiece = map S.pack
116+
50117instance MultiPiece [S.Text] where
51118 fromMultiPiece = Just
52119 toMultiPiece = id
120+
53121instance MultiPiece [L.Text] where
54122 fromMultiPiece = Just . map (L.fromChunks . return)
55123 toMultiPiece = map $ S.concat . L.toChunks
path-pieces.cabal+14−1
@@ -7,7 +7,7 @@ maintainer: Michael Snoyman <michael@snoyman.com>
77synopsis: Components of paths.
88category: Web, Yesod
99stability: unstable
10−cabal-version: >= 1.6
10+cabal-version: >= 1.8
1111build-type: Simple
1212homepage: http://github.com/snoyberg/path-pieces
1313
@@ -17,6 +17,19 @@ library
1717 exposed-modules: Web.PathPieces
1818 ghc-options: -Wall
1919
20+test-suite test
21+ type: exitcode-stdio-1.0
22+ main-is: main.hs
23+ hs-source-dirs: test
24+ ghc-options: -Wall
25+ build-depends: HUnit
26+ , hspec >= 0.8 && < 0.9
27+ , file-location >= 0.4 && < 0.5
28+ , base >= 4 && < 5
29+ , QuickCheck == 2.4.*
30+ , path-pieces
31+ , text
32+
2033source-repository head
2134 type: git
2235 location: git://github.com/snoyberg/path-pieces.git
test/main.hsnew file+70
@@ -0,0 +1,70 @@
1+{-# Language ScopedTypeVariables #-}
2+{-# OPTIONS_GHC -fno-warn-orphans #-}
3+module Main where
4+
5+import Test.Hspec.Monadic (Specs, describe, hspecX)
6+import Test.Hspec.HUnit()
7+import Test.Hspec.QuickCheck(prop)
8+import Test.QuickCheck
9+
10+import Web.PathPieces
11+import qualified Data.Text as T
12+import Data.Maybe (fromJust)
13+
14+-- import FileLocation (debug)
15+
16+instance Arbitrary T.Text where
17+ arbitrary = fmap T.pack arbitrary
18+
19+
20+main :: IO ()
21+main = hspecX specs
22+
23+specs :: Specs
24+specs = do
25+ describe "RoutePiece" $ do
26+ prop "toRoutePiece <=> fromSinglePiece String" $ \(p::String) ->
27+ case (fromRoutePiece . toSinglePiece) p of
28+ Nothing -> null p
29+ Just pConverted -> p == pConverted
30+
31+ prop "toRoutePiece <=> fromSinglePiece String" $ \(p::T.Text) ->
32+ case (fromRoutePiece . toSinglePiece) p of
33+ Nothing -> T.null p
34+ Just pConverted -> p == pConverted
35+
36+ prop "toRoutePiece <=> fromSinglePiece String" $ \(p::Int) ->
37+ case (fromRoutePiece . toSinglePiece) p of
38+ Nothing -> p < 0
39+ Just pConverted -> p == pConverted
40+
41+ describe "RouteMultiPiece" $ do
42+ prop "toRouteMultiPiece <=> fromMultiPiece String" $ \(p::[String]) ->
43+ p == (fromJust . fromRouteMultiPiece . toMultiPiece) p
44+
45+ prop "toRouteMultiPiece <=> fromMultiPiece String" $ \(p::[T.Text]) ->
46+ p == (fromJust . fromRouteMultiPiece . toMultiPiece) p
47+
48+
49+ describe "SinglePiece" $ do
50+ prop "toSinglePiece <=> fromSinglePiece String" $ \(p::String) ->
51+ case (fromSinglePiece . toSinglePiece) p of
52+ Nothing -> null p
53+ Just pConverted -> p == pConverted
54+
55+ prop "toSinglePiece <=> fromSinglePiece String" $ \(p::T.Text) ->
56+ case (fromSinglePiece . toSinglePiece) p of
57+ Nothing -> T.null p
58+ Just pConverted -> p == pConverted
59+
60+ prop "toSinglePiece <=> fromSinglePiece String" $ \(p::Int) ->
61+ case (fromSinglePiece . toSinglePiece) p of
62+ Nothing -> p < 0
63+ Just pConverted -> p == pConverted
64+
65+ describe "MultiPiece" $ do
66+ prop "toMultiPiece <=> fromMultiPiece String" $ \(p::[String]) ->
67+ p == (fromJust . fromMultiPiece . toMultiPiece) p
68+
69+ prop "toMultiPiece <=> fromMultiPiece String" $ \(p::[T.Text]) ->
70+ p == (fromJust . fromMultiPiece . toMultiPiece) p