{-# options_haddock prune #-}

-- |Description: Process Interpreters, Internal
module Polysemy.Process.Interpreter.Process where

import Control.Concurrent.STM.TBMQueue (TBMQueue)
import qualified Polysemy.Conc as Conc
import Polysemy.Conc.Async (withAsync_)
import qualified Polysemy.Conc.Data.QueueResult as QueueResult
import qualified Polysemy.Conc.Effect.Queue as Queue
import Polysemy.Conc.Effect.Queue (Queue)
import Polysemy.Conc.Effect.Race (Race)
import Polysemy.Conc.Effect.Scoped (Scoped)
import Polysemy.Conc.Interpreter.Queue.TBM (interpretQueueTBMWith, withTBMQueue)
import Polysemy.Conc.Interpreter.Scoped (interpretScopedResumableWith_)
import Polysemy.Resume (Stop, resumeOr, resume_, stop, type (!!))
import Prelude hiding (fromException)

import Polysemy.Process.Data.ProcessError (ProcessError (Terminated))
import Polysemy.Process.Data.ProcessKill (ProcessKill (KillAfter, KillImmediately, KillNever))
import Polysemy.Process.Data.ProcessOptions (ProcessOptions (ProcessOptions))
import qualified Polysemy.Process.Effect.Process as Process
import Polysemy.Process.Effect.Process (Process)
import qualified Polysemy.Process.Effect.ProcessOutput as ProcessOutput
import Polysemy.Process.Effect.ProcessOutput (ProcessOutput)
import qualified Polysemy.Process.Effect.SystemProcess as SystemProcess
import Polysemy.Process.Effect.SystemProcess (SystemProcess, withSystemProcess)
import Polysemy.Process.Interpreter.ProcessOutput (
  interpretProcessOutputId,
  interpretProcessOutputLines,
  interpretProcessOutputText,
  interpretProcessOutputTextLines,
  )

newtype In a =
  In { forall a. In a -> a
unIn :: a }
  deriving stock (In a -> In a -> Bool
(In a -> In a -> Bool) -> (In a -> In a -> Bool) -> Eq (In a)
forall a. Eq a => In a -> In a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: In a -> In a -> Bool
$c/= :: forall a. Eq a => In a -> In a -> Bool
== :: In a -> In a -> Bool
$c== :: forall a. Eq a => In a -> In a -> Bool
Eq, Int -> In a -> ShowS
[In a] -> ShowS
In a -> String
(Int -> In a -> ShowS)
-> (In a -> String) -> ([In a] -> ShowS) -> Show (In a)
forall a. Show a => Int -> In a -> ShowS
forall a. Show a => [In a] -> ShowS
forall a. Show a => In a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [In a] -> ShowS
$cshowList :: forall a. Show a => [In a] -> ShowS
show :: In a -> String
$cshow :: forall a. Show a => In a -> String
showsPrec :: Int -> In a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> In a -> ShowS
Show)

newtype Out a =
  Out { forall a. Out a -> a
unOut :: a }
  deriving stock (Out a -> Out a -> Bool
(Out a -> Out a -> Bool) -> (Out a -> Out a -> Bool) -> Eq (Out a)
forall a. Eq a => Out a -> Out a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Out a -> Out a -> Bool
$c/= :: forall a. Eq a => Out a -> Out a -> Bool
== :: Out a -> Out a -> Bool
$c== :: forall a. Eq a => Out a -> Out a -> Bool
Eq, Int -> Out a -> ShowS
[Out a] -> ShowS
Out a -> String
(Int -> Out a -> ShowS)
-> (Out a -> String) -> ([Out a] -> ShowS) -> Show (Out a)
forall a. Show a => Int -> Out a -> ShowS
forall a. Show a => [Out a] -> ShowS
forall a. Show a => Out a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Out a] -> ShowS
$cshowList :: forall a. Show a => [Out a] -> ShowS
show :: Out a -> String
$cshow :: forall a. Show a => Out a -> String
showsPrec :: Int -> Out a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Out a -> ShowS
Show)

newtype Err a =
  Err { forall a. Err a -> a
unErr :: a }
  deriving stock (Err a -> Err a -> Bool
(Err a -> Err a -> Bool) -> (Err a -> Err a -> Bool) -> Eq (Err a)
forall a. Eq a => Err a -> Err a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Err a -> Err a -> Bool
$c/= :: forall a. Eq a => Err a -> Err a -> Bool
== :: Err a -> Err a -> Bool
$c== :: forall a. Eq a => Err a -> Err a -> Bool
Eq, Int -> Err a -> ShowS
[Err a] -> ShowS
Err a -> String
(Int -> Err a -> ShowS)
-> (Err a -> String) -> ([Err a] -> ShowS) -> Show (Err a)
forall a. Show a => Int -> Err a -> ShowS
forall a. Show a => [Err a] -> ShowS
forall a. Show a => Err a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Err a] -> ShowS
$cshowList :: forall a. Show a => [Err a] -> ShowS
show :: Err a -> String
$cshow :: forall a. Show a => Err a -> String
showsPrec :: Int -> Err a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Err a -> ShowS
Show)

data ProcessQueues o e =
  ProcessQueues {
    forall o e. ProcessQueues o e -> TBMQueue (In ByteString)
pqIn :: TBMQueue (In ByteString),
    forall o e. ProcessQueues o e -> TBMQueue (Out o)
pqOut :: TBMQueue (Out o),
    forall o e. ProcessQueues o e -> TBMQueue (Err e)
pqErr :: TBMQueue (Err e)
  }

interpretQueues ::
  Members [Resource, Race, Embed IO] r =>
  ProcessQueues o e ->
  InterpretersFor [Queue (In ByteString), Queue (Out o), Queue (Err e)] r
interpretQueues :: forall (r :: [(* -> *) -> * -> *]) o e.
Members '[Resource, Race, Embed IO] r =>
ProcessQueues o e
-> InterpretersFor
     '[Queue (In ByteString), Queue (Out o), Queue (Err e)] r
interpretQueues (ProcessQueues TBMQueue (In ByteString)
inQ TBMQueue (Out o)
outQ TBMQueue (Err e)
errQ) =
  TBMQueue (Err e) -> InterpreterFor (Queue (Err e)) r
forall d (r :: [(* -> *) -> * -> *]).
Members '[Race, Embed IO] r =>
TBMQueue d -> InterpreterFor (Queue d) r
interpretQueueTBMWith TBMQueue (Err e)
errQ (Sem (Queue (Err e) : r) a -> Sem r a)
-> (Sem
      (Queue (In ByteString) : Queue (Out o) : Queue (Err e) : r) a
    -> Sem (Queue (Err e) : r) a)
-> Sem
     (Queue (In ByteString) : Queue (Out o) : Queue (Err e) : r) a
-> Sem r a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  TBMQueue (Out o)
-> InterpreterFor (Queue (Out o)) (Queue (Err e) : r)
forall d (r :: [(* -> *) -> * -> *]).
Members '[Race, Embed IO] r =>
TBMQueue d -> InterpreterFor (Queue d) r
interpretQueueTBMWith TBMQueue (Out o)
outQ (Sem (Queue (Out o) : Queue (Err e) : r) a
 -> Sem (Queue (Err e) : r) a)
-> (Sem
      (Queue (In ByteString) : Queue (Out o) : Queue (Err e) : r) a
    -> Sem (Queue (Out o) : Queue (Err e) : r) a)
-> Sem
     (Queue (In ByteString) : Queue (Out o) : Queue (Err e) : r) a
-> Sem (Queue (Err e) : r) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  TBMQueue (In ByteString)
-> InterpreterFor
     (Queue (In ByteString)) (Queue (Out o) : Queue (Err e) : r)
forall d (r :: [(* -> *) -> * -> *]).
Members '[Race, Embed IO] r =>
TBMQueue d -> InterpreterFor (Queue d) r
interpretQueueTBMWith TBMQueue (In ByteString)
inQ

handleProcessWithQueues ::
   o e m r a .
  Members [Queue (In ByteString), Queue (Out o), Queue (Err e), Stop ProcessError] r =>
  Process ByteString o e m a ->
  Sem r a
handleProcessWithQueues :: forall o e (m :: * -> *) (r :: [(* -> *) -> * -> *]) a.
Members
  '[Queue (In ByteString), Queue (Out o), Queue (Err e),
    Stop ProcessError]
  r =>
Process ByteString o e m a -> Sem r a
handleProcessWithQueues = \case
  Process ByteString o e m a
Process.Recv ->
    Sem r (QueueResult (Out a))
forall d (r :: [(* -> *) -> * -> *]).
MemberWithError (Queue d) r =>
Sem r (QueueResult d)
Queue.read Sem r (QueueResult (Out a))
-> (QueueResult (Out a) -> Sem r a) -> Sem r a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      QueueResult (Out a)
QueueResult.Closed ->
        ProcessError -> Sem r a
forall e (r :: [(* -> *) -> * -> *]) a.
MemberWithError (Stop e) r =>
e -> Sem r a
stop (Text -> ProcessError
Terminated Text
"closed")
      QueueResult (Out a)
QueueResult.NotAvailable ->
        ProcessError -> Sem r a
forall e (r :: [(* -> *) -> * -> *]) a.
MemberWithError (Stop e) r =>
e -> Sem r a
stop (Text -> ProcessError
Terminated Text
"impossible: empty")
      QueueResult.Success (Out a
msg) ->
        a -> Sem r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
msg
  Process ByteString o e m a
Process.RecvError ->
    Sem r (QueueResult (Err a))
forall d (r :: [(* -> *) -> * -> *]).
MemberWithError (Queue d) r =>
Sem r (QueueResult d)
Queue.read Sem r (QueueResult (Err a))
-> (QueueResult (Err a) -> Sem r a) -> Sem r a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      QueueResult (Err a)
QueueResult.Closed ->
        ProcessError -> Sem r a
forall e (r :: [(* -> *) -> * -> *]) a.
MemberWithError (Stop e) r =>
e -> Sem r a
stop (Text -> ProcessError
Terminated Text
"closed")
      QueueResult (Err a)
QueueResult.NotAvailable ->
        ProcessError -> Sem r a
forall e (r :: [(* -> *) -> * -> *]) a.
MemberWithError (Stop e) r =>
e -> Sem r a
stop (Text -> ProcessError
Terminated Text
"impossible: empty")
      QueueResult.Success (Err a
msg) ->
        a -> Sem r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
msg
  Process.Send ByteString
msg -> do
    Sem r Bool -> Sem r () -> Sem r ()
forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
whenM (forall d (r :: [(* -> *) -> * -> *]).
MemberWithError (Queue d) r =>
Sem r Bool
Queue.closed @(In ByteString)) (ProcessError -> Sem r ()
forall e (r :: [(* -> *) -> * -> *]) a.
MemberWithError (Stop e) r =>
e -> Sem r a
stop (Text -> ProcessError
Terminated Text
"closed"))
    In ByteString -> Sem r ()
forall d (r :: [(* -> *) -> * -> *]).
MemberWithError (Queue d) r =>
d -> Sem r ()
Queue.write (ByteString -> In ByteString
forall a. a -> In a
In ByteString
msg)

withSTMResources ::
   o e r a .
  Members [Resource, Embed IO] r =>
  Int ->
  (ProcessQueues o e -> Sem r a) ->
  Sem r a
withSTMResources :: forall o e (r :: [(* -> *) -> * -> *]) a.
Members '[Resource, Embed IO] r =>
Int -> (ProcessQueues o e -> Sem r a) -> Sem r a
withSTMResources Int
qSize ProcessQueues o e -> Sem r a
action = do
  Int -> (TBMQueue (In ByteString) -> Sem r a) -> Sem r a
forall d (r :: [(* -> *) -> * -> *]) a.
Members '[Resource, Embed IO] r =>
Int -> (TBMQueue d -> Sem r a) -> Sem r a
withTBMQueue Int
qSize \ TBMQueue (In ByteString)
inQ ->
    Int -> (TBMQueue (Out o) -> Sem r a) -> Sem r a
forall d (r :: [(* -> *) -> * -> *]) a.
Members '[Resource, Embed IO] r =>
Int -> (TBMQueue d -> Sem r a) -> Sem r a
withTBMQueue Int
qSize \ TBMQueue (Out o)
outQ ->
      Int -> (TBMQueue (Err e) -> Sem r a) -> Sem r a
forall d (r :: [(* -> *) -> * -> *]) a.
Members '[Resource, Embed IO] r =>
Int -> (TBMQueue d -> Sem r a) -> Sem r a
withTBMQueue Int
qSize \ TBMQueue (Err e)
errQ ->
        ProcessQueues o e -> Sem r a
action (TBMQueue (In ByteString)
-> TBMQueue (Out o) -> TBMQueue (Err e) -> ProcessQueues o e
forall o e.
TBMQueue (In ByteString)
-> TBMQueue (Out o) -> TBMQueue (Err e) -> ProcessQueues o e
ProcessQueues TBMQueue (In ByteString)
inQ TBMQueue (Out o)
outQ TBMQueue (Err e)
errQ)

withQueues ::
  Members [Race, Resource, Embed IO] r =>
  Int ->
  InterpretersFor [Queue (In ByteString), Queue (Out o), Queue (Err e)] r
withQueues :: forall (r :: [(* -> *) -> * -> *]) o e.
Members '[Race, Resource, Embed IO] r =>
Int
-> InterpretersFor
     '[Queue (In ByteString), Queue (Out o), Queue (Err e)] r
withQueues Int
qSize Sem
  (Append '[Queue (In ByteString), Queue (Out o), Queue (Err e)] r) a
action =
  Int -> (ProcessQueues o e -> Sem r a) -> Sem r a
forall o e (r :: [(* -> *) -> * -> *]) a.
Members '[Resource, Embed IO] r =>
Int -> (ProcessQueues o e -> Sem r a) -> Sem r a
withSTMResources Int
qSize \ ProcessQueues o e
qs -> ProcessQueues o e
-> InterpretersFor
     '[Queue (In ByteString), Queue (Out o), Queue (Err e)] r
forall (r :: [(* -> *) -> * -> *]) o e.
Members '[Resource, Race, Embed IO] r =>
ProcessQueues o e
-> InterpretersFor
     '[Queue (In ByteString), Queue (Out o), Queue (Err e)] r
interpretQueues ProcessQueues o e
qs Sem
  (Append '[Queue (In ByteString), Queue (Out o), Queue (Err e)] r) a
action

outputQueue ::
   pipe chunk err r .
  Coercible (pipe chunk) chunk =>
  Members [SystemProcess !! err, ProcessOutput chunk, Queue (pipe chunk), Embed IO] r =>
  Bool ->
  Sem (SystemProcess : r) ByteString ->
  Sem r ()
outputQueue :: forall (pipe :: * -> *) chunk err (r :: [(* -> *) -> * -> *]).
(Coercible (pipe chunk) chunk,
 Members
   '[SystemProcess !! err, ProcessOutput chunk, Queue (pipe chunk),
     Embed IO]
   r) =>
Bool -> Sem (SystemProcess : r) ByteString -> Sem r ()
outputQueue Bool
discardWhenFull Sem (SystemProcess : r) ByteString
readChunk = do
  ByteString -> Sem r ()
spin ByteString
""
  where
    spin :: ByteString -> Sem r ()
spin ByteString
buffer =
      forall err (eff :: (* -> *) -> * -> *) (r :: [(* -> *) -> * -> *])
       a b.
Member (Resumable err eff) r =>
Sem (eff : r) a -> (a -> Sem r b) -> (err -> Sem r b) -> Sem r b
resumeOr @err Sem (SystemProcess : r) ByteString
readChunk (ByteString -> ByteString -> Sem r ()
write ByteString
buffer) (Sem r () -> err -> Sem r ()
forall a b. a -> b -> a
const (forall d (r :: [(* -> *) -> * -> *]).
MemberWithError (Queue d) r =>
Sem r ()
Queue.close @(pipe chunk)))
    write :: ByteString -> ByteString -> Sem r ()
write ByteString
buffer ByteString
msg = do
      ([chunk]
chunks, ByteString
newBuffer) <- ByteString -> ByteString -> Sem r ([chunk], ByteString)
forall a (r :: [(* -> *) -> * -> *]).
MemberWithError (ProcessOutput a) r =>
ByteString -> ByteString -> Sem r ([a], ByteString)
ProcessOutput.chunk ByteString
buffer ByteString
msg
      [chunk] -> (chunk -> Sem r ()) -> Sem r ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [chunk]
chunks \ (forall a b. Coercible a b => a -> b
coerce @chunk @(pipe chunk) -> pipe chunk
c) ->
        if Bool
discardWhenFull then Sem r (QueueResult ()) -> Sem r ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (pipe chunk -> Sem r (QueueResult ())
forall d (r :: [(* -> *) -> * -> *]).
MemberWithError (Queue d) r =>
d -> Sem r (QueueResult ())
Queue.tryWrite pipe chunk
c) else pipe chunk -> Sem r ()
forall d (r :: [(* -> *) -> * -> *]).
MemberWithError (Queue d) r =>
d -> Sem r ()
Queue.write pipe chunk
c
      ByteString -> Sem r ()
spin ByteString
newBuffer

inputQueue ::
   err r .
  Members [SystemProcess !! err, Queue (In ByteString), Embed IO] r =>
  (ByteString -> Sem (SystemProcess : r) ()) ->
  Sem r ()
inputQueue :: forall err (r :: [(* -> *) -> * -> *]).
Members
  '[SystemProcess !! err, Queue (In ByteString), Embed IO] r =>
(ByteString -> Sem (SystemProcess : r) ()) -> Sem r ()
inputQueue ByteString -> Sem (SystemProcess : r) ()
writeChunk =
  Sem r ()
spin
  where
    spin :: Sem r ()
spin =
      Sem r (QueueResult (In ByteString))
forall d (r :: [(* -> *) -> * -> *]).
MemberWithError (Queue d) r =>
Sem r (QueueResult d)
Queue.read Sem r (QueueResult (In ByteString))
-> (QueueResult (In ByteString) -> Sem r ()) -> Sem r ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        QueueResult.Success (In ByteString
msg) ->
          forall err (eff :: (* -> *) -> * -> *) (r :: [(* -> *) -> * -> *])
       a b.
Member (Resumable err eff) r =>
Sem (eff : r) a -> (a -> Sem r b) -> (err -> Sem r b) -> Sem r b
resumeOr @err (ByteString -> Sem (SystemProcess : r) ()
writeChunk ByteString
msg) (Sem r () -> () -> Sem r ()
forall a b. a -> b -> a
const Sem r ()
spin) (Sem r () -> err -> Sem r ()
forall a b. a -> b -> a
const (forall d (r :: [(* -> *) -> * -> *]).
MemberWithError (Queue d) r =>
Sem r ()
Queue.close @(In ByteString)))
        QueueResult (In ByteString)
_ ->
          Sem r ()
forall (f :: * -> *). Applicative f => f ()
unit

handleKill ::
  Members [SystemProcess, Race] r =>
  ProcessKill ->
  Sem r ()
handleKill :: forall (r :: [(* -> *) -> * -> *]).
Members '[SystemProcess, Race] r =>
ProcessKill -> Sem r ()
handleKill = \case
  KillAfter NanoSeconds
interval ->
    Sem r () -> NanoSeconds -> Sem r () -> Sem r ()
forall u (r :: [(* -> *) -> * -> *]) a.
(TimeUnit u, Member Race r) =>
Sem r a -> u -> Sem r a -> Sem r a
Conc.timeout_ Sem r ()
forall (r :: [(* -> *) -> * -> *]).
Member SystemProcess r =>
Sem r ()
SystemProcess.term NanoSeconds
interval (Sem r ExitCode -> Sem r ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void Sem r ExitCode
forall (r :: [(* -> *) -> * -> *]).
MemberWithError SystemProcess r =>
Sem r ExitCode
SystemProcess.wait)
  ProcessKill
KillImmediately ->
    Sem r ()
forall (r :: [(* -> *) -> * -> *]).
Member SystemProcess r =>
Sem r ()
SystemProcess.term
  ProcessKill
KillNever ->
    Sem r ExitCode -> Sem r ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void Sem r ExitCode
forall (r :: [(* -> *) -> * -> *]).
MemberWithError SystemProcess r =>
Sem r ExitCode
SystemProcess.wait

withKill ::
   err r a .
  Members [SystemProcess !! err, Resource, Race] r =>
  ProcessKill ->
  Sem r a ->
  Sem r a
withKill :: forall err (r :: [(* -> *) -> * -> *]) a.
Members '[SystemProcess !! err, Resource, Race] r =>
ProcessKill -> Sem r a -> Sem r a
withKill ProcessKill
kill Sem r a
ma =
  Sem r a -> Sem r () -> Sem r a
forall (r :: [(* -> *) -> * -> *]) a b.
Member Resource r =>
Sem r a -> Sem r b -> Sem r a
finally Sem r a
ma (Sem r () -> Sem r a) -> Sem r () -> Sem r a
forall a b. (a -> b) -> a -> b
$ forall err (eff :: (* -> *) -> * -> *) (r :: [(* -> *) -> * -> *]).
Member (Resumable err eff) r =>
Sem (eff : r) () -> Sem r ()
resume_ @err @SystemProcess do
    Sem (SystemProcess : r) Pid -> Sem (SystemProcess : r) ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void Sem (SystemProcess : r) Pid
forall (r :: [(* -> *) -> * -> *]).
MemberWithError SystemProcess r =>
Sem r Pid
SystemProcess.pid
    ProcessKill -> Sem (SystemProcess : r) ()
forall (r :: [(* -> *) -> * -> *]).
Members '[SystemProcess, Race] r =>
ProcessKill -> Sem r ()
handleKill ProcessKill
kill

type ScopeEffects o e err =
  [Queue (In ByteString), Queue (Out o), Queue (Err e), SystemProcess !! err]

scope ::
   o e resource err r .
  Member (Scoped resource (SystemProcess !! err)) r =>
  Members [ProcessOutput e, ProcessOutput o, Resource, Race, Async, Embed IO] r =>
  ProcessOptions ->
  InterpretersFor (ScopeEffects o e err) r
scope :: forall o e resource err (r :: [(* -> *) -> * -> *]).
(Member (Scoped resource (SystemProcess !! err)) r,
 Members
   '[ProcessOutput e, ProcessOutput o, Resource, Race, Async,
     Embed IO]
   r) =>
ProcessOptions -> InterpretersFor (ScopeEffects o e err) r
scope (ProcessOptions Bool
discard Int
qSize ProcessKill
kill) =
  forall resource err (r :: [(* -> *) -> * -> *]).
Member (Scoped resource (SystemProcess !! err)) r =>
InterpreterFor (SystemProcess !! err) r
withSystemProcess @resource (Sem ((SystemProcess !! err) : r) a -> Sem r a)
-> (Sem
      (Queue (In ByteString)
         : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
      a
    -> Sem ((SystemProcess !! err) : r) a)
-> Sem
     (Queue (In ByteString)
        : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
     a
-> Sem r a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Int
-> InterpretersFor
     '[Queue (In ByteString), Queue (Out o), Queue (Err e)]
     ((SystemProcess !! err) : r)
forall (r :: [(* -> *) -> * -> *]) o e.
Members '[Race, Resource, Embed IO] r =>
Int
-> InterpretersFor
     '[Queue (In ByteString), Queue (Out o), Queue (Err e)] r
withQueues Int
qSize (Sem
   (Queue (In ByteString)
      : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
   a
 -> Sem ((SystemProcess !! err) : r) a)
-> (Sem
      (Queue (In ByteString)
         : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
      a
    -> Sem
         (Queue (In ByteString)
            : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
         a)
-> Sem
     (Queue (In ByteString)
        : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
     a
-> Sem ((SystemProcess !! err) : r) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Sem
  (Queue (In ByteString)
     : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
  ()
-> Sem
     (Queue (In ByteString)
        : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
     a
-> Sem
     (Queue (In ByteString)
        : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
     a
forall (r :: [(* -> *) -> * -> *]) b a.
Members '[Resource, Race, Async] r =>
Sem r b -> Sem r a -> Sem r a
withAsync_ (forall (pipe :: * -> *) chunk err (r :: [(* -> *) -> * -> *]).
(Coercible (pipe chunk) chunk,
 Members
   '[SystemProcess !! err, ProcessOutput chunk, Queue (pipe chunk),
     Embed IO]
   r) =>
Bool -> Sem (SystemProcess : r) ByteString -> Sem r ()
outputQueue @Err @e @err Bool
discard Sem
  (SystemProcess
     : Queue (In ByteString) : Queue (Out o) : Queue (Err e)
     : (SystemProcess !! err) : r)
  ByteString
forall (r :: [(* -> *) -> * -> *]).
MemberWithError SystemProcess r =>
Sem r ByteString
SystemProcess.readStderr) (Sem
   (Queue (In ByteString)
      : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
   a
 -> Sem
      (Queue (In ByteString)
         : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
      a)
-> (Sem
      (Queue (In ByteString)
         : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
      a
    -> Sem
         (Queue (In ByteString)
            : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
         a)
-> Sem
     (Queue (In ByteString)
        : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
     a
-> Sem
     (Queue (In ByteString)
        : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
     a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Sem
  (Queue (In ByteString)
     : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
  ()
-> Sem
     (Queue (In ByteString)
        : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
     a
-> Sem
     (Queue (In ByteString)
        : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
     a
forall (r :: [(* -> *) -> * -> *]) b a.
Members '[Resource, Race, Async] r =>
Sem r b -> Sem r a -> Sem r a
withAsync_ (forall (pipe :: * -> *) chunk err (r :: [(* -> *) -> * -> *]).
(Coercible (pipe chunk) chunk,
 Members
   '[SystemProcess !! err, ProcessOutput chunk, Queue (pipe chunk),
     Embed IO]
   r) =>
Bool -> Sem (SystemProcess : r) ByteString -> Sem r ()
outputQueue @Out @o @err Bool
discard Sem
  (SystemProcess
     : Queue (In ByteString) : Queue (Out o) : Queue (Err e)
     : (SystemProcess !! err) : r)
  ByteString
forall (r :: [(* -> *) -> * -> *]).
MemberWithError SystemProcess r =>
Sem r ByteString
SystemProcess.readStdout) (Sem
   (Queue (In ByteString)
      : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
   a
 -> Sem
      (Queue (In ByteString)
         : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
      a)
-> (Sem
      (Queue (In ByteString)
         : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
      a
    -> Sem
         (Queue (In ByteString)
            : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
         a)
-> Sem
     (Queue (In ByteString)
        : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
     a
-> Sem
     (Queue (In ByteString)
        : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
     a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Sem
  (Queue (In ByteString)
     : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
  ()
-> Sem
     (Queue (In ByteString)
        : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
     a
-> Sem
     (Queue (In ByteString)
        : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
     a
forall (r :: [(* -> *) -> * -> *]) b a.
Members '[Resource, Race, Async] r =>
Sem r b -> Sem r a -> Sem r a
withAsync_ (forall err (r :: [(* -> *) -> * -> *]).
Members
  '[SystemProcess !! err, Queue (In ByteString), Embed IO] r =>
(ByteString -> Sem (SystemProcess : r) ()) -> Sem r ()
inputQueue @err ByteString
-> Sem
     (SystemProcess
        : Queue (In ByteString) : Queue (Out o) : Queue (Err e)
        : (SystemProcess !! err) : r)
     ()
forall (r :: [(* -> *) -> * -> *]).
MemberWithError SystemProcess r =>
ByteString -> Sem r ()
SystemProcess.writeStdin) (Sem
   (Queue (In ByteString)
      : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
   a
 -> Sem
      (Queue (In ByteString)
         : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
      a)
-> (Sem
      (Queue (In ByteString)
         : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
      a
    -> Sem
         (Queue (In ByteString)
            : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
         a)
-> Sem
     (Queue (In ByteString)
        : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
     a
-> Sem
     (Queue (In ByteString)
        : Queue (Out o) : Queue (Err e) : (SystemProcess !! err) : r)
     a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  forall err (r :: [(* -> *) -> * -> *]) a.
Members '[SystemProcess !! err, Resource, Race] r =>
ProcessKill -> Sem r a -> Sem r a
withKill @err ProcessKill
kill

-- |Interpret 'Process' with a system process resource whose file descriptors are connected to three 'TBMQueue's,
-- deferring decoding of stdout and stderr to the interpreters of two 'ProcessOutput' effects.
interpretProcess ::
   resource err o e r .
  Member (Scoped resource (SystemProcess !! err)) r =>
  Members [ProcessOutput o, ProcessOutput e, Resource, Race, Async, Embed IO] r =>
  ProcessOptions ->
  InterpreterFor (Scoped () (Process ByteString o e) !! ProcessError) r
interpretProcess :: forall resource err o e (r :: [(* -> *) -> * -> *]).
(Member (Scoped resource (SystemProcess !! err)) r,
 Members
   '[ProcessOutput o, ProcessOutput e, Resource, Race, Async,
     Embed IO]
   r) =>
ProcessOptions
-> InterpreterFor
     (Scoped () (Process ByteString o e) !! ProcessError) r
interpretProcess ProcessOptions
options =
  forall (extra :: [(* -> *) -> * -> *])
       (effect :: (* -> *) -> * -> *) err (r :: [(* -> *) -> * -> *])
       (r1 :: [(* -> *) -> * -> *]).
(r1 ~ ((extra ++ '[Stop err]) ++ r),
 InsertAtIndex
   1
   '[Scoped () effect !! err]
   r1
   r
   ((Scoped () effect !! err) : r1)
   (extra ++ '[Stop err])) =>
(forall x. Sem r1 x -> Sem (Stop err : r) x)
-> (forall (r0 :: [(* -> *) -> * -> *]) x.
    effect (Sem r0) x -> Sem r1 x)
-> InterpreterFor (Scoped () effect !! err) r
interpretScopedResumableWith_ @(ScopeEffects o e err) (forall o e resource err (r :: [(* -> *) -> * -> *]).
(Member (Scoped resource (SystemProcess !! err)) r,
 Members
   '[ProcessOutput e, ProcessOutput o, Resource, Race, Async,
     Embed IO]
   r) =>
ProcessOptions -> InterpretersFor (ScopeEffects o e err) r
scope @o @e @resource ProcessOptions
options) forall (r0 :: [(* -> *) -> * -> *]) x.
Process ByteString o e (Sem r0) x
-> Sem
     (Queue (In ByteString)
        : Queue (Out o) : Queue (Err e) : (SystemProcess !! err)
        : Stop ProcessError : r)
     x
forall o e (m :: * -> *) (r :: [(* -> *) -> * -> *]) a.
Members
  '[Queue (In ByteString), Queue (Out o), Queue (Err e),
    Stop ProcessError]
  r =>
Process ByteString o e m a -> Sem r a
handleProcessWithQueues

-- |Interpret 'Process' with a system process resource whose file descriptors are connected to three 'TBMQueue's,
-- producing 'ByteString's.
interpretProcessByteString ::
   resource err r .
  Members [Scoped resource (SystemProcess !! err), Resource, Race, Async, Embed IO] r =>
  ProcessOptions ->
  InterpreterFor (Scoped () (Process ByteString ByteString ByteString) !! ProcessError) r
interpretProcessByteString :: forall resource err (r :: [(* -> *) -> * -> *]).
Members
  '[Scoped resource (SystemProcess !! err), Resource, Race, Async,
    Embed IO]
  r =>
ProcessOptions
-> InterpreterFor
     (Scoped () (Process ByteString ByteString ByteString)
      !! ProcessError)
     r
interpretProcessByteString ProcessOptions
options =
  Sem (ProcessOutput ByteString : r) a -> Sem r a
forall (r :: [(* -> *) -> * -> *]).
InterpreterFor (ProcessOutput ByteString) r
interpretProcessOutputId (Sem (ProcessOutput ByteString : r) a -> Sem r a)
-> (Sem
      ((Scoped () (Process ByteString ByteString ByteString)
        !! ProcessError)
         : r)
      a
    -> Sem (ProcessOutput ByteString : r) a)
-> Sem
     ((Scoped () (Process ByteString ByteString ByteString)
       !! ProcessError)
        : r)
     a
-> Sem r a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  forall resource err o e (r :: [(* -> *) -> * -> *]).
(Member (Scoped resource (SystemProcess !! err)) r,
 Members
   '[ProcessOutput o, ProcessOutput e, Resource, Race, Async,
     Embed IO]
   r) =>
ProcessOptions
-> InterpreterFor
     (Scoped () (Process ByteString o e) !! ProcessError) r
interpretProcess @resource @err ProcessOptions
options (Sem
   ((Scoped () (Process ByteString ByteString ByteString)
     !! ProcessError)
      : ProcessOutput ByteString : r)
   a
 -> Sem (ProcessOutput ByteString : r) a)
-> (Sem
      ((Scoped () (Process ByteString ByteString ByteString)
        !! ProcessError)
         : r)
      a
    -> Sem
         ((Scoped () (Process ByteString ByteString ByteString)
           !! ProcessError)
            : ProcessOutput ByteString : r)
         a)
-> Sem
     ((Scoped () (Process ByteString ByteString ByteString)
       !! ProcessError)
        : r)
     a
-> Sem (ProcessOutput ByteString : r) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Sem
  ((Scoped () (Process ByteString ByteString ByteString)
    !! ProcessError)
     : r)
  a
-> Sem
     ((Scoped () (Process ByteString ByteString ByteString)
       !! ProcessError)
        : ProcessOutput ByteString : r)
     a
forall (e2 :: (* -> *) -> * -> *) (e1 :: (* -> *) -> * -> *)
       (r :: [(* -> *) -> * -> *]) a.
Sem (e1 : r) a -> Sem (e1 : e2 : r) a
raiseUnder

-- |Interpret 'Process' with a system process resource whose file descriptors are connected to three 'TBMQueue's,
-- producing chunks of lines of 'ByteString's.
interpretProcessByteStringLines ::
   resource err r .
  Members [Scoped resource (SystemProcess !! err), Resource, Race, Async, Embed IO] r =>
  ProcessOptions ->
  InterpreterFor (Scoped () (Process ByteString ByteString ByteString) !! ProcessError) r
interpretProcessByteStringLines :: forall resource err (r :: [(* -> *) -> * -> *]).
Members
  '[Scoped resource (SystemProcess !! err), Resource, Race, Async,
    Embed IO]
  r =>
ProcessOptions
-> InterpreterFor
     (Scoped () (Process ByteString ByteString ByteString)
      !! ProcessError)
     r
interpretProcessByteStringLines ProcessOptions
options =
  Sem (ProcessOutput ByteString : r) a -> Sem r a
forall (r :: [(* -> *) -> * -> *]).
InterpreterFor (ProcessOutput ByteString) r
interpretProcessOutputLines (Sem (ProcessOutput ByteString : r) a -> Sem r a)
-> (Sem
      ((Scoped () (Process ByteString ByteString ByteString)
        !! ProcessError)
         : r)
      a
    -> Sem (ProcessOutput ByteString : r) a)
-> Sem
     ((Scoped () (Process ByteString ByteString ByteString)
       !! ProcessError)
        : r)
     a
-> Sem r a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  forall resource err o e (r :: [(* -> *) -> * -> *]).
(Member (Scoped resource (SystemProcess !! err)) r,
 Members
   '[ProcessOutput o, ProcessOutput e, Resource, Race, Async,
     Embed IO]
   r) =>
ProcessOptions
-> InterpreterFor
     (Scoped () (Process ByteString o e) !! ProcessError) r
interpretProcess @resource @err ProcessOptions
options (Sem
   ((Scoped () (Process ByteString ByteString ByteString)
     !! ProcessError)
      : ProcessOutput ByteString : r)
   a
 -> Sem (ProcessOutput ByteString : r) a)
-> (Sem
      ((Scoped () (Process ByteString ByteString ByteString)
        !! ProcessError)
         : r)
      a
    -> Sem
         ((Scoped () (Process ByteString ByteString ByteString)
           !! ProcessError)
            : ProcessOutput ByteString : r)
         a)
-> Sem
     ((Scoped () (Process ByteString ByteString ByteString)
       !! ProcessError)
        : r)
     a
-> Sem (ProcessOutput ByteString : r) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Sem
  ((Scoped () (Process ByteString ByteString ByteString)
    !! ProcessError)
     : r)
  a
-> Sem
     ((Scoped () (Process ByteString ByteString ByteString)
       !! ProcessError)
        : ProcessOutput ByteString : r)
     a
forall (e2 :: (* -> *) -> * -> *) (e1 :: (* -> *) -> * -> *)
       (r :: [(* -> *) -> * -> *]) a.
Sem (e1 : r) a -> Sem (e1 : e2 : r) a
raiseUnder

-- |Interpret 'Process' with a system process resource whose file descriptors are connected to three 'TBMQueue's,
-- producing 'Text's.
interpretProcessText ::
   resource err r .
  Members [Scoped resource (SystemProcess !! err), Resource, Race, Async, Embed IO] r =>
  ProcessOptions ->
  InterpreterFor (Scoped () (Process ByteString Text Text) !! ProcessError) r
interpretProcessText :: forall resource err (r :: [(* -> *) -> * -> *]).
Members
  '[Scoped resource (SystemProcess !! err), Resource, Race, Async,
    Embed IO]
  r =>
ProcessOptions
-> InterpreterFor
     (Scoped () (Process ByteString Text Text) !! ProcessError) r
interpretProcessText ProcessOptions
options =
  Sem (ProcessOutput Text : r) a -> Sem r a
forall (r :: [(* -> *) -> * -> *]).
InterpreterFor (ProcessOutput Text) r
interpretProcessOutputText (Sem (ProcessOutput Text : r) a -> Sem r a)
-> (Sem
      ((Scoped () (Process ByteString Text Text) !! ProcessError) : r) a
    -> Sem (ProcessOutput Text : r) a)
-> Sem
     ((Scoped () (Process ByteString Text Text) !! ProcessError) : r) a
-> Sem r a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  forall resource err o e (r :: [(* -> *) -> * -> *]).
(Member (Scoped resource (SystemProcess !! err)) r,
 Members
   '[ProcessOutput o, ProcessOutput e, Resource, Race, Async,
     Embed IO]
   r) =>
ProcessOptions
-> InterpreterFor
     (Scoped () (Process ByteString o e) !! ProcessError) r
interpretProcess @resource @err ProcessOptions
options (Sem
   ((Scoped () (Process ByteString Text Text) !! ProcessError)
      : ProcessOutput Text : r)
   a
 -> Sem (ProcessOutput Text : r) a)
-> (Sem
      ((Scoped () (Process ByteString Text Text) !! ProcessError) : r) a
    -> Sem
         ((Scoped () (Process ByteString Text Text) !! ProcessError)
            : ProcessOutput Text : r)
         a)
-> Sem
     ((Scoped () (Process ByteString Text Text) !! ProcessError) : r) a
-> Sem (ProcessOutput Text : r) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Sem
  ((Scoped () (Process ByteString Text Text) !! ProcessError) : r) a
-> Sem
     ((Scoped () (Process ByteString Text Text) !! ProcessError)
        : ProcessOutput Text : r)
     a
forall (e2 :: (* -> *) -> * -> *) (e1 :: (* -> *) -> * -> *)
       (r :: [(* -> *) -> * -> *]) a.
Sem (e1 : r) a -> Sem (e1 : e2 : r) a
raiseUnder

-- |Interpret 'Process' with a system process resource whose file descriptors are connected to three 'TBMQueue's,
-- producing chunks of lines of 'Text's.
interpretProcessTextLines ::
   resource err r .
  Members [Scoped resource (SystemProcess !! err), Resource, Race, Async, Embed IO] r =>
  ProcessOptions ->
  InterpreterFor (Scoped () (Process ByteString Text Text) !! ProcessError) r
interpretProcessTextLines :: forall resource err (r :: [(* -> *) -> * -> *]).
Members
  '[Scoped resource (SystemProcess !! err), Resource, Race, Async,
    Embed IO]
  r =>
ProcessOptions
-> InterpreterFor
     (Scoped () (Process ByteString Text Text) !! ProcessError) r
interpretProcessTextLines ProcessOptions
options =
  Sem (ProcessOutput Text : r) a -> Sem r a
forall (r :: [(* -> *) -> * -> *]).
InterpreterFor (ProcessOutput Text) r
interpretProcessOutputTextLines (Sem (ProcessOutput Text : r) a -> Sem r a)
-> (Sem
      ((Scoped () (Process ByteString Text Text) !! ProcessError) : r) a
    -> Sem (ProcessOutput Text : r) a)
-> Sem
     ((Scoped () (Process ByteString Text Text) !! ProcessError) : r) a
-> Sem r a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  forall resource err o e (r :: [(* -> *) -> * -> *]).
(Member (Scoped resource (SystemProcess !! err)) r,
 Members
   '[ProcessOutput o, ProcessOutput e, Resource, Race, Async,
     Embed IO]
   r) =>
ProcessOptions
-> InterpreterFor
     (Scoped () (Process ByteString o e) !! ProcessError) r
interpretProcess @resource @err ProcessOptions
options (Sem
   ((Scoped () (Process ByteString Text Text) !! ProcessError)
      : ProcessOutput Text : r)
   a
 -> Sem (ProcessOutput Text : r) a)
-> (Sem
      ((Scoped () (Process ByteString Text Text) !! ProcessError) : r) a
    -> Sem
         ((Scoped () (Process ByteString Text Text) !! ProcessError)
            : ProcessOutput Text : r)
         a)
-> Sem
     ((Scoped () (Process ByteString Text Text) !! ProcessError) : r) a
-> Sem (ProcessOutput Text : r) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Sem
  ((Scoped () (Process ByteString Text Text) !! ProcessError) : r) a
-> Sem
     ((Scoped () (Process ByteString Text Text) !! ProcessError)
        : ProcessOutput Text : r)
     a
forall (e2 :: (* -> *) -> * -> *) (e1 :: (* -> *) -> * -> *)
       (r :: [(* -> *) -> * -> *]) a.
Sem (e1 : r) a -> Sem (e1 : e2 : r) a
raiseUnder