packages feed

api-builder 0.5.0.0 → 0.6.0.0

raw patch · 8 files changed

+111/−10 lines, 8 filesdep +Cabaldep +api-builderdep +containersdep ~aesondep ~basedep ~bifunctors

Dependencies added: Cabal, api-builder, containers, datetime, hspec, http-client

Dependency ranges changed: aeson, base, bifunctors, bytestring, http-conduit, text, transformers

Files

api-builder.cabal view
@@ -1,14 +1,24 @@ name: api-builder-version: 0.5.0.0+version: 0.6.0.0 synopsis: Library for easily building REST API wrappers in Haskell license: BSD3 author: Fraser Murray maintainer: fraser.m.murray@gmail.com+homepage: https://github.com/intolerable/api-builder copyright: (c) Fraser Murray 2014 category: Network build-type: Simple cabal-version: >= 1.10 +source-repository head+  type: git+  location: git://github.com/intolerable/api-builder.git++source-repository this+  type: git+  location: git://github.com/intolerable/api-builder.git+  tag: v0.6.0.0+ library   exposed-modules:     Network.API.Builder@@ -20,16 +30,18 @@     Network.API.Builder.Receive     Network.API.Builder.Routes     Network.API.Builder.Send+    Network.API.Builder.Send.Multipart   build-depends:     base >= 4.6 && < 4.8,     aeson >= 0.7 && < 0.9,     attoparsec >= 0.11 && < 0.13,-    bifunctors,+    bifunctors == 4.*,     bytestring == 0.10.*,     either == 4.*,     HTTP == 4000.*,-    http-types == 0.8.*,+    http-client >= 0.4.7 && < 0.4.10,     http-conduit == 2.*,+    http-types == 0.8.*,     text == 1.*,     transformers >= 0.3 && < 0.5   hs-source-dirs: src/@@ -38,3 +50,44 @@     FlexibleInstances     OverloadedStrings   ghc-options: -Wall++test-suite test+  hs-source-dirs: test+  main-is: Spec.hs+  default-extensions:+    OverloadedStrings+    ScopedTypeVariables+  default-language: Haskell2010+  type: exitcode-stdio-1.0+  build-depends:+    base == 4.*,+    Cabal >= 1.16.0,+    api-builder,+    aeson,+    bytestring,+    datetime,+    hspec,+    http-conduit,+    text,+    transformers+  GHC-options: -Wall -Werror++test-suite test-io+  hs-source-dirs: test-io+  main-is: Spec.hs+  default-extensions:+    LambdaCase+  default-language: Haskell2010+  type: exitcode-stdio-1.0+  build-depends:+    base == 4.*,+    Cabal >= 1.16.0,+    api-builder,+    aeson,+    bytestring,+    containers,+    datetime,+    hspec,+    text,+    transformers+  GHC-options: -Wall -Werror
src/Network/API/Builder/Examples/StackOverflow.hs view
@@ -36,7 +36,7 @@ stackOverflow = basicBuilder "StackOverflow API" "http://api.stackexchange.com"  answersRoute :: Route-answersRoute = Route { fragments = [ "2.2", "questions" ]+answersRoute = Route { urlPieces = [ "2.2", "questions" ]                      , urlParams = [ "order" =. ("desc" :: Text)                                    , "sort" =. ("activity" :: Text)                                    , "site" =. ("stackoverflow" :: Text) ]
src/Network/API/Builder/Query.hs view
@@ -1,5 +1,6 @@ module Network.API.Builder.Query where +import Data.Monoid import Data.Text (Text) import qualified Data.Text as Text @@ -26,3 +27,12 @@ instance ToQuery a => ToQuery [a] where   toQuery _ [] = []   toQuery k xs = [(k, Text.intercalate "," $ map snd $ concatMap (toQuery k) xs)]++newtype IndexedList a = IndexedList [a]+  deriving (Show, Read, Eq)++instance ToQuery a => ToQuery (IndexedList a) where+  toQuery _ (IndexedList []) = []+  toQuery k (IndexedList l) =+    zipWith (\n (x, y) -> (x <> "[" <> tshow n <> "]", y)) ([0..] :: [Integer]) $ concatMap (toQuery k) l+    where tshow = Text.pack . show
src/Network/API/Builder/Receive.hs view
@@ -2,6 +2,7 @@  import Network.API.Builder.Error +import Control.Applicative import Data.Aeson hiding (decode, eitherDecode) import Data.Aeson.Parser import Data.Aeson.Types (parseEither)@@ -20,6 +21,18 @@  instance Receivable Value where   receive = useFromJSON++instance (Receivable a, Receivable b) => Receivable (a, b) where+  receive x = (,) <$> receive x <*> receive x++instance (Receivable a, Receivable b, Receivable c) => Receivable (a, b, c) where+  receive x = (,,) <$> receive x <*> receive x <*> receive x++instance (Receivable a, Receivable b, Receivable c, Receivable d) => Receivable (a, b, c, d) where+  receive x = (,,,) <$> receive x <*> receive x <*> receive x <*> receive x++instance (Receivable a, Receivable b, Receivable c, Receivable d, Receivable e) => Receivable (a, b, c, d, e) where+  receive x = (,,,,) <$> receive x <*> receive x <*> receive x <*> receive x <*> receive x  useFromJSON :: (FromJSON a, ErrorReceivable e) => Response ByteString -> Either (APIError e) a useFromJSON resp =
src/Network/API/Builder/Routes.hs view
@@ -1,6 +1,6 @@ module Network.API.Builder.Routes   ( Route(..)-  , URLFragment+  , URLPiece   , URLParam   , (=.)   , routeURL ) where@@ -15,7 +15,7 @@ import Network.API.Builder.Query  -- | Alias for @Text@ to store the URL fragments for each @Route@.-type URLFragment = Text+type URLPiece = Text  -- | Alias to @(Text, Maybe Text)@ used to store each query that gets --   tacked onto the request.@@ -34,7 +34,7 @@ -- | Main type for routes in the API. Used to represent the URL minus the actual --   endpoint URL as well as the query string and the HTTP method used to communicate --   with the server.-data Route = Route { fragments :: [URLFragment]+data Route = Route { urlPieces :: [URLPiece]                    , urlParams :: [URLParam]                    , httpMethod :: HTTP.Method }   deriving (Show, Read, Eq)@@ -45,10 +45,14 @@          -> Route -- ^ the @Route@ to process          -> Text -- ^ the finalized URL as a @Text@ routeURL baseURL (Route fs ps _) =-  let path = T.intercalate "/" fs-  in baseURL <> "/" <> path <> pathParamsSep fs <> buildParams ps+  baseURL <> firstSep <> path <> querySep <> buildParams ps+  where+    firstSep = if null fs then T.empty else "/"+    path = T.intercalate "/" fs+    querySep = if null ps then T.empty else pathParamsSep fs -pathParamsSep :: [URLFragment] -> Text++pathParamsSep :: [URLPiece] -> Text pathParamsSep [] = "?" pathParamsSep xs = if T.isInfixOf "." (last xs) then "?" else "/?" 
+ src/Network/API/Builder/Send/Multipart.hs view
@@ -0,0 +1,19 @@+module Network.API.Builder.Send.Multipart where++import Network.API.Builder.Builder+import Network.API.Builder.Routes+import Network.API.Builder.Send++import Control.Monad+import Control.Monad.IO.Class+import Network.HTTP.Client.MultipartFormData+import Network.HTTP.Conduit (Request)++data Multipart = Multipart [Part]+  deriving (Show)++sendMultipart :: MonadIO m => Builder -> Route -> Multipart -> m (Maybe Request)+sendMultipart b r (Multipart ps) = do+  case send b r () of+    Nothing -> return Nothing+    Just req -> liftM Just $ formDataBody ps req
+ test-io/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
+ test/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}