packages feed

http-api-data 0.1.1.1 → 0.2

raw patch · 5 files changed

+122/−32 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Web.HttpApiData.Internal: parseBoundedCaseInsensitiveTextData :: (Show a, Bounded a, Enum a) => Text -> Either Text a
- Web.HttpApiData.Internal: readEitherTextData :: Read a => Text -> Either Text a
- Web.HttpApiData.Internal: readMaybeTextData :: Read a => Text -> Maybe a
+ Web.HttpApiData: parseBoundedTextData :: (Show a, Bounded a, Enum a) => Text -> Either Text a
+ Web.HttpApiData: parseHeaderMaybe :: FromHttpApiData a => ByteString -> Maybe a
+ Web.HttpApiData: parseHeaderWithPrefix :: FromHttpApiData a => ByteString -> ByteString -> Either Text a
+ Web.HttpApiData: parseQueryParamMaybe :: FromHttpApiData a => Text -> Maybe a
+ Web.HttpApiData: parseQueryParamWithPrefix :: FromHttpApiData a => Text -> Text -> Either Text a
+ Web.HttpApiData: parseUrlPieceMaybe :: FromHttpApiData a => Text -> Maybe a
+ Web.HttpApiData: parseUrlPieceWithPrefix :: FromHttpApiData a => Text -> Text -> Either Text a
+ Web.HttpApiData: readTextData :: Read a => Text -> Either Text a
+ Web.HttpApiData: showTextData :: Show a => a -> Text
+ Web.HttpApiData.Internal: parseBoundedTextData :: (Show a, Bounded a, Enum a) => Text -> Either Text a
+ Web.HttpApiData.Internal: parseHeaderWithPrefix :: FromHttpApiData a => ByteString -> ByteString -> Either Text a
+ Web.HttpApiData.Internal: parseQueryParamWithPrefix :: FromHttpApiData a => Text -> Text -> Either Text a
+ Web.HttpApiData.Internal: readTextData :: Read a => Text -> Either Text a

Files

CHANGELOG.md view
@@ -1,3 +1,12 @@+0.2+---++* Export helper functions from `Web.HttpApiData`:+    * `parseUrlPieceMaybe`, `parseHeaderMaybe`, `parseQueryParamMaybe`+    * `parseUrlPieceWithPrefix`, `parseHeaderWithPrefix`, `parseQueryParamWithPrefix`+    * `showTextData`, `readTextData`, `parseBoundedTextData`+* Fix AMP related warnings+ 0.1.1 --- 
Web/HttpApiData.hs view
@@ -8,6 +8,21 @@   -- * Classes   ToHttpApiData (..),   FromHttpApiData (..),++  -- * @'Maybe'@ parsers+  parseUrlPieceMaybe,+  parseHeaderMaybe,+  parseQueryParamMaybe,++  -- * Prefix parsers+  parseUrlPieceWithPrefix,+  parseHeaderWithPrefix,+  parseQueryParamWithPrefix,++  -- * Other helpers+  showTextData,+  readTextData,+  parseBoundedTextData, ) where  import Web.HttpApiData.Internal
Web/HttpApiData/Internal.hs view
@@ -9,11 +9,14 @@ -- such as URL pieces, headers and query parameters. module Web.HttpApiData.Internal where +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Arrow ((&&&))  import Data.Monoid import Data.ByteString (ByteString)+import qualified Data.ByteString as BS  import Data.Int import Data.Word@@ -24,7 +27,7 @@ import qualified Data.Text as T import qualified Data.Text.Lazy as L -import Data.Time (Day)+import Data.Time import Data.Version  #if MIN_VERSION_base(4,8,0)@@ -101,7 +104,9 @@     Just val -> Right val  #if USE_TEXT_SHOW--- | Convert to URL piece using @'TextShow'@ instance.+-- | /Lower case/.+--+-- Convert to URL piece using @'TextShow'@ instance. -- The result is always lower cased. -- -- >>> showTextData True@@ -121,7 +126,9 @@ showTextData :: TextShow a => a -> Text showTextData = T.toLower . showt #else--- | Convert to URL piece using @'Show'@ instance.+-- | /Lower case/.+--+-- Convert to URL piece using @'Show'@ instance. -- The result is always lower cased. -- -- >>> showTextData True@@ -141,8 +148,11 @@ showt = T.pack . show #endif --- | Parse given text case insensitive and return the rest of the input.+-- | /Case insensitive/. --+-- Parse given text case insensitive and then parse the rest of the input+-- using @'parseUrlPiece'@.+-- -- >>> parseUrlPieceWithPrefix "Just " "just 10" :: Either Text Int -- Right 10 -- >>> parseUrlPieceWithPrefix "Left " "left" :: Either Text Bool@@ -161,12 +171,49 @@   where     (prefix, rest) = T.splitAt (T.length pattern) input +-- $setup+-- >>> data BasicAuthToken = BasicAuthToken Text deriving (Show)+-- >>> instance FromHttpApiData BasicAuthToken where parseHeader h = BasicAuthToken <$> parseHeaderWithPrefix "Basic " h; parseQueryParam p = BasicAuthToken <$> parseQueryParam p++-- | Parse given bytestring then parse the rest of the input using @'parseHeader'@.+--+-- @+-- data BasicAuthToken = BasicAuthToken Text deriving (Show)+--+-- instance FromHttpApiData BasicAuthToken where+--   parseHeader h     = BasicAuthToken \<$\> parseHeaderWithPrefix "Basic " h+--   parseQueryParam p = BasicAuthToken \<$\> parseQueryParam p+-- @+--+-- >>> parseHeader "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" :: Either Text BasicAuthToken+-- Right (BasicAuthToken "QWxhZGRpbjpvcGVuIHNlc2FtZQ==")+parseHeaderWithPrefix :: FromHttpApiData a => ByteString -> ByteString -> Either Text a+parseHeaderWithPrefix pattern input+  | pattern `BS.isPrefixOf` input = parseHeader (BS.drop (BS.length pattern) input)+  | otherwise                     = defaultParseError (showt input)++-- | /Case insensitive/.+--+-- Parse given text case insensitive and then parse the rest of the input+-- using @'parseQueryParam'@.+--+-- >>> parseQueryParamWithPrefix "z" "z10" :: Either Text Int+-- Right 10+parseQueryParamWithPrefix :: FromHttpApiData a => Text -> Text -> Either Text a+parseQueryParamWithPrefix pattern input+  | T.toLower pattern == T.toLower prefix = parseQueryParam rest+  | otherwise                             = defaultParseError input+  where+    (prefix, rest) = T.splitAt (T.length pattern) input+ #if USE_TEXT_SHOW--- | Parse values case insensitively based on @'TextShow'@ instance.+-- | /Case insensitive/. ----- >>> parseBoundedCaseInsensitiveTextData "true" :: Either Text Bool+-- Parse values case insensitively based on @'TextShow'@ instance.+--+-- >>> parseBoundedTextData "true" :: Either Text Bool -- Right True--- >>> parseBoundedCaseInsensitiveTextData "FALSE" :: Either Text Bool+-- >>> parseBoundedTextData "FALSE" :: Either Text Bool -- Right False -- -- This can be used as a default implementation for enumeration types:@@ -178,36 +225,47 @@ --   showt = genericShowt -- -- instance FromHttpApiData MyData where---   parseUrlPiece = parseBoundedCaseInsensitiveTextData+--   parseUrlPiece = parseBoundedTextData -- @-parseBoundedCaseInsensitiveTextData :: forall a. (TextShow a, Bounded a, Enum a) => Text -> Either Text a+parseBoundedTextData :: (TextShow a, Bounded a, Enum a) => Text -> Either Text a #else--- | Parse values case insensitively based on @'Show'@ instance.+-- | /Case insensitive/. ----- >>> parseBoundedCaseInsensitiveTextData "true" :: Either Text Bool+-- Parse values case insensitively based on @'Show'@ instance.+--+-- >>> parseBoundedTextData "true" :: Either Text Bool -- Right True--- >>> parseBoundedCaseInsensitiveTextData "FALSE" :: Either Text Bool+-- >>> parseBoundedTextData "FALSE" :: Either Text Bool -- Right False -- -- This can be used as a default implementation for enumeration types: -- -- >>> data MyData = Foo | Bar | Baz deriving (Show, Bounded, Enum)--- >>> instance FromHttpApiData MyData where parseUrlPiece = parseBoundedCaseInsensitiveTextData+-- >>> instance FromHttpApiData MyData where parseUrlPiece = parseBoundedTextData -- >>> parseUrlPiece "foo" :: Either Text MyData -- Right Foo-parseBoundedCaseInsensitiveTextData :: forall a. (Show a, Bounded a, Enum a) => Text -> Either Text a+parseBoundedTextData :: (Show a, Bounded a, Enum a) => Text -> Either Text a #endif-parseBoundedCaseInsensitiveTextData = parseMaybeTextData (flip lookup values . T.toLower)+parseBoundedTextData = parseMaybeTextData (flip lookup values . T.toLower)   where-    values = map (showTextData &&& id) [minBound..maxBound :: a]---- | Parse URL piece using @'Read'@ instance.-readMaybeTextData :: Read a => Text -> Maybe a-readMaybeTextData = readMaybe . T.unpack+    values = map (showTextData &&& id) [minBound..maxBound]  -- | Parse URL piece using @'Read'@ instance.-readEitherTextData :: Read a => Text -> Either Text a-readEitherTextData = parseMaybeTextData readMaybeTextData+--+-- Use for types which do not involve letters:+--+-- >>> readTextData "1991-06-02" :: Either Text Day+-- Right 1991-06-02+--+-- This parser is case sensitive and will not match @'showTextData'@+-- in presense of letters:+--+-- >>> readTextData (showTextData True) :: Either Text Bool+-- Left "could not parse: `true'"+--+-- See @'parseBoundedTextData'@.+readTextData :: Read a => Text -> Either Text a+readTextData = parseMaybeTextData (readMaybe . T.unpack)  -- | Run @'Reader'@ as HTTP API data parser. runReader :: Reader a -> Text -> Either Text a@@ -226,7 +284,7 @@ parseBounded reader input = do   n <- runReader reader input   if (n > h || n < l)-    then Left  ("out of bounds: `" <> input <> "' (should be between " <> T.pack (show l) <> " and " <> T.pack (show h) <> ")")+    then Left  ("out of bounds: `" <> input <> "' (should be between " <> showt l <> " and " <> showt h <> ")")     else Right (fromInteger n)   where     l = toInteger (minBound :: a)@@ -267,6 +325,10 @@ instance ToHttpApiData Word16   where toUrlPiece = showt instance ToHttpApiData Word32   where toUrlPiece = showt instance ToHttpApiData Word64   where toUrlPiece = showt++-- |+-- >>> toUrlPiece (fromGregorian 2015 10 03)+-- "2015-10-03" instance ToHttpApiData Day      where toUrlPiece = T.pack . show  instance ToHttpApiData String   where toUrlPiece = T.pack@@ -302,13 +364,13 @@ -- >>> parseUrlPiece "_" :: Either Text () -- Right () instance FromHttpApiData () where-  parseUrlPiece "_" = return ()+  parseUrlPiece "_" = pure ()   parseUrlPiece s   = defaultParseError s  instance FromHttpApiData Char where   parseUrlPiece s =     case T.uncons s of-      Just (c, s') | T.null s' -> return c+      Just (c, s') | T.null s' -> pure c       _                        -> defaultParseError s  -- |@@ -317,16 +379,17 @@ instance FromHttpApiData Version where   parseUrlPiece s =     case reverse (readP_to_S parseVersion (T.unpack s)) of-      ((x, ""):_) -> return x+      ((x, ""):_) -> pure x       _           -> defaultParseError s  #if MIN_VERSION_base(4,8,0)+-- | Parsing a @'Void'@ value is always an error, considering @'Void'@ as a data type with no constructors. instance FromHttpApiData Void where   parseUrlPiece _ = Left "Void cannot be parsed!" #endif -instance FromHttpApiData Bool     where parseUrlPiece = parseBoundedCaseInsensitiveTextData-instance FromHttpApiData Ordering where parseUrlPiece = parseBoundedCaseInsensitiveTextData+instance FromHttpApiData Bool     where parseUrlPiece = parseBoundedTextData+instance FromHttpApiData Ordering where parseUrlPiece = parseBoundedTextData instance FromHttpApiData Double   where parseUrlPiece = runReader rational instance FromHttpApiData Float    where parseUrlPiece = runReader rational instance FromHttpApiData Int      where parseUrlPiece = parseBounded (signed decimal)@@ -343,8 +406,12 @@ instance FromHttpApiData String   where parseUrlPiece = Right . T.unpack instance FromHttpApiData Text     where parseUrlPiece = Right instance FromHttpApiData L.Text   where parseUrlPiece = Right . L.fromStrict-instance FromHttpApiData Day      where parseUrlPiece = readEitherTextData +-- |+-- >>> toGregorian <$> parseUrlPiece "2016-12-01"+-- Right (2016,12,1)+instance FromHttpApiData Day      where parseUrlPiece = readTextData+ instance FromHttpApiData All where parseUrlPiece = fmap All . parseUrlPiece instance FromHttpApiData Any where parseUrlPiece = fmap Any . parseUrlPiece @@ -359,7 +426,7 @@ -- Right (Just 123) instance FromHttpApiData a => FromHttpApiData (Maybe a) where   parseUrlPiece s-    | T.toLower (T.take 7 s) == "nothing" = return Nothing+    | T.toLower (T.take 7 s) == "nothing" = pure Nothing     | otherwise                           = Just <$> parseUrlPieceWithPrefix "Just " s  -- |
http-api-data.cabal view
@@ -1,5 +1,5 @@ name:            http-api-data-version:         0.1.1.1+version:         0.2 license:         BSD3 license-file:    LICENSE author:          Nickolay Kudasov <nickolay.kudasov@gmail.com>
test/Spec.hs view
@@ -17,7 +17,6 @@ import Test.QuickCheck  import Web.HttpApiData-import Web.HttpApiData.Internal  instance Arbitrary T.Text where   arbitrary = T.pack <$> arbitrary