1- {-# LANGUAGE FlexibleContexts #-}
2- {-# LANGUAGE TypeOperators #-}
1+ {-# LANGUAGE AllowAmbiguousTypes #-}
2+ {-# LANGUAGE DataKinds #-}
3+ {-# LANGUAGE FlexibleContexts #-}
4+ {-# LANGUAGE FlexibleInstances #-}
5+ {-# LANGUAGE TypeOperators #-}
6+ {-# LANGUAGE TypeFamilies #-}
37
48module Data.Conduit.Process.Effectful
59 ( sourceProcessWithStreams
610 ) where
711
8- import Data.ByteString (ByteString )
9- import Data.Conduit (ConduitT , runConduit , (.|) )
10- import Data.Conduit.Process (StreamingProcessHandle ,
11- streamingProcess ,
12- streamingProcessHandleRaw ,
13- waitForStreamingProcess )
14- import Data.Void (Void )
15- import Effectful (Eff , IOE , Limit (Unlimited ),
16- Persistence (Ephemeral ),
17- UnliftStrategy (ConcUnlift ),
18- liftIO , withEffToIO , (:>) )
19- import Effectful.Concurrent.Async (Concurrent , Concurrently (.. ),
20- runConcurrently )
21- import Effectful.Exception (finally , onException )
22- import Effectful.Process (CreateProcess , Process ,
23- terminateProcess )
24- import System.Exit (ExitCode )
12+ import Control.Monad.Trans (lift )
13+ import Data.ByteString (ByteString )
14+ import qualified Data.ByteString as BS (null )
15+ import Data.ByteString.Builder.Extra (defaultChunkSize )
16+ import Data.Conduit (ConduitT , awaitForever ,
17+ runConduit , yield , (.|) )
18+ import Data.Functor (($>) )
19+ import Data.Streaming.Process.Effectful (InputSource , OutputSink ,
20+ StreamingProcessHandle ,
21+ isStdStream , osStdStream ,
22+ streamingProcess ,
23+ streamingProcessHandleRaw ,
24+ waitForStreamingProcess )
25+ import Data.Void (Void )
26+ import Effectful (Eff ,
27+ Limit (Unlimited ),
28+ Persistence (Ephemeral ),
29+ UnliftStrategy (ConcUnlift ),
30+ liftIO , withEffToIO , (:>) )
31+ import Effectful.Concurrent (Concurrent )
32+ import Effectful.Concurrent.Async (Concurrently (.. ),
33+ runConcurrently )
34+ import Effectful.Exception (finally , onException )
35+ import Effectful.FileSystem (FileSystem )
36+ import Effectful.FileSystem.IO (BufferMode (NoBuffering ),
37+ Handle , hClose ,
38+ hSetBuffering )
39+ import Effectful.FileSystem.IO.ByteString (hGetSome , hPut )
40+ import Effectful.Process (CreateProcess , Process ,
41+ StdStream (CreatePipe ),
42+ terminateProcess )
43+ import System.Exit (ExitCode )
44+
45+ instance (FileSystem :> es ) => InputSource (ConduitT ByteString o (Eff es ) () ) where
46+ isStdStream =
47+ (\ (Just h) -> hSetBuffering h NoBuffering $> sinkHandle h, Just CreatePipe )
48+
49+ instance (FileSystem :> es , r ~ () , r' ~ () ) =>
50+ InputSource (ConduitT ByteString o (Eff es ) r , Eff es r' ) where
51+ isStdStream =
52+ ( \ (Just h) -> hSetBuffering h NoBuffering $> (sinkHandle h, hClose h)
53+ , Just CreatePipe )
54+
55+ instance (FileSystem :> es ) => OutputSink (ConduitT i ByteString (Eff es ) () ) where
56+ osStdStream =
57+ ( \ (Just h) -> hSetBuffering h NoBuffering $> sourceHandle h
58+ , Just CreatePipe )
59+
60+ instance (FileSystem :> es , r ~ () , r' ~ () ) =>
61+ OutputSink (ConduitT i ByteString (Eff es ) r , Eff es r' ) where
62+ osStdStream =
63+ ( \ (Just h) -> hSetBuffering h NoBuffering $> (sourceHandle h, hClose h)
64+ , Just CreatePipe )
65+
66+ sinkHandle :: (FileSystem :> es ) => Handle -> ConduitT ByteString o (Eff es ) ()
67+ sinkHandle h = awaitForever (lift . hPut h)
68+
69+ sourceHandle ::
70+ (FileSystem :> es ) => Handle -> ConduitT i ByteString (Eff es ) ()
71+ sourceHandle h = do
72+ bs <- lift $ hGetSome h defaultChunkSize
73+ if BS. null bs
74+ then pure ()
75+ else yield bs >> sourceHandle h
2576
2677sourceProcessWithStreams ::
27- (Process :> es , Concurrent :> es , IOE :> es )
78+ (Process :> es , Concurrent :> es , FileSystem :> es )
2879 => CreateProcess
2980 -> ConduitT () ByteString (Eff es ) ()
3081 -> ConduitT ByteString Void (Eff es ) a
@@ -47,5 +98,5 @@ sourceProcessWithStreams cp producerStdin consumerStdout consumerStderr = do
4798 return (ec, resStdout, resStderr)
4899
49100terminateStreamingProcess ::
50- (Process :> es ) => StreamingProcessHandle -> Eff es ()
101+ (Process :> es ) => StreamingProcessHandle es -> Eff es ()
51102terminateStreamingProcess = terminateProcess . streamingProcessHandleRaw
0 commit comments