{-# LANGUAGE CPP #-}
-- |
-- Module       : Sysetem.Process.Lens.ProcessHandler
-- Copyright 	: 2019 Emily Pillmore
-- License	: BSD
--
-- Maintainer	: Emily Pillmore <emilypi@cohomolo.gy>
-- Stability	: Experimental
-- Portability	: TypeFamilies, Rank2Types
--
-- Convenient data type with associated optics + isos for working
-- with the output of a 'createProcess' call.
--
module System.Process.Lens.ProcessHandler
( -- * Types
  ProcessHandler(..)
  -- * Isos
, _Handler
  -- * Lenses
, hstdin
, hstdout
, hstderr
, hhandle
  -- * Defaults
, defaultCreateProcess
) where


import Control.Lens

import System.IO
import System.Process


-- | A convenient handler for the output of a 'createProcess' call.
-- This data containes 4 components:
--
data ProcessHandler =
  ProcessHandler
    { ProcessHandler -> Maybe Handle
_hstdin :: Maybe Handle
      -- ^ a handle to stdin if it was requested
    , ProcessHandler -> Maybe Handle
_hstdout :: Maybe Handle
      -- ^ a handle to stdout if it was requested
    , ProcessHandler -> Maybe Handle
_hstderr :: Maybe Handle
      -- ^ a handle to stderr if it was requested
    , ProcessHandler -> ProcessHandle
_hhandle :: ProcessHandle
      -- ^ a process handle, containing a pid lock, information regarding
      -- ctcl-c delegation, and closed/open handle status info.
    }

-- | A lens into the stdin handle if requested
--
hstdin :: Lens' ProcessHandler (Maybe Handle)
hstdin :: (Maybe Handle -> f (Maybe Handle))
-> ProcessHandler -> f ProcessHandler
hstdin = (ProcessHandler -> Maybe Handle)
-> (ProcessHandler -> Maybe Handle -> ProcessHandler)
-> Lens ProcessHandler ProcessHandler (Maybe Handle) (Maybe Handle)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens ProcessHandler -> Maybe Handle
_hstdin (\t :: ProcessHandler
t b :: Maybe Handle
b -> ProcessHandler
t { _hstdin :: Maybe Handle
_hstdin = Maybe Handle
b })

-- | A lens into the stdout handle if requested
--
hstdout :: Lens' ProcessHandler (Maybe Handle)
hstdout :: (Maybe Handle -> f (Maybe Handle))
-> ProcessHandler -> f ProcessHandler
hstdout = (ProcessHandler -> Maybe Handle)
-> (ProcessHandler -> Maybe Handle -> ProcessHandler)
-> Lens ProcessHandler ProcessHandler (Maybe Handle) (Maybe Handle)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens ProcessHandler -> Maybe Handle
_hstdout (\t :: ProcessHandler
t b :: Maybe Handle
b -> ProcessHandler
t { _hstdout :: Maybe Handle
_hstdout = Maybe Handle
b })

-- | A lens into the stderr handle if requested
--
hstderr :: Lens' ProcessHandler (Maybe Handle)
hstderr :: (Maybe Handle -> f (Maybe Handle))
-> ProcessHandler -> f ProcessHandler
hstderr = (ProcessHandler -> Maybe Handle)
-> (ProcessHandler -> Maybe Handle -> ProcessHandler)
-> Lens ProcessHandler ProcessHandler (Maybe Handle) (Maybe Handle)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens ProcessHandler -> Maybe Handle
_hstderr (\t :: ProcessHandler
t b :: Maybe Handle
b -> ProcessHandler
t { _hstderr :: Maybe Handle
_hstderr = Maybe Handle
b })

-- | A lens into the process handle
--
hhandle :: Lens' ProcessHandler ProcessHandle
hhandle :: (ProcessHandle -> f ProcessHandle)
-> ProcessHandler -> f ProcessHandler
hhandle = (ProcessHandler -> ProcessHandle)
-> (ProcessHandler -> ProcessHandle -> ProcessHandler)
-> Lens ProcessHandler ProcessHandler ProcessHandle ProcessHandle
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens ProcessHandler -> ProcessHandle
_hhandle (\t :: ProcessHandler
t b :: ProcessHandle
b -> ProcessHandler
t { _hhandle :: ProcessHandle
_hhandle = ProcessHandle
b })

-- | An iso between the ProcessHandler data and its product
-- representation
--
_Handler :: Iso' ProcessHandler (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
_Handler :: p (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
  (f (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle))
-> p ProcessHandler (f ProcessHandler)
_Handler = (ProcessHandler
 -> (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle))
-> ((Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
    -> ProcessHandler)
-> Iso
     ProcessHandler
     ProcessHandler
     (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
     (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso
  (\(ProcessHandler a :: Maybe Handle
a b :: Maybe Handle
b c :: Maybe Handle
c p :: ProcessHandle
p) -> (Maybe Handle
a,Maybe Handle
b,Maybe Handle
c,ProcessHandle
p))
  (\(a :: Maybe Handle
a,b :: Maybe Handle
b,c :: Maybe Handle
c,p :: ProcessHandle
p) -> Maybe Handle
-> Maybe Handle -> Maybe Handle -> ProcessHandle -> ProcessHandler
ProcessHandler Maybe Handle
a Maybe Handle
b Maybe Handle
c ProcessHandle
p)

-- | A default for a 'CreateProcess'
--
defaultCreateProcess :: CreateProcess
defaultCreateProcess :: CreateProcess
defaultCreateProcess =
  CreateProcess :: CmdSpec
-> Maybe FilePath
-> Maybe [(FilePath, FilePath)]
-> StdStream
-> StdStream
-> StdStream
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Maybe GroupID
-> Maybe UserID
-> Bool
-> CreateProcess
CreateProcess
    { cmdspec :: CmdSpec
cmdspec = FilePath -> CmdSpec
ShellCommand ""
    , cwd :: Maybe FilePath
cwd = Maybe FilePath
forall a. Maybe a
Nothing
    , env :: Maybe [(FilePath, FilePath)]
env = Maybe [(FilePath, FilePath)]
forall a. Maybe a
Nothing
    , std_in :: StdStream
std_in = StdStream
Inherit
    , std_out :: StdStream
std_out = StdStream
Inherit
    , std_err :: StdStream
std_err = StdStream
Inherit
    , close_fds :: Bool
close_fds = Bool
False
    , create_group :: Bool
create_group = Bool
False
    , delegate_ctlc :: Bool
delegate_ctlc = Bool
False
    , new_session :: Bool
new_session = Bool
False
#if MIN_VERSION_process(1, 3, 0)
    , detach_console :: Bool
detach_console = Bool
False
    , create_new_console :: Bool
create_new_console = Bool
False
#endif
#if MIN_VERSION_process(1, 4, 0)
    , child_group :: Maybe GroupID
child_group = Maybe GroupID
forall a. Maybe a
Nothing
    , child_user :: Maybe UserID
child_user = Maybe UserID
forall a. Maybe a
Nothing
#endif
#if MIN_VERSION_process(1, 5, 0)
    , use_process_jobs :: Bool
use_process_jobs = Bool
False
#endif
    }