@@ -11,6 +11,7 @@ module Web.HttpApiData.Internal where
12#if __GLASGOW_HASKELL__ < 710
12#if __GLASGOW_HASKELL__ < 710
13import Control.Applicative
13import Control.Applicative
14+import Data.Traversable (Traversable(traverse))
15import Control.Arrow ((&&&))
16import Control.Arrow ((&&&))
@@ -71,6 +72,38 @@ class FromHttpApiData a where
71 parseQueryParam :: Text -> Either Text a
72 parseQueryParam :: Text -> Either Text a
72 parseQueryParam = parseUrlPiece
73 parseQueryParam = parseUrlPiece
75+-- | Convert multiple values to a list of URL pieces.
77+-- >>> toUrlPieces [1, 2, 3]
79+toUrlPieces :: (Functor t, ToHttpApiData a) => t a -> t Text
80+toUrlPieces = fmap toUrlPiece
82+-- | Parse multiple URL pieces.
84+-- >>> parseUrlPieces ["true", "false"] :: Either Text [Bool]
86+-- >>> parseUrlPieces ["123", "hello", "world"] :: Either Text [Int]
87+-- Left "could not parse: `hello' (input does not start with a digit)"
88+parseUrlPieces :: (Traversable t, FromHttpApiData a) => t Text -> Either Text (t a)
89+parseUrlPieces = traverse parseUrlPiece
91+-- | Convert multiple values to a list of query parameter values.
93+-- >>> toQueryParams [fromGregorian 2015 10 03, fromGregorian 2015 12 01]
94+-- ["2015-10-03","2015-12-01"]
95+toQueryParams :: (Functor t, ToHttpApiData a) => t a -> t Text
96+toQueryParams = fmap toQueryParam
98+-- | Parse multiple query parameters.
100+-- >>> parseQueryParams ["1", "2", "3"] :: Either Text [Int]
102+-- >>> parseQueryParams ["64", "128", "256"] :: Either Text [Word8]
103+-- Left "out of bounds: `256' (should be between 0 and 255)"
104+parseQueryParams :: (Traversable t, FromHttpApiData a) => t Text -> Either Text (t a)
105+parseQueryParams = traverse parseQueryParam
74-- | Parse URL path piece in a @'Maybe'@.
107-- | Parse URL path piece in a @'Maybe'@.
76-- >>> parseUrlPieceMaybe "12" :: Maybe Int
109-- >>> parseUrlPieceMaybe "12" :: Maybe Int
@@ -271,7 +304,7 @@ readTextData = parseMaybeTextData (readMaybe . T.unpack)
271runReader :: Reader a -> Text -> Either Text a
304runReader :: Reader a -> Text -> Either Text a
272runReader reader input =
305runReader reader input =
273 case reader input of
306 case reader input of
274− Left err -> Left (T.pack err)
307+ Left err -> Left ("could not parse: `" <> input <> "' (" <> T.pack err <> ")")
275 Right (x, rest)
308 Right (x, rest)
276 | T.null rest -> Right x
309 | T.null rest -> Right x
277 | otherwise -> defaultParseError input
310 | otherwise -> defaultParseError input