@@ -58,6 +58,9 @@ import Data.Data (Data)
58import qualified Data.ByteString.Builder as BS
58import qualified Data.ByteString.Builder as BS
59import qualified Network.HTTP.Types as H
59import qualified Network.HTTP.Types as H
61+import qualified Data.Attoparsec.Text as Atto
62+import qualified Data.Attoparsec.Time as Atto
63-- >>> data BasicAuthToken = BasicAuthToken Text deriving (Show)
66-- >>> data BasicAuthToken = BasicAuthToken Text deriving (Show)
@@ -577,27 +580,25 @@ instance FromHttpApiData L.Text where parseUrlPiece = Right . L.fromStrict
578-- >>> toGregorian <$> parseUrlPiece "2016-12-01"
581-- >>> toGregorian <$> parseUrlPiece "2016-12-01"
579-- Right (2016,12,1)
582-- Right (2016,12,1)
580−instance FromHttpApiData Day where parseUrlPiece = readTextData
583+instance FromHttpApiData Day where parseUrlPiece = runAtto Atto.day
582−timeParseUrlPiece :: ParseTime t => String -> Text -> Either Text t
583−timeParseUrlPiece fmt = parseMaybeTextData (timeParseUrlPieceMaybe . T.unpack)
585− timeParseUrlPieceMaybe = parseTime defaultTimeLocale (iso8601DateFormat (Just fmt))
588-- >>> parseUrlPiece "2015-10-03T14:55:01" :: Either Text LocalTime
586-- >>> parseUrlPiece "2015-10-03T14:55:01" :: Either Text LocalTime
589-- Right 2015-10-03 14:55:01
587-- Right 2015-10-03 14:55:01
590−instance FromHttpApiData LocalTime where parseUrlPiece = timeParseUrlPiece "%H:%M:%S"
588+instance FromHttpApiData LocalTime where parseUrlPiece = runAtto Atto.localTime
593-- >>> parseUrlPiece "2015-10-03T14:55:01+0000" :: Either Text ZonedTime
591-- >>> parseUrlPiece "2015-10-03T14:55:01+0000" :: Either Text ZonedTime
594-- Right 2015-10-03 14:55:01 +0000
592-- Right 2015-10-03 14:55:01 +0000
594+-- >>> parseQueryParam "2016-12-31T01:00:00Z" :: Either Text ZonedTime
595+-- Right 2016-12-31 01:00:00 +0000
595−instance FromHttpApiData ZonedTime where parseUrlPiece = timeParseUrlPiece "%H:%M:%S%z"
596+instance FromHttpApiData ZonedTime where parseUrlPiece = runAtto Atto.zonedTime
598-- >>> parseUrlPiece "2015-10-03T00:14:24Z" :: Either Text UTCTime
599-- >>> parseUrlPiece "2015-10-03T00:14:24Z" :: Either Text UTCTime
599-- Right 2015-10-03 00:14:24 UTC
600-- Right 2015-10-03 00:14:24 UTC
600−instance FromHttpApiData UTCTime where parseUrlPiece = timeParseUrlPiece "%H:%M:%SZ"
601+instance FromHttpApiData UTCTime where parseUrlPiece = runAtto Atto.utcTime
602instance FromHttpApiData NominalDiffTime where parseUrlPiece = fmap fromInteger . parseUrlPiece
603instance FromHttpApiData NominalDiffTime where parseUrlPiece = fmap fromInteger . parseUrlPiece
@@ -650,3 +651,12 @@ instance FromHttpApiData a => FromHttpApiData (LenientData a) where
650 parseUrlPiece = Right . LenientData . parseUrlPiece
651 parseUrlPiece = Right . LenientData . parseUrlPiece
651 parseHeader = Right . LenientData . parseHeader
652 parseHeader = Right . LenientData . parseHeader
652 parseQueryParam = Right . LenientData . parseQueryParam
653 parseQueryParam = Right . LenientData . parseQueryParam
655+-------------------------------------------------------------------------------
656+-- Attoparsec helpers
657+-------------------------------------------------------------------------------
659+runAtto :: Atto.Parser a -> Text -> Either Text a
660+runAtto p t = case Atto.parseOnly (p <* Atto.endOfInput) t of
661+ Left err -> Left (T.pack err)