@@ -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