git.iko.soy/typeable/servant
on master help sign in
make client endpoint give polymorphic result
commit0c77a2b4b0581a6d91fd3c99229d200ef402602b authorGershom <gershom@awakesecurity.com> dateTue 24 Oct 2017, 17:26 (9 years ago) parente75a3cc
3 files changed+12−9
servant-client-core/src/Servant/Client/Core/Internal/HasClient.hs+3−5 servant/src/Servant/API.hs+2−1 servant/src/Servant/API/Stream.hs+7−3
servant-client-core/src/Servant/Client/Core/Internal/HasClient.hs+3−5
@@ -4,7 +4,6 @@
44{-# LANGUAGE FlexibleInstances #-}
55{-# LANGUAGE InstanceSigs #-}
66{-# LANGUAGE MultiParamTypeClasses #-}
7−{-# LANGUAGE RankNTypes #-}
87{-# LANGUAGE OverloadedStrings #-}
98{-# LANGUAGE PolyKinds #-}
109{-# LANGUAGE ScopedTypeVariables #-}
@@ -48,6 +47,7 @@ import Servant.API ((:<|>) ((:<|>)), (:>),
4847 QueryParams, Raw,
4948 ReflectMethod (..),
5049 RemoteHost, ReqBody,
50+ ResultStream(..),
5151 Stream,
5252 Summary, ToHttpApiData,
5353 Vault, Verb,
@@ -253,21 +253,19 @@ instance OVERLAPPING_
253253 , getHeadersHList = buildHeadersTo . toList $ responseHeaders response
254254 }
255255
256−data ResultStream a = ResultStream ((forall b. (IO (Maybe (Either String a)) -> IO b) -> IO b))
257−
258256instance OVERLAPPABLE_
259257 ( RunClient m, MimeUnrender ct a, ReflectMethod method,
260258 FramingUnrender framing a, BuildFromStream a (f a)
261259 ) => HasClient m (Stream method framing ct (f a)) where
262260
263− type Client m (Stream method framing ct (f a)) = m (ResultStream a)
261+ type Client m (Stream method framing ct (f a)) = m (f a)
264262
265263 clientWithRoute _pm Proxy req = do
266264 sresp <- streamingRequest req
267265 { requestAccept = fromList [contentType (Proxy :: Proxy ct)]
268266 , requestMethod = reflectMethod (Proxy :: Proxy method)
269267 }
270− return $ ResultStream $ \k ->
268+ return . buildFromStream $ ResultStream $ \k ->
271269 runStreamingResponse sresp $ \(status,_headers,_httpversion,reader) -> do
272270 when (H.statusCode status /= 200) $ error "bad status" --fixme
273271 let unrender = unrenderFrames (Proxy :: Proxy framing) (Proxy :: Proxy a)
servant/src/Servant/API.hs+2−1
@@ -84,7 +84,8 @@ import Servant.API.QueryParam (QueryFlag, QueryParam,
8484 QueryParams)
8585import Servant.API.Raw (Raw)
8686import Servant.API.Stream (Stream, StreamGenerator (..),
87− ToStreamGenerator (..), BuildFromStream (..),
87+ ToStreamGenerator (..),
88+ ResultStream(..), BuildFromStream (..),
8889 ByteStringParser (..),
8990 FramingRender (..), BoundaryStrategy (..),
9091 FramingUnrender (..),
servant/src/Servant/API/Stream.hs+7−3
@@ -6,6 +6,7 @@
66{-# LANGUAGE MultiParamTypeClasses #-}
77{-# LANGUAGE OverloadedStrings #-}
88{-# LANGUAGE PolyKinds #-}
9+{-# LANGUAGE RankNTypes #-}
910{-# LANGUAGE TupleSections #-}
1011{-# OPTIONS_HADDOCK not-home #-}
1112
@@ -35,11 +36,14 @@ class ToStreamGenerator f a where
3536instance ToStreamGenerator StreamGenerator a
3637 where toStreamGenerator x = x
3738
38−-- | BuildFromStream is intended to be implemented for types such as Conduit, Pipe, etc. By implementing this class, all such streaming abstractions can be used directly on the client side for talking to streaming endpoints. The streams we build from are represented as lazy lists of elements interspersed with possible errors.
39+-- | Clients reading from streaming endpoints can be implemented as producing a @ResultStream@ that captures the setup, takedown, and incremental logic for a read, being an IO continuation that takes a producer of Just either values or errors that terminates with a Nothing.
40+data ResultStream a = ResultStream ((forall b. (IO (Maybe (Either String a)) -> IO b) -> IO b))
41+
42+-- | BuildFromStream is intended to be implemented for types such as Conduit, Pipe, etc. By implementing this class, all such streaming abstractions can be used directly on the client side for talking to streaming endpoints.
3943class BuildFromStream a b where
40− buildFromStream :: [Either String a] -> b
44+ buildFromStream :: ResultStream a -> b
4145
42−instance BuildFromStream a [Either String a]
46+instance BuildFromStream a (ResultStream a)
4347 where buildFromStream x = x
4448
4549-- | The FramingRender class provides the logic for emitting a framing strategy. The strategy emits a header, followed by boundary-delimited data, and finally a termination character. For many strategies, some of these will just be empty bytestrings.