@@ -2,6 +2,7 @@
2{-# LANGUAGE DeriveDataTypeable #-}
2{-# LANGUAGE DeriveDataTypeable #-}
3{-# LANGUAGE DeriveGeneric #-}
3{-# LANGUAGE DeriveGeneric #-}
4{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE FlexibleInstances #-}
5+{-# LANGUAGE FunctionalDependencies #-}
5{-# LANGUAGE KindSignatures #-}
6{-# LANGUAGE KindSignatures #-}
6{-# LANGUAGE MultiParamTypeClasses #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
7{-# LANGUAGE OverloadedStrings #-}
8{-# LANGUAGE OverloadedStrings #-}
@@ -38,13 +39,13 @@ type StreamGet = Stream 'GET
38type StreamPost = Stream 'POST
39type StreamPost = Stream 'POST
40-- | Stream endpoints may be implemented as producing a @StreamGenerator@ -- a function that itself takes two emit functions -- the first to be used on the first value the stream emits, and the second to be used on all subsequent values (to allow interspersed framing strategies such as comma separation).
41-- | Stream endpoints may be implemented as producing a @StreamGenerator@ -- a function that itself takes two emit functions -- the first to be used on the first value the stream emits, and the second to be used on all subsequent values (to allow interspersed framing strategies such as comma separation).
41−newtype StreamGenerator a = StreamGenerator {getStreamGenerator :: (a -> IO ()) -> (a -> IO ()) -> IO ()}
42+newtype StreamGenerator a = StreamGenerator {getStreamGenerator :: (a -> IO ()) -> (a -> IO ()) -> IO ()}
43-- | ToStreamGenerator is intended to be implemented for types such as Conduit, Pipe, etc. By implementing this class, all such streaming abstractions can be used directly as endpoints.
44-- | ToStreamGenerator is intended to be implemented for types such as Conduit, Pipe, etc. By implementing this class, all such streaming abstractions can be used directly as endpoints.
44−class ToStreamGenerator f a where
45+class ToStreamGenerator a b | a -> b where
45− toStreamGenerator :: f a -> StreamGenerator a
46+ toStreamGenerator :: a -> StreamGenerator b
47−instance ToStreamGenerator StreamGenerator a
48+instance ToStreamGenerator (StreamGenerator a) a
48 where toStreamGenerator x = x
49 where toStreamGenerator x = x
50-- | 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.
51-- | 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.
@@ -80,6 +81,18 @@ data ByteStringParser a = ByteStringParser {
80class FramingUnrender strategy a where
81class FramingUnrender strategy a where
81 unrenderFrames :: Proxy strategy -> Proxy a -> ByteStringParser (ByteStringParser (Either String ByteString))
82 unrenderFrames :: Proxy strategy -> Proxy a -> ByteStringParser (ByteStringParser (Either String ByteString))
84+-- | A framing strategy that does not do any framing at all, it just passes the input data
85+-- This will be used most of the time with binary data, such as files
88+instance FramingRender NoFraming a where
90+ boundary _ _ = BoundaryStrategyGeneral id
93+instance FramingUnrender NoFraming a where
94+ unrenderFrames _ _ = ByteStringParser (Just . (go,)) (go,)
95+ where go = ByteStringParser (Just . (, empty) . Right) ((, empty) . Right)
84-- | A simple framing strategy that has no header or termination, and inserts a newline character between each frame.
97-- | A simple framing strategy that has no header or termination, and inserts a newline character between each frame.
85-- This assumes that it is used with a Content-Type that encodes without newlines (e.g. JSON).
98-- This assumes that it is used with a Content-Type that encodes without newlines (e.g. JSON).