@@ -73,11 +73,15 @@ class FromHttpApiData a where
73 parseQueryParam :: Text -> Either Text a
73 parseQueryParam :: Text -> Either Text a
74 parseQueryParam = parseUrlPiece
74 parseQueryParam = parseUrlPiece
76+-- | Default parsing error.
77+defaultParseError :: Text -> Either Text a
78+defaultParseError input = Left ("could not convert: `" <> input <> "'")
76-- | Convert @'Maybe'@ parser into @'Either' 'Text'@ parser with default error message.
80-- | Convert @'Maybe'@ parser into @'Either' 'Text'@ parser with default error message.
77parseMaybeHttpApiData :: (Text -> Maybe a) -> (Text -> Either Text a)
81parseMaybeHttpApiData :: (Text -> Maybe a) -> (Text -> Either Text a)
78parseMaybeHttpApiData parse input =
82parseMaybeHttpApiData parse input =
79 case parse input of
83 case parse input of
80− Nothing -> Left ("could not convert: `" <> input <> "'")
84+ Nothing -> defaultParseError input
81 Just val -> Right val
85 Just val -> Right val
83-- | Convert to URL piece using @'Show'@ instance.
87-- | Convert to URL piece using @'Show'@ instance.
@@ -99,7 +103,7 @@ runReader reader input =
99 Left err -> Left (T.pack err)
103 Left err -> Left (T.pack err)
100 Right (x, rest)
104 Right (x, rest)
101 | T.null rest -> Right x
105 | T.null rest -> Right x
102− | otherwise -> Left ("could not convert: `" <> input <> "'")
106+ | otherwise -> defaultParseError input
104-- | Run @'Reader'@ to parse bounded integral value with bounds checking.
108-- | Run @'Reader'@ to parse bounded integral value with bounds checking.
105parseBounded :: forall a. (Bounded a, Integral a) => Reader Integer -> Text -> Either Text a
109parseBounded :: forall a. (Bounded a, Integral a) => Reader Integer -> Text -> Either Text a
@@ -112,6 +116,12 @@ parseBounded reader input = do
112 l = toInteger (minBound :: a)
116 l = toInteger (minBound :: a)
113 h = toInteger (maxBound :: a)
117 h = toInteger (maxBound :: a)
122+instance ToHttpApiData () where
115instance ToHttpApiData Bool where toUrlPiece = showUrlPiece
125instance ToHttpApiData Bool where toUrlPiece = showUrlPiece
116instance ToHttpApiData Double where toUrlPiece = showUrlPiece
126instance ToHttpApiData Double where toUrlPiece = showUrlPiece
117instance ToHttpApiData Float where toUrlPiece = showUrlPiece
127instance ToHttpApiData Float where toUrlPiece = showUrlPiece
@@ -131,6 +141,13 @@ instance ToHttpApiData Text where toUrlPiece = id
131instance ToHttpApiData L.Text where toUrlPiece = L.toStrict
141instance ToHttpApiData L.Text where toUrlPiece = L.toStrict
132instance ToHttpApiData Day where toUrlPiece = showUrlPiece
142instance ToHttpApiData Day where toUrlPiece = showUrlPiece
145+-- >>> parseUrlPiece "_" :: Either Text ()
147+instance FromHttpApiData () where
148+ parseUrlPiece "_" = pure ()
149+ parseUrlPiece s = defaultParseError s
134instance FromHttpApiData Bool where parseUrlPiece = readEitherUrlPiece
151instance FromHttpApiData Bool where parseUrlPiece = readEitherUrlPiece
135instance FromHttpApiData Double where parseUrlPiece = runReader rational
152instance FromHttpApiData Double where parseUrlPiece = runReader rational
136instance FromHttpApiData Float where parseUrlPiece = runReader rational
153instance FromHttpApiData Float where parseUrlPiece = runReader rational