{-# options_haddock prune #-}
-- |Description: Process Interpreters, Internal
module Polysemy.Process.Interpreter.Process where

import Polysemy.Async (Async)
import Polysemy.Conc (Race)
import Polysemy.Conc.Effect.Scoped (Scoped)
import Polysemy.Conc.Interpreter.Scoped (runScoped)
import Polysemy.Error (fromException, runError)
import Polysemy.Resource (Resource, bracket)
import Polysemy.Resume (type (!!))
import Prelude hiding (fromException)
import qualified System.Process.Typed as System
import System.Process.Typed (
  ProcessConfig,
  startProcess,
  stopProcess,
  )

import Polysemy.Process.Effect.Process (Process)

withProcess ::
  Members [Resource, Embed IO] r =>
  ProcessConfig stdin stdout stderr ->
  (System.Process stdin stdout stderr -> Sem r a) ->
  Sem r a
withProcess :: ProcessConfig stdin stdout stderr
-> (Process stdin stdout stderr -> Sem r a) -> Sem r a
withProcess ProcessConfig stdin stdout stderr
config =
  Sem r (Process stdin stdout stderr)
-> (Process stdin stdout stderr -> Sem r (Either SomeException ()))
-> (Process stdin stdout stderr -> Sem r a)
-> Sem r a
forall (r :: [Effect]) a c b.
MemberWithError Resource r =>
Sem r a -> (a -> Sem r c) -> (a -> Sem r b) -> Sem r b
bracket (IO (Process stdin stdout stderr)
-> Sem r (Process stdin stdout stderr)
forall (m :: * -> *) (r :: [Effect]) a.
Member (Embed m) r =>
m a -> Sem r a
embed @IO (ProcessConfig stdin stdout stderr
-> IO (Process stdin stdout stderr)
forall (m :: * -> *) stdin stdout stderr.
MonadIO m =>
ProcessConfig stdin stdout stderr
-> m (Process stdin stdout stderr)
startProcess ProcessConfig stdin stdout stderr
config)) (forall (r :: [Effect]) a.
Sem (Error SomeException : r) a -> Sem r (Either SomeException a)
forall e (r :: [Effect]) a.
Sem (Error e : r) a -> Sem r (Either e a)
runError @SomeException (Sem (Error SomeException : r) ()
 -> Sem r (Either SomeException ()))
-> (Process stdin stdout stderr
    -> Sem (Error SomeException : r) ())
-> Process stdin stdout stderr
-> Sem r (Either SomeException ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (r :: [Effect]) a.
(Exception SomeException, Member (Error SomeException) r,
 Member (Embed IO) r) =>
IO a -> Sem r a
forall e (r :: [Effect]) a.
(Exception e, Member (Error e) r, Member (Embed IO) r) =>
IO a -> Sem r a
fromException @SomeException (IO () -> Sem (Error SomeException : r) ())
-> (Process stdin stdout stderr -> IO ())
-> Process stdin stdout stderr
-> Sem (Error SomeException : r) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Process stdin stdout stderr -> IO ()
forall (m :: * -> *) stdin stdout stderr.
MonadIO m =>
Process stdin stdout stderr -> m ()
stopProcess)

-- |Interpret 'Process' with a system process resource.
interpretProcessNative ::
   resource i o e err stdin stdout stderr r .
  Members [Resource, Race, Async, Embed IO] r =>
  ProcessConfig stdin stdout stderr ->
  ( x. System.Process stdin stdout stderr -> (resource -> Sem r x) -> Sem r x) ->
  (resource -> InterpreterFor (Process i o e !! err) r) ->
  InterpreterFor (Scoped resource (Process i o e !! err)) r
interpretProcessNative :: ProcessConfig stdin stdout stderr
-> (forall x.
    Process stdin stdout stderr -> (resource -> Sem r x) -> Sem r x)
-> (resource -> InterpreterFor (Process i o e !! err) r)
-> InterpreterFor (Scoped resource (Process i o e !! err)) r
interpretProcessNative ProcessConfig stdin stdout stderr
config forall x.
Process stdin stdout stderr -> (resource -> Sem r x) -> Sem r x
fromProcess =
  (forall x. (resource -> Sem r x) -> Sem r x)
-> (resource -> InterpreterFor (Process i o e !! err) r)
-> InterpreterFor (Scoped resource (Process i o e !! err)) r
forall resource (effect :: Effect) (r :: [Effect]).
(forall x. (resource -> Sem r x) -> Sem r x)
-> (resource -> InterpreterFor effect r)
-> InterpreterFor (Scoped resource effect) r
runScoped \ resource -> Sem r x
f ->
    ProcessConfig stdin stdout stderr
-> (Process stdin stdout stderr -> Sem r x) -> Sem r x
forall (r :: [Effect]) stdin stdout stderr a.
Members '[Resource, Embed IO] r =>
ProcessConfig stdin stdout stderr
-> (Process stdin stdout stderr -> Sem r a) -> Sem r a
withProcess ProcessConfig stdin stdout stderr
config \ Process stdin stdout stderr
prc ->
      Process stdin stdout stderr -> (resource -> Sem r x) -> Sem r x
forall x.
Process stdin stdout stderr -> (resource -> Sem r x) -> Sem r x
fromProcess Process stdin stdout stderr
prc resource -> Sem r x
f