{-# options_haddock prune #-}

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

import Data.ByteString (hGetSome, hPut)
import Polysemy.Conc.Effect.Scoped (Scoped)
import Polysemy.Conc.Interpreter.Scoped (runScoped)
import Polysemy.Resume (Stop, interpretResumable, stop, stopNote, type (!!))
import Prelude hiding (fromException)
import System.IO (BufferMode (NoBuffering), Handle, hSetBuffering)
import qualified System.Posix as Signal
import System.Process (Pid, getPid)
import System.Process.Typed (
  Process,
  ProcessConfig,
  createPipe,
  getStderr,
  getStdin,
  getStdout,
  setStderr,
  setStdin,
  setStdout,
  startProcess,
  stopProcess,
  unsafeProcessHandle,
  waitExitCode,
  )

import qualified Polysemy.Process.Data.SystemProcessError as SystemProcessError
import Polysemy.Process.Data.SystemProcessError (SystemProcessError)
import qualified Polysemy.Process.Effect.SystemProcess as SystemProcess
import Polysemy.Process.Effect.SystemProcess (SystemProcess)

type PipesProcess =
  Process Handle Handle Handle

processWithPipes :: ProcessConfig () () () -> ProcessConfig Handle Handle Handle
processWithPipes :: ProcessConfig () () () -> ProcessConfig Handle Handle Handle
processWithPipes =
  StreamSpec 'STInput Handle
-> ProcessConfig () Handle Handle
-> ProcessConfig Handle Handle Handle
forall stdin stdin0 stdout stderr.
StreamSpec 'STInput stdin
-> ProcessConfig stdin0 stdout stderr
-> ProcessConfig stdin stdout stderr
setStdin StreamSpec 'STInput Handle
forall (anyStreamType :: StreamType).
StreamSpec anyStreamType Handle
createPipe (ProcessConfig () Handle Handle
 -> ProcessConfig Handle Handle Handle)
-> (ProcessConfig () () () -> ProcessConfig () Handle Handle)
-> ProcessConfig () () ()
-> ProcessConfig Handle Handle Handle
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  StreamSpec 'STOutput Handle
-> ProcessConfig () () Handle -> ProcessConfig () Handle Handle
forall stdout stdin stdout0 stderr.
StreamSpec 'STOutput stdout
-> ProcessConfig stdin stdout0 stderr
-> ProcessConfig stdin stdout stderr
setStdout StreamSpec 'STOutput Handle
forall (anyStreamType :: StreamType).
StreamSpec anyStreamType Handle
createPipe (ProcessConfig () () Handle -> ProcessConfig () Handle Handle)
-> (ProcessConfig () () () -> ProcessConfig () () Handle)
-> ProcessConfig () () ()
-> ProcessConfig () Handle Handle
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  StreamSpec 'STOutput Handle
-> ProcessConfig () () () -> ProcessConfig () () Handle
forall stderr stdin stdout stderr0.
StreamSpec 'STOutput stderr
-> ProcessConfig stdin stdout stderr0
-> ProcessConfig stdin stdout stderr
setStderr StreamSpec 'STOutput Handle
forall (anyStreamType :: StreamType).
StreamSpec anyStreamType Handle
createPipe

start ::
  Member (Embed IO) r =>
  ProcessConfig () () () ->
  Sem r PipesProcess
start :: forall (r :: [(* -> *) -> * -> *]).
Member (Embed IO) r =>
ProcessConfig () () () -> Sem r PipesProcess
start =
  ProcessConfig Handle Handle Handle -> Sem r PipesProcess
forall (m :: * -> *) stdin stdout stderr.
MonadIO m =>
ProcessConfig stdin stdout stderr
-> m (Process stdin stdout stderr)
startProcess (ProcessConfig Handle Handle Handle -> Sem r PipesProcess)
-> (ProcessConfig () () () -> ProcessConfig Handle Handle Handle)
-> ProcessConfig () () ()
-> Sem r PipesProcess
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProcessConfig () () () -> ProcessConfig Handle Handle Handle
processWithPipes

withProcess ::
  Members [Resource, Embed IO] r =>
  ProcessConfig () () () ->
  (PipesProcess -> Sem r a) ->
  Sem r a
withProcess :: forall (r :: [(* -> *) -> * -> *]) a.
Members '[Resource, Embed IO] r =>
ProcessConfig () () () -> (PipesProcess -> Sem r a) -> Sem r a
withProcess ProcessConfig () () ()
config PipesProcess -> Sem r a
use =
  Sem r PipesProcess
-> (PipesProcess -> Sem r (Either Text ()))
-> (PipesProcess -> Sem r a)
-> Sem r a
forall (r :: [(* -> *) -> * -> *]) a c b.
MemberWithError Resource r =>
Sem r a -> (a -> Sem r c) -> (a -> Sem r b) -> Sem r b
bracket (ProcessConfig () () () -> Sem r PipesProcess
forall (r :: [(* -> *) -> * -> *]).
Member (Embed IO) r =>
ProcessConfig () () () -> Sem r PipesProcess
start ProcessConfig () () ()
config) (IO () -> Sem r (Either Text ())
forall (r :: [(* -> *) -> * -> *]) a.
Member (Embed IO) r =>
IO a -> Sem r (Either Text a)
tryAny (IO () -> Sem r (Either Text ()))
-> (PipesProcess -> IO ())
-> PipesProcess
-> Sem r (Either Text ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PipesProcess -> IO ()
forall (m :: * -> *) stdin stdout stderr.
MonadIO m =>
Process stdin stdout stderr -> m ()
stopProcess) \ PipesProcess
p -> do
    Handle -> Sem r ()
forall {r :: [(* -> *) -> * -> *]}.
(Find (Embed IO) r, LocateEffect (Embed IO) r ~ '()) =>
Handle -> Sem r ()
unbuffer (PipesProcess -> Handle
forall stdin stdout stderr. Process stdin stdout stderr -> stdin
getStdin PipesProcess
p)
    Handle -> Sem r ()
forall {r :: [(* -> *) -> * -> *]}.
(Find (Embed IO) r, LocateEffect (Embed IO) r ~ '()) =>
Handle -> Sem r ()
unbuffer (PipesProcess -> Handle
forall stdin stdout stderr. Process stdin stdout stderr -> stdout
getStdout PipesProcess
p)
    Handle -> Sem r ()
forall {r :: [(* -> *) -> * -> *]}.
(Find (Embed IO) r, LocateEffect (Embed IO) r ~ '()) =>
Handle -> Sem r ()
unbuffer (PipesProcess -> Handle
forall stdin stdout stderr. Process stdin stdout stderr -> stderr
getStderr PipesProcess
p)
    PipesProcess -> Sem r a
use PipesProcess
p
  where
    unbuffer :: Handle -> Sem r ()
unbuffer Handle
h =
      Sem r (Maybe ()) -> Sem r ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Sem r (Maybe ()) -> Sem r ()) -> Sem r (Maybe ()) -> Sem r ()
forall a b. (a -> b) -> a -> b
$ IO () -> Sem r (Maybe ())
forall (r :: [(* -> *) -> * -> *]) a.
Member (Embed IO) r =>
IO a -> Sem r (Maybe a)
tryMaybe (Handle -> BufferMode -> IO ()
hSetBuffering Handle
h BufferMode
NoBuffering)

startOpaque ::
  Member (Embed IO) r =>
  ProcessConfig i o e ->
  Sem r (Process i o e)
startOpaque :: forall (r :: [(* -> *) -> * -> *]) i o e.
Member (Embed IO) r =>
ProcessConfig i o e -> Sem r (Process i o e)
startOpaque =
  ProcessConfig i o e -> Sem r (Process i o e)
forall (m :: * -> *) stdin stdout stderr.
MonadIO m =>
ProcessConfig stdin stdout stderr
-> m (Process stdin stdout stderr)
startProcess

withProcessOpaque ::
  Members [Resource, Embed IO] r =>
  ProcessConfig i o e ->
  (Process i o e -> Sem r a) ->
  Sem r a
withProcessOpaque :: forall (r :: [(* -> *) -> * -> *]) i o e a.
Members '[Resource, Embed IO] r =>
ProcessConfig i o e -> (Process i o e -> Sem r a) -> Sem r a
withProcessOpaque ProcessConfig i o e
config =
  Sem r (Process i o e)
-> (Process i o e -> Sem r (Either Text ()))
-> (Process i o e -> Sem r a)
-> Sem r a
forall (r :: [(* -> *) -> * -> *]) a c b.
MemberWithError Resource r =>
Sem r a -> (a -> Sem r c) -> (a -> Sem r b) -> Sem r b
bracket (ProcessConfig i o e -> Sem r (Process i o e)
forall (r :: [(* -> *) -> * -> *]) i o e.
Member (Embed IO) r =>
ProcessConfig i o e -> Sem r (Process i o e)
startOpaque ProcessConfig i o e
config) (IO () -> Sem r (Either Text ())
forall (r :: [(* -> *) -> * -> *]) a.
Member (Embed IO) r =>
IO a -> Sem r (Either Text a)
tryAny (IO () -> Sem r (Either Text ()))
-> (Process i o e -> IO ())
-> Process i o e
-> Sem r (Either Text ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Process i o e -> IO ()
forall (m :: * -> *) stdin stdout stderr.
MonadIO m =>
Process stdin stdout stderr -> m ()
stopProcess)

terminate ::
  Member (Stop SystemProcessError) r =>
  Text ->
  Maybe a ->
  Sem r a
terminate :: forall (r :: [(* -> *) -> * -> *]) a.
Member (Stop SystemProcessError) r =>
Text -> Maybe a -> Sem r a
terminate Text
msg =
  SystemProcessError -> Maybe a -> Sem r a
forall err (r :: [(* -> *) -> * -> *]) a.
Member (Stop err) r =>
err -> Maybe a -> Sem r a
stopNote (Text -> SystemProcessError
SystemProcessError.Terminated Text
msg)

tryStop ::
  Members [Stop SystemProcessError, Embed IO] r =>
  Text ->
  IO a ->
  Sem r a
tryStop :: forall (r :: [(* -> *) -> * -> *]) a.
Members '[Stop SystemProcessError, Embed IO] r =>
Text -> IO a -> Sem r a
tryStop Text
msg =
  Text -> Maybe a -> Sem r a
forall (r :: [(* -> *) -> * -> *]) a.
Member (Stop SystemProcessError) r =>
Text -> Maybe a -> Sem r a
terminate Text
msg (Maybe a -> Sem r a)
-> (IO a -> Sem r (Maybe a)) -> IO a -> Sem r a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< IO a -> Sem r (Maybe a)
forall (r :: [(* -> *) -> * -> *]) a.
Member (Embed IO) r =>
IO a -> Sem r (Maybe a)
tryMaybe

processId ::
  Members [Stop SystemProcessError, Embed IO] r =>
  Process i o e ->
  Sem r Pid
processId :: forall (r :: [(* -> *) -> * -> *]) i o e.
Members '[Stop SystemProcessError, Embed IO] r =>
Process i o e -> Sem r Pid
processId Process i o e
process =
  Text -> Maybe Pid -> Sem r Pid
forall (r :: [(* -> *) -> * -> *]) a.
Member (Stop SystemProcessError) r =>
Text -> Maybe a -> Sem r a
terminate Text
"getPid returned Nothing" (Maybe Pid -> Sem r Pid) -> Sem r (Maybe Pid) -> Sem r Pid
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO (Maybe Pid) -> Sem r (Maybe Pid)
forall (m :: * -> *) (r :: [(* -> *) -> * -> *]) a.
Member (Embed m) r =>
m a -> Sem r a
embed (ProcessHandle -> IO (Maybe Pid)
getPid (Process i o e -> ProcessHandle
forall stdin stdout stderr.
Process stdin stdout stderr -> ProcessHandle
unsafeProcessHandle Process i o e
process))

-- |Interpret 'SystemProcess' with a concrete 'System.Process' with connected pipes.
interpretSystemProcessWithProcess ::
   r .
  Member (Embed IO) r =>
  Process Handle Handle Handle ->
  InterpreterFor (SystemProcess !! SystemProcessError) r
interpretSystemProcessWithProcess :: forall (r :: [(* -> *) -> * -> *]).
Member (Embed IO) r =>
PipesProcess
-> InterpreterFor (SystemProcess !! SystemProcessError) r
interpretSystemProcessWithProcess PipesProcess
process =
  (forall x (r0 :: [(* -> *) -> * -> *]).
 SystemProcess (Sem r0) x -> Sem (Stop SystemProcessError : r) x)
-> InterpreterFor (SystemProcess !! SystemProcessError) r
forall err (eff :: (* -> *) -> * -> *) (r :: [(* -> *) -> * -> *]).
FirstOrder eff "interpretResumable" =>
(forall x (r0 :: [(* -> *) -> * -> *]).
 eff (Sem r0) x -> Sem (Stop err : r) x)
-> InterpreterFor (Resumable err eff) r
interpretResumable \case
    SystemProcess (Sem r0) x
SystemProcess.Pid ->
      PipesProcess -> Sem (Stop SystemProcessError : r) Pid
forall (r :: [(* -> *) -> * -> *]) i o e.
Members '[Stop SystemProcessError, Embed IO] r =>
Process i o e -> Sem r Pid
processId PipesProcess
process
    SystemProcess.Signal Signal
sig -> do
      Pid
pid <- PipesProcess -> Sem (Stop SystemProcessError : r) Pid
forall (r :: [(* -> *) -> * -> *]) i o e.
Members '[Stop SystemProcessError, Embed IO] r =>
Process i o e -> Sem r Pid
processId PipesProcess
process
      Text -> IO () -> Sem (Stop SystemProcessError : r) ()
forall (r :: [(* -> *) -> * -> *]) a.
Members '[Stop SystemProcessError, Embed IO] r =>
Text -> IO a -> Sem r a
tryStop Text
"signal failed" (Signal -> Pid -> IO ()
Signal.signalProcess Signal
sig Pid
pid)
    SystemProcess (Sem r0) x
SystemProcess.ReadStdout ->
      Text
-> IO ByteString -> Sem (Stop SystemProcessError : r) ByteString
forall (r :: [(* -> *) -> * -> *]) a.
Members '[Stop SystemProcessError, Embed IO] r =>
Text -> IO a -> Sem r a
tryStop Text
"stdout failed" (Handle -> Int -> IO ByteString
hGetSome (PipesProcess -> Handle
forall stdin stdout stderr. Process stdin stdout stderr -> stdout
getStdout PipesProcess
process) Int
4096)
    SystemProcess (Sem r0) x
SystemProcess.ReadStderr ->
      Text
-> IO ByteString -> Sem (Stop SystemProcessError : r) ByteString
forall (r :: [(* -> *) -> * -> *]) a.
Members '[Stop SystemProcessError, Embed IO] r =>
Text -> IO a -> Sem r a
tryStop Text
"stderr failed" (Handle -> Int -> IO ByteString
hGetSome (PipesProcess -> Handle
forall stdin stdout stderr. Process stdin stdout stderr -> stderr
getStderr PipesProcess
process) Int
4096)
    SystemProcess.WriteStdin ByteString
msg ->
      Text -> IO () -> Sem (Stop SystemProcessError : r) ()
forall (r :: [(* -> *) -> * -> *]) a.
Members '[Stop SystemProcessError, Embed IO] r =>
Text -> IO a -> Sem r a
tryStop Text
"stdin failed" (Handle -> ByteString -> IO ()
hPut (PipesProcess -> Handle
forall stdin stdout stderr. Process stdin stdout stderr -> stdin
getStdin PipesProcess
process) ByteString
msg)
    SystemProcess (Sem r0) x
SystemProcess.Wait ->
      Text -> IO ExitCode -> Sem (Stop SystemProcessError : r) ExitCode
forall (r :: [(* -> *) -> * -> *]) a.
Members '[Stop SystemProcessError, Embed IO] r =>
Text -> IO a -> Sem r a
tryStop Text
"wait failed" (PipesProcess -> IO ExitCode
forall (m :: * -> *) stdin stdout stderr.
MonadIO m =>
Process stdin stdout stderr -> m ExitCode
waitExitCode PipesProcess
process)

-- |Interpret 'SystemProcess' as a single global 'System.Process' that's started immediately.
interpretSystemProcessNativeSingle ::
   r .
  Members [Resource, Embed IO] r =>
  ProcessConfig () () () ->
  InterpreterFor (SystemProcess !! SystemProcessError) r
interpretSystemProcessNativeSingle :: forall (r :: [(* -> *) -> * -> *]).
Members '[Resource, Embed IO] r =>
ProcessConfig () () ()
-> InterpreterFor (SystemProcess !! SystemProcessError) r
interpretSystemProcessNativeSingle ProcessConfig () () ()
config Sem ((SystemProcess !! SystemProcessError) : r) a
sem =
  ProcessConfig () () () -> (PipesProcess -> Sem r a) -> Sem r a
forall (r :: [(* -> *) -> * -> *]) a.
Members '[Resource, Embed IO] r =>
ProcessConfig () () () -> (PipesProcess -> Sem r a) -> Sem r a
withProcess ProcessConfig () () ()
config \ PipesProcess
process ->
    PipesProcess
-> InterpreterFor (SystemProcess !! SystemProcessError) r
forall (r :: [(* -> *) -> * -> *]).
Member (Embed IO) r =>
PipesProcess
-> InterpreterFor (SystemProcess !! SystemProcessError) r
interpretSystemProcessWithProcess PipesProcess
process Sem ((SystemProcess !! SystemProcessError) : r) a
sem

-- |Interpret 'SystemProcess' as a scoped 'System.Process' that's started wherever 'Polysemy.Process.withSystemProcess'
-- is called and terminated when the wrapped action finishes.
interpretSystemProcessNative ::
   r .
  Members [Resource, Embed IO] r =>
  ProcessConfig () () () ->
  InterpreterFor (Scoped PipesProcess (SystemProcess !! SystemProcessError)) r
interpretSystemProcessNative :: forall (r :: [(* -> *) -> * -> *]).
Members '[Resource, Embed IO] r =>
ProcessConfig () () ()
-> InterpreterFor
     (Scoped PipesProcess (SystemProcess !! SystemProcessError)) r
interpretSystemProcessNative ProcessConfig () () ()
config =
  (forall x. (PipesProcess -> Sem r x) -> Sem r x)
-> (PipesProcess
    -> InterpreterFor (SystemProcess !! SystemProcessError) r)
-> InterpreterFor
     (Scoped PipesProcess (SystemProcess !! SystemProcessError)) r
forall resource (effect :: (* -> *) -> * -> *)
       (r :: [(* -> *) -> * -> *]).
(forall x. (resource -> Sem r x) -> Sem r x)
-> (resource -> InterpreterFor effect r)
-> InterpreterFor (Scoped resource effect) r
runScoped (ProcessConfig () () () -> (PipesProcess -> Sem r x) -> Sem r x
forall (r :: [(* -> *) -> * -> *]) a.
Members '[Resource, Embed IO] r =>
ProcessConfig () () () -> (PipesProcess -> Sem r a) -> Sem r a
withProcess ProcessConfig () () ()
config) PipesProcess
-> InterpreterFor (SystemProcess !! SystemProcessError) r
forall (r :: [(* -> *) -> * -> *]).
Member (Embed IO) r =>
PipesProcess
-> InterpreterFor (SystemProcess !! SystemProcessError) r
interpretSystemProcessWithProcess

-- |Interpret 'SystemProcess' with a concrete 'System.Process' with connected pipes.
interpretSystemProcessWithProcessOpaque ::
   i o e r .
  Member (Embed IO) r =>
  Process i o e ->
  InterpreterFor (SystemProcess !! SystemProcessError) r
interpretSystemProcessWithProcessOpaque :: forall i o e (r :: [(* -> *) -> * -> *]).
Member (Embed IO) r =>
Process i o e
-> InterpreterFor (SystemProcess !! SystemProcessError) r
interpretSystemProcessWithProcessOpaque Process i o e
process =
  (forall x (r0 :: [(* -> *) -> * -> *]).
 SystemProcess (Sem r0) x -> Sem (Stop SystemProcessError : r) x)
-> InterpreterFor (SystemProcess !! SystemProcessError) r
forall err (eff :: (* -> *) -> * -> *) (r :: [(* -> *) -> * -> *]).
FirstOrder eff "interpretResumable" =>
(forall x (r0 :: [(* -> *) -> * -> *]).
 eff (Sem r0) x -> Sem (Stop err : r) x)
-> InterpreterFor (Resumable err eff) r
interpretResumable \case
    SystemProcess (Sem r0) x
SystemProcess.Pid ->
      Process i o e -> Sem (Stop SystemProcessError : r) Pid
forall (r :: [(* -> *) -> * -> *]) i o e.
Members '[Stop SystemProcessError, Embed IO] r =>
Process i o e -> Sem r Pid
processId Process i o e
process
    SystemProcess.Signal Signal
sig -> do
      Pid
pid <- Process i o e -> Sem (Stop SystemProcessError : r) Pid
forall (r :: [(* -> *) -> * -> *]) i o e.
Members '[Stop SystemProcessError, Embed IO] r =>
Process i o e -> Sem r Pid
processId Process i o e
process
      Text -> IO () -> Sem (Stop SystemProcessError : r) ()
forall (r :: [(* -> *) -> * -> *]) a.
Members '[Stop SystemProcessError, Embed IO] r =>
Text -> IO a -> Sem r a
tryStop Text
"signal failed" (Signal -> Pid -> IO ()
Signal.signalProcess Signal
sig Pid
pid)
    SystemProcess (Sem r0) x
SystemProcess.ReadStdout ->
      SystemProcessError -> Sem (Stop SystemProcessError : r) x
forall e (r :: [(* -> *) -> * -> *]) a.
MemberWithError (Stop e) r =>
e -> Sem r a
stop SystemProcessError
SystemProcessError.NoPipes
    SystemProcess (Sem r0) x
SystemProcess.ReadStderr ->
      SystemProcessError -> Sem (Stop SystemProcessError : r) x
forall e (r :: [(* -> *) -> * -> *]) a.
MemberWithError (Stop e) r =>
e -> Sem r a
stop SystemProcessError
SystemProcessError.NoPipes
    SystemProcess.WriteStdin ByteString
_ ->
      SystemProcessError -> Sem (Stop SystemProcessError : r) x
forall e (r :: [(* -> *) -> * -> *]) a.
MemberWithError (Stop e) r =>
e -> Sem r a
stop SystemProcessError
SystemProcessError.NoPipes
    SystemProcess (Sem r0) x
SystemProcess.Wait ->
      Text -> IO ExitCode -> Sem (Stop SystemProcessError : r) ExitCode
forall (r :: [(* -> *) -> * -> *]) a.
Members '[Stop SystemProcessError, Embed IO] r =>
Text -> IO a -> Sem r a
tryStop Text
"wait failed" (Process i o e -> IO ExitCode
forall (m :: * -> *) stdin stdout stderr.
MonadIO m =>
Process stdin stdout stderr -> m ExitCode
waitExitCode Process i o e
process)

-- |Interpret 'SystemProcess' as a single global 'System.Process' that's started immediately.
interpretSystemProcessNativeOpaqueSingle ::
   i o e r .
  Members [Resource, Embed IO] r =>
  ProcessConfig i o e ->
  InterpreterFor (SystemProcess !! SystemProcessError) r
interpretSystemProcessNativeOpaqueSingle :: forall i o e (r :: [(* -> *) -> * -> *]).
Members '[Resource, Embed IO] r =>
ProcessConfig i o e
-> InterpreterFor (SystemProcess !! SystemProcessError) r
interpretSystemProcessNativeOpaqueSingle ProcessConfig i o e
config Sem ((SystemProcess !! SystemProcessError) : r) a
sem =
  ProcessConfig i o e -> (Process i o e -> Sem r a) -> Sem r a
forall (r :: [(* -> *) -> * -> *]) i o e a.
Members '[Resource, Embed IO] r =>
ProcessConfig i o e -> (Process i o e -> Sem r a) -> Sem r a
withProcessOpaque ProcessConfig i o e
config \ Process i o e
process ->
    Process i o e
-> InterpreterFor (SystemProcess !! SystemProcessError) r
forall i o e (r :: [(* -> *) -> * -> *]).
Member (Embed IO) r =>
Process i o e
-> InterpreterFor (SystemProcess !! SystemProcessError) r
interpretSystemProcessWithProcessOpaque Process i o e
process Sem ((SystemProcess !! SystemProcessError) : r) a
sem

-- |Interpret 'SystemProcess' as a scoped 'System.Process' that's started wherever 'Polysemy.Process.withSystemProcess'
-- is called and terminated when the wrapped action finishes.
interpretSystemProcessNativeOpaque ::
   i o e r .
  Members [Resource, Embed IO] r =>
  ProcessConfig i o e ->
  InterpreterFor (Scoped (Process i o e) (SystemProcess !! SystemProcessError)) r
interpretSystemProcessNativeOpaque :: forall i o e (r :: [(* -> *) -> * -> *]).
Members '[Resource, Embed IO] r =>
ProcessConfig i o e
-> InterpreterFor
     (Scoped (Process i o e) (SystemProcess !! SystemProcessError)) r
interpretSystemProcessNativeOpaque ProcessConfig i o e
config =
  (forall x. (Process i o e -> Sem r x) -> Sem r x)
-> (Process i o e
    -> InterpreterFor (SystemProcess !! SystemProcessError) r)
-> InterpreterFor
     (Scoped (Process i o e) (SystemProcess !! SystemProcessError)) r
forall resource (effect :: (* -> *) -> * -> *)
       (r :: [(* -> *) -> * -> *]).
(forall x. (resource -> Sem r x) -> Sem r x)
-> (resource -> InterpreterFor effect r)
-> InterpreterFor (Scoped resource effect) r
runScoped (ProcessConfig i o e -> (Process i o e -> Sem r x) -> Sem r x
forall (r :: [(* -> *) -> * -> *]) i o e a.
Members '[Resource, Embed IO] r =>
ProcessConfig i o e -> (Process i o e -> Sem r a) -> Sem r a
withProcessOpaque ProcessConfig i o e
config) Process i o e
-> InterpreterFor (SystemProcess !! SystemProcessError) r
forall i o e (r :: [(* -> *) -> * -> *]).
Member (Embed IO) r =>
Process i o e
-> InterpreterFor (SystemProcess !! SystemProcessError) r
interpretSystemProcessWithProcessOpaque