{-|
Module : Effectful.Process.Typed
Description : effectful bindings for typed-process
Copyright : (c) 2022 Dominik Peteler
License : BSD-3-Clause
Stability : stable
This module provides [effectful](https://hackage.haskell.org/package/effectful)
bindings for [typed-process](https://hackage.haskell.org/package/typed-process).
-}
{-# OPTIONS_GHC -fno-warn-dodgy-imports #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE TypeFamilies #-}
module Effectful.Process.Typed
( -- * Process effect
TypedProcess
, runTypedProcess
-- * Launch a process
, startProcess
, stopProcess
, withProcessWait
, withProcessWait_
, withProcessTerm
, withProcessTerm_
, readProcess
, readProcess_
, runProcess
, runProcess_
, readProcessStdout
, readProcessStdout_
, readProcessStderr
, readProcessStderr_
, readProcessInterleaved
, readProcessInterleaved_
-- * Process exit code
, waitExitCode
, getExitCode
, checkExitCode
-- * Re-exports from "System.Process.Typed"
, module Reexport
#if ! MIN_VERSION_typed_process(0,2,8)
, ExitCode(..)
#endif
) where
import System.Process.Typed as Reexport hiding
( startProcess
, stopProcess
, withProcessWait
, withProcessWait_
, withProcessTerm
, withProcessTerm_
, readProcess
, readProcess_
, runProcess
, runProcess_
, readProcessStdout
, readProcessStdout_
, readProcessStderr
, readProcessStderr_
, readProcessInterleaved
, readProcessInterleaved_
, waitExitCode
, getExitCode
, checkExitCode
)
import Data.ByteString.Lazy (ByteString)
import qualified System.Process.Typed as PT
import Effectful
import qualified Effectful.Process
import Effectful.Dispatch.Static
#if ! MIN_VERSION_typed_process(0,2,8)
import System.Exit (ExitCode(..))
#endif
----------------------------------------
-- Effect & Handler
-- | We provide a type synonym for the 'Effectful.Process.Process' effect since
-- it clashes with 'PT.Process' type of @typed-process@.
type TypedProcess = Effectful.Process.Process
-- | This is merely an alias for 'Effectful.Process.runProcess' since that name
-- clashes with 'runProcess', i.e.:
--
-- > runTypedProcess = Effectful.Process.runProcess
runTypedProcess :: IOE :> es => Eff (TypedProcess : es) a -> Eff es a
runTypedProcess = Effectful.Process.runProcess
----------------------------------------
-- Launch a process
-- | Lifted 'PT.startProcess'.
startProcess :: TypedProcess :> es
=> PT.ProcessConfig stdin stdout stderr
-> Eff es (PT.Process stdin stdout stderr)
startProcess = unsafeEff_ . PT.startProcess
-- | Lifted 'PT.stopProcess'.
stopProcess :: TypedProcess :> es => PT.Process stdin stdout stderr -> Eff es ()
stopProcess = unsafeEff_ . PT.stopProcess
-- | Lifted 'PT.withProcessWait'.
withProcessWait :: TypedProcess :> es
=> PT.ProcessConfig stdin stdout stderr
-> (PT.Process stdin stdout stderr -> Eff es a)
-> Eff es a
withProcessWait = liftWithProcess PT.withProcessWait
-- | Lifted 'PT.withProcessWait_'.
withProcessWait_ :: TypedProcess :> es
=> PT.ProcessConfig stdin stdout stderr
-> (PT.Process stdin stdout stderr -> Eff es a)
-> Eff es a
withProcessWait_ = liftWithProcess PT.withProcessWait_
-- | Lifted 'PT.withProcessTerm'.
withProcessTerm :: TypedProcess :> es
=> PT.ProcessConfig stdin stdout stderr
-> (PT.Process stdin stdout stderr -> Eff es a)
-> Eff es a
withProcessTerm = liftWithProcess PT.withProcessTerm
-- | Lifted 'PT.withProcessTerm_'.
withProcessTerm_ :: TypedProcess :> es
=> PT.ProcessConfig stdin stdout stderr
-> (PT.Process stdin stdout stderr -> Eff es a)
-> Eff es a
withProcessTerm_ = liftWithProcess PT.withProcessTerm_
-- | Lifted 'PT.readProcess'.
readProcess :: TypedProcess :> es
=> PT.ProcessConfig stdin stdoutIgnored stderrIgnored
-> Eff es (ExitCode, ByteString, ByteString)
readProcess = unsafeEff_ . PT.readProcess
-- | Lifted 'PT.readProcess_'.
readProcess_ :: TypedProcess :> es
=> PT.ProcessConfig stdin stdoutIgnored stderrIgnored
-> Eff es (ByteString, ByteString)
readProcess_ = unsafeEff_ . PT.readProcess_
-- | Lifted 'PT.runProcess'.
runProcess :: TypedProcess :> es
=> PT.ProcessConfig stdin stdout stderr
-> Eff es ExitCode
runProcess = unsafeEff_ . PT.runProcess
-- | Lifted 'PT.runProcess_'.
runProcess_ :: TypedProcess :> es
=> PT.ProcessConfig stdin stdout stderr
-> Eff es ()
runProcess_ = unsafeEff_ . PT.runProcess_
-- | Lifted 'PT.readProcessStdout'.
readProcessStdout :: TypedProcess :> es
=> PT.ProcessConfig stdin stdoutIgnored stderr
-> Eff es (ExitCode, ByteString)
readProcessStdout = unsafeEff_ . PT.readProcessStdout
-- | Lifted 'PT.readProcessStdout_'.
readProcessStdout_ :: TypedProcess :> es
=> PT.ProcessConfig stdin stdoutIgnored stderr
-> Eff es ByteString
readProcessStdout_ = unsafeEff_ . PT.readProcessStdout_
-- | Lifted 'PT.readProcessStderr'.
readProcessStderr :: TypedProcess :> es
=> PT.ProcessConfig stdin stdout stderrIgnored
-> Eff es (ExitCode, ByteString)
readProcessStderr = unsafeEff_ . PT.readProcessStderr
-- | Lifted 'PT.readProcessStderr_'.
readProcessStderr_ :: TypedProcess :> es
=> PT.ProcessConfig stdin stdout stderrIgnored
-> Eff es ByteString
readProcessStderr_ = unsafeEff_ . PT.readProcessStderr_
-- | Lifted 'PT.readProcessInterleaved'.
readProcessInterleaved :: TypedProcess :> es
=> PT.ProcessConfig stdin stdoutIgnored stderrIgnored
-> Eff es (ExitCode, ByteString)
readProcessInterleaved = unsafeEff_ . PT.readProcessInterleaved
-- | Lifted 'PT.readProcessInterleaved_'.
readProcessInterleaved_ :: TypedProcess :> es
=> PT.ProcessConfig stdin stdoutIgnored stderrIgnored
-> Eff es ByteString
readProcessInterleaved_ = unsafeEff_ . PT.readProcessInterleaved_
----------------------------------------
-- Process exit code
-- | Lifted 'PT.waitExitCode'.
waitExitCode :: TypedProcess :> es
=> PT.Process stdin stdout stderr
-> Eff es ExitCode
waitExitCode = unsafeEff_ . PT.waitExitCode
---- | Lifted 'PT.waitExitCodeSTM'.
--waitExitCodeSTM :: TypedProcess :> es
-- => PT.Process stdin stdout stderr
-- -> Eff es ExitCode
--waitExitCodeSTM = unsafeEff_ . PT.waitExitCode
-- | Lifted 'PT.getExitCode'.
getExitCode :: TypedProcess :> es
=> PT.Process stdin stdout stderr
-> Eff es (Maybe ExitCode)
getExitCode = unsafeEff_ . PT.getExitCode
---- | Lifted 'PT.getExitCodeSTM'.
--getExitCodeSTM :: TypedProcess :> es
-- => PT.Process stdin stdout stderr
-- -> Eff es (Maybe ExitCode)
--getExitCodeSTM = unsafeEff_ . PT.getExitCodeSTM
-- | Lifted 'PT.checkExitCode'.
checkExitCode :: TypedProcess :> es
=> PT.Process stdin stdout stderr
-> Eff es ()
checkExitCode = unsafeEff_ . PT.checkExitCode
---- | Lifted 'PT.checkExitCodeSTM'.
--checkExitCodeSTM :: TypedProcess :> es
-- => PT.Process stdin stdout stderr
-- -> Eff es ()
--checkExitCodeSTM = unsafeEff_ . PT.checkExitCodeSTM
----------------------------------------
-- Helpers
liftWithProcess :: TypedProcess :> es
=> (PT.ProcessConfig stdin stdout stderr -> (PT.Process stdin stdout stderr -> IO a) -> IO a)
-> PT.ProcessConfig stdin stdout stderr
-> (PT.Process stdin stdout stderr -> Eff es a)
-> Eff es a
liftWithProcess k pc f = unsafeEff $ \es ->
seqUnliftIO es $ \runInIO ->
k pc (runInIO . f)