git.iko.soy/typeable/http-api-data
on master help sign in
Add To/FromHttpApiData instances for ()
commit3cb3fe60ef35d1c141336680718ba58690c6c36a authorNickolay Kudasov <nickolay.kudasov@gmail.com> dateMon 5 Oct 2015, 18:20 (11 years ago) parentfec05be
3 files changed+21−6
Web/HttpApiData.hs+19−2 Web/PathPieces.hs+1−4 test/main.hs+1
Web/HttpApiData.hs+19−2
@@ -73,11 +73,15 @@ class FromHttpApiData a where
7373 parseQueryParam :: Text -> Either Text a
7474 parseQueryParam = parseUrlPiece
7575
76+-- | Default parsing error.
77+defaultParseError :: Text -> Either Text a
78+defaultParseError input = Left ("could not convert: `" <> input <> "'")
79+
7680-- | Convert @'Maybe'@ parser into @'Either' 'Text'@ parser with default error message.
7781parseMaybeHttpApiData :: (Text -> Maybe a) -> (Text -> Either Text a)
7882parseMaybeHttpApiData parse input =
7983 case parse input of
80− Nothing -> Left ("could not convert: `" <> input <> "'")
84+ Nothing -> defaultParseError input
8185 Just val -> Right val
8286
8387-- | Convert to URL piece using @'Show'@ instance.
@@ -99,7 +103,7 @@ runReader reader input =
99103 Left err -> Left (T.pack err)
100104 Right (x, rest)
101105 | T.null rest -> Right x
102− | otherwise -> Left ("could not convert: `" <> input <> "'")
106+ | otherwise -> defaultParseError input
103107
104108-- | Run @'Reader'@ to parse bounded integral value with bounds checking.
105109parseBounded :: forall a. (Bounded a, Integral a) => Reader Integer -> Text -> Either Text a
@@ -112,6 +116,12 @@ parseBounded reader input = do
112116 l = toInteger (minBound :: a)
113117 h = toInteger (maxBound :: a)
114118
119+-- |
120+-- >>> toUrlPiece ()
121+-- "_"
122+instance ToHttpApiData () where
123+ toUrlPiece () = "_"
124+
115125instance ToHttpApiData Bool where toUrlPiece = showUrlPiece
116126instance ToHttpApiData Double where toUrlPiece = showUrlPiece
117127instance ToHttpApiData Float where toUrlPiece = showUrlPiece
@@ -131,6 +141,13 @@ instance ToHttpApiData Text where toUrlPiece = id
131141instance ToHttpApiData L.Text where toUrlPiece = L.toStrict
132142instance ToHttpApiData Day where toUrlPiece = showUrlPiece
133143
144+-- |
145+-- >>> parseUrlPiece "_" :: Either Text ()
146+-- Right ()
147+instance FromHttpApiData () where
148+ parseUrlPiece "_" = pure ()
149+ parseUrlPiece s = defaultParseError s
150+
134151instance FromHttpApiData Bool where parseUrlPiece = readEitherUrlPiece
135152instance FromHttpApiData Double where parseUrlPiece = runReader rational
136153instance FromHttpApiData Float where parseUrlPiece = runReader rational
Web/PathPieces.hs+1−4
@@ -32,6 +32,7 @@ class PathPiece s where
3232 default toPathPiece :: ToHttpApiData s => s -> S.Text
3333 toPathPiece = toUrlPiece
3434
35+instance PathPiece ()
3536instance PathPiece Bool
3637instance PathPiece Double
3738instance PathPiece Float
@@ -50,10 +51,6 @@ instance PathPiece S.Text
5051instance PathPiece L.Text
5152instance PathPiece Day
5253
53−instance PathPiece () where
54− fromPathPiece t = if t == "_" then Just () else Nothing
55− toPathPiece () = "_"
56−
5754instance (PathPiece a) => PathPiece (Maybe a) where
5855 fromPathPiece s = case S.stripPrefix "Just " s of
5956 Just r -> Just `fmap` fromPathPiece r
test/main.hs+1
@@ -34,6 +34,7 @@ main = hspec spec
3434spec :: Spec
3535spec = do
3636 describe "PathPiece" $ do
37+ prop "toPathPiece <=> fromPathPiece ()" $ \(p :: ()) -> (toPathPiece <=> fromPathPiece) p
3738 prop "toPathPiece <=> fromPathPiece Bool" $ \(p :: Bool) -> (toPathPiece <=> fromPathPiece) p
3839 prop "toPathPiece <=> fromPathPiece Int" $ \(p :: Int) -> (toPathPiece <=> fromPathPiece) p
3940 prop "toPathPiece <=> fromPathPiece Int8" $ \(p :: Int8) -> (toPathPiece <=> fromPathPiece) p