packages feed

symantic-http-client 0.0.0.20190324 → 0.0.1.20190410

raw patch · 2 files changed

+60/−38 lines, 2 filesdep ~base64-bytestringdep ~symantic-httpPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: base64-bytestring, symantic-http

API changes (from Hackage documentation)

+ Symantic.HTTP.Client: class ClientConnectionClass a (ts :: [*]) where {
+ Symantic.HTTP.Client: instance Symantic.HTTP.API.HTTP_Raw Symantic.HTTP.Client.Client
+ Symantic.HTTP.Client: instance Symantic.HTTP.Client.ClientConnectionClass Symantic.HTTP.Client.ClientResponse '[]
+ Symantic.HTTP.Client: instance Symantic.HTTP.Client.ClientConnectionClass a (t : ts)
+ Symantic.HTTP.Client: type family ClientConnectionConstraint a ts :: Constraint;
+ Symantic.HTTP.Client: }
- Symantic.HTTP.Client: Client :: ((ClientModifier -> k) -> requests) -> Client requests k
+ Symantic.HTTP.Client: Client :: ((ClientModifier -> k) -> callers) -> Client callers k
- Symantic.HTTP.Client: ClientError_DecodeFailure :: Text -> ClientResponse -> ClientError
+ Symantic.HTTP.Client: ClientError_DecodeFailure :: String -> ClientResponse -> ClientError
- Symantic.HTTP.Client: [unClient] :: Client requests k -> (ClientModifier -> k) -> requests
+ Symantic.HTTP.Client: [unClient] :: Client callers k -> (ClientModifier -> k) -> callers
- Symantic.HTTP.Client: client :: Client requests ClientRequest -> requests
+ Symantic.HTTP.Client: client :: Client callers ClientRequest -> callers
- Symantic.HTTP.Client: clientConnection :: forall a ts. MimeTypes ts (MimeDecodable a) => (Proxy ts -> Proxy a -> ClientRequest) -> ClientConnection a
+ Symantic.HTTP.Client: clientConnection :: (ClientConnectionClass a ts, ClientConnectionConstraint a ts) => (Proxy ts -> Proxy a -> ClientRequest) -> ClientConnection a
- Symantic.HTTP.Client: newtype Client requests k
+ Symantic.HTTP.Client: newtype Client callers k
- Symantic.HTTP.Client: runClient :: MimeTypes ts (MimeDecodable a) => ClientEnv -> (Proxy ts -> Proxy a -> ClientRequest) -> IO (Either ClientError a)
+ Symantic.HTTP.Client: runClient :: ClientConnectionConstraint a ts => ClientConnectionClass a ts => ClientEnv -> (Proxy ts -> Proxy a -> ClientRequest) -> IO (Either ClientError a)

Files

Symantic/HTTP/Client.hs view
@@ -17,12 +17,12 @@ import Data.Foldable (null, for_, toList) import Data.Function (($), (.), id, on) import Data.Functor (Functor(..), (<$>))+import Data.Kind (Constraint) import Data.Maybe (Maybe(..), maybe, fromMaybe) import Data.Ord (Ord(..)) import Data.Proxy (Proxy(..)) import Data.Semigroup (Semigroup(..))-import Data.String (IsString(..))-import Data.Text (Text)+import Data.String (IsString(..), String) import Data.Traversable (sequence) import Data.Tuple (fst) import GHC.Exts (fromList)@@ -42,7 +42,6 @@ import qualified Data.List as List import qualified Data.List.NonEmpty as NonEmpty import qualified Data.Sequence as Seq-import qualified Data.Text as Text import qualified Data.Text.Encoding as Text import qualified Data.Time.Clock as Time import qualified Network.HTTP.Client as Client@@ -56,20 +55,20 @@ import Symantic.HTTP.MIME  -- * Type 'Client'--- | @'Client' a k@ is a recipe to produce a 'ClientRequest'--- from arguments 'requests' (one per number of alternative routes)+-- | (@'Client' a k@) is a recipe to produce a 'ClientRequest'+-- from returned ('callers') (one per number of alternative routes) -- separated by (':!:'). ----- 'Client' is analogous to a printf using a format customized for HTTP routing.-newtype Client requests k+-- 'Client' is analogous to a printf using the API as a format customized for HTTP routing.+newtype Client callers k  =      Client- {    unClient :: (ClientModifier -> k) -> requests+ {    unClient :: (ClientModifier -> k) -> callers  } --- | @'client' requests@ returns the 'ClientRequest'+-- | @'client' callers@ returns the 'ClientRequest' -- builders from the given API.-client :: Client requests ClientRequest -> requests-client (Client requests) = requests ($ ini)+client :: Client callers ClientRequest -> callers+client (Client callers) = callers ($ ini) 	where 	ini = ClientRequest 	 {    clientReq_httpVersion = HTTP.http11@@ -114,7 +113,14 @@ instance HTTP_Header Client where 	header n = Client $ \k v -> k $ \req -> 		req{ clientReq_headers = clientReq_headers req Seq.|> (n, Web.toHeader v) }+instance HTTP_Raw Client where+	type RawConstraint Client = ()+	type RawArgs Client = HTTP.Method -> Proxy ('[]::[*]) -> Proxy ClientResponse -> ClientRequest+	type Raw Client = ClientRequest+	raw = Client $ \k meth Proxy Proxy -> k $ \req ->+		req{ clientReq_method = meth } instance HTTP_BasicAuth Client where+	type BasicAuthConstraint Client a = () 	type BasicAuthArgs Client a k = BasicAuthUser -> BasicAuthPass -> k 	basicAuth' realm = Client $ \k user pass -> k $ \req -> 		req{ clientReq_headers =@@ -201,9 +207,9 @@ 	 HTTP.Method -> 	 repr (ResponseArgs repr a ts) 	      (Response repr)-	response m = Client $ \k Proxy Proxy -> k $ \req ->+	response meth = Client $ \k Proxy Proxy -> k $ \req -> 		req-		 { clientReq_method = m+		 { clientReq_method = meth 		 , clientReq_accept = 			clientReq_accept req <> 			fromList (toList $ mediaTypes @ts @(MimeDecodable a))@@ -226,9 +232,9 @@ 	 HTTP.Method -> 	 repr (ResponseStreamArgs repr as ts framing) 	      (ResponseStream repr)-	responseStream m = Client $ \k Proxy Proxy Proxy -> k $ \req ->+	responseStream meth = Client $ \k Proxy Proxy Proxy -> k $ \req -> 		req-		 { clientReq_method = m+		 { clientReq_method = meth 		 , clientReq_accept = 			clientReq_accept req <> 			fromList (toList $ mediaTypes @ts @(MimeDecodable (FramingYield as)))@@ -272,7 +278,7 @@      -- | The server returned an error response  =   ClientError_FailureResponse ClientResponse      -- | The body could not be decoded at the expected type- |   ClientError_DecodeFailure Text ClientResponse+ |   ClientError_DecodeFailure String ClientResponse      -- | The content-type of the response is not supported  |   ClientError_UnsupportedContentType BS.ByteString ClientResponse      -- | There was a connection error, and no response was received@@ -342,7 +348,8 @@ -}  runClient ::- MimeTypes ts (MimeDecodable a) =>+ ClientConnectionConstraint a ts =>+ ClientConnectionClass a ts =>  ClientEnv ->  (Proxy ts -> Proxy a -> ClientRequest) ->  IO (Either ClientError a)@@ -352,23 +359,38 @@ 	unClientConn . 	clientConnection -clientConnection ::- forall a ts.- MimeTypes ts (MimeDecodable a) =>- (Proxy ts -> Proxy a -> ClientRequest) ->- ClientConnection a-clientConnection req = do-	clientRes <- doClientRequest $ req (Proxy::Proxy ts) (Proxy::Proxy a)-	let mtRes =-		fromMaybe "application/octet-stream" $-		List.lookup "Content-Type" $-		Client.responseHeaders clientRes-	case matchContent @ts @(MimeDecodable a) mtRes of-	 Nothing -> MC.throw $ ClientError_UnsupportedContentType mtRes clientRes-	 Just (MimeType mt) ->-		case mimeDecode mt $ Client.responseBody clientRes of-		 Left  err -> MC.throw $ ClientError_DecodeFailure (Text.pack err) clientRes-		 Right val -> return val+-- ** Class 'ClientConnectionClass'+-- | 'clientConnection' is different when 'ts' is empty:+-- no 'mimeDecode' is performed.+-- This is used by the 'raw' combinator.+class ClientConnectionClass a (ts::[*]) where+	type ClientConnectionConstraint a ts :: Constraint+	clientConnection ::+	 ClientConnectionConstraint a ts =>+	 (Proxy ts -> Proxy a -> ClientRequest) ->+	 ClientConnection a+instance ClientConnectionClass ClientResponse '[] where+	type ClientConnectionConstraint ClientResponse '[] = ()+	clientConnection req = do+		clientRes <- doClientRequest $ req+		 (Proxy::Proxy '[])+		 (Proxy::Proxy ClientResponse)+		return clientRes+instance ClientConnectionClass a (t ': ts) where+	type ClientConnectionConstraint a (t ': ts) =+	 MimeTypes (t ': ts) (MimeDecodable a)+	clientConnection req = do+		clientRes <- doClientRequest $ req (Proxy::Proxy (t ': ts)) (Proxy::Proxy a)+		let mtRes =+			fromMaybe "application/octet-stream" $+			List.lookup "Content-Type" $+			Client.responseHeaders clientRes+		case matchContent @(t ': ts) @(MimeDecodable a) mtRes of+		 Nothing -> MC.throw $ ClientError_UnsupportedContentType mtRes clientRes+		 Just (MimeType mt) ->+			case mimeDecode mt $ Client.responseBody clientRes of+			 Left err -> MC.throw $ ClientError_DecodeFailure err clientRes+			 Right a -> return a  doClientRequest :: ClientRequest -> ClientConnection ClientResponse doClientRequest clientReq = do
symantic-http-client.cabal view
@@ -2,12 +2,12 @@ -- PVP:  +-+------- breaking API changes --       | | +----- non-breaking API additions --       | | | +--- code changes with no API change-version: 0.0.0.20190324+version: 0.0.1.20190410 category: Protocol synopsis: symantic-http applied to the derivation of HTTP clients description:    This library applies <https://hackage.haskell.org/package/symantic-http symantic-http>-  to the building of an HTTP client (request building and encoding)+  to the building of an HTTP client (request building and response decoding)   based upon <https://hackage.haskell.org/package/http-client http-client>.   .   For learning how to use this library,@@ -60,9 +60,9 @@     -fno-warn-tabs     -- -fhide-source-paths   build-depends:-      symantic-http >= 0.0+      symantic-http >= 0.1.1     , base >= 4.10 && < 5-    , base64-bytestring >= 1.0.0.1+    , base64-bytestring >= 1.0     , bytestring >= 0.10     , containers >= 0.5     , http-api-data >= 0.4