{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns #-}

-----------------------------------------------------------------------------
-- |
-- Module      :  System.Exit.Lens
-- Copyright   :  (C) 2013-16 Edward Kmett
-- License     :  BSD-style (see the file LICENSE)
-- Maintainer  :  Edward Kmett <ekmett@gmail.com>
-- Stability   :  provisional
-- Portability :  Control.Exception
--
-- These prisms can be used with the combinators in "Control.Exception.Lens".
----------------------------------------------------------------------------
module System.Exit.Lens
  ( AsExitCode(..)
  , _ExitFailure
  , _ExitSuccess
  , pattern ExitFailure_
  , pattern ExitSuccess_
  ) where

import Prelude ()

import Control.Exception
import Control.Exception.Lens
import Control.Lens
import Control.Lens.Internal.Prelude
import System.Exit

-- | Exit codes that a program can return with:
class AsExitCode t where
  _ExitCode :: Prism' t ExitCode

instance AsExitCode ExitCode where
  _ExitCode :: Prism' ExitCode ExitCode
_ExitCode = p ExitCode (f ExitCode) -> p ExitCode (f ExitCode)
forall a. a -> a
id
  {-# INLINE _ExitCode #-}

instance AsExitCode SomeException where
  _ExitCode :: Prism' SomeException ExitCode
_ExitCode = p ExitCode (f ExitCode) -> p SomeException (f SomeException)
forall a. Exception a => Prism' SomeException a
Prism' SomeException ExitCode
exception
  {-# INLINE _ExitCode #-}

-- | indicates successful termination;
--
-- @
-- '_ExitSuccess' :: 'Prism'' 'ExitCode'      ()
-- '_ExitSuccess' :: 'Prism'' 'SomeException' ()
-- @
_ExitSuccess :: AsExitCode t => Prism' t ()
_ExitSuccess :: forall t. AsExitCode t => Prism' t ()
_ExitSuccess = p ExitCode (f ExitCode) -> p t (f t)
forall t. AsExitCode t => Prism' t ExitCode
Prism' t ExitCode
_ExitCode (p ExitCode (f ExitCode) -> p t (f t))
-> (p () (f ()) -> p ExitCode (f ExitCode))
-> p () (f ())
-> p t (f t)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ExitCode -> Either (f ExitCode) ())
-> (Either (f ExitCode) (f ExitCode) -> f ExitCode)
-> p (Either (f ExitCode) ()) (Either (f ExitCode) (f ExitCode))
-> p ExitCode (f ExitCode)
forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap ExitCode -> Either (f ExitCode) ()
forall {f :: * -> *}.
Applicative f =>
ExitCode -> Either (f ExitCode) ()
seta ((f ExitCode -> f ExitCode)
-> (f ExitCode -> f ExitCode)
-> Either (f ExitCode) (f ExitCode)
-> f ExitCode
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either f ExitCode -> f ExitCode
forall a. a -> a
id f ExitCode -> f ExitCode
forall a. a -> a
id) (p (Either (f ExitCode) ()) (Either (f ExitCode) (f ExitCode))
 -> p ExitCode (f ExitCode))
-> (p () (f ())
    -> p (Either (f ExitCode) ()) (Either (f ExitCode) (f ExitCode)))
-> p () (f ())
-> p ExitCode (f ExitCode)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p () (f ExitCode)
-> p (Either (f ExitCode) ()) (Either (f ExitCode) (f ExitCode))
forall a b c. p a b -> p (Either c a) (Either c b)
forall (p :: * -> * -> *) a b c.
Choice p =>
p a b -> p (Either c a) (Either c b)
right' (p () (f ExitCode)
 -> p (Either (f ExitCode) ()) (Either (f ExitCode) (f ExitCode)))
-> (p () (f ()) -> p () (f ExitCode))
-> p () (f ())
-> p (Either (f ExitCode) ()) (Either (f ExitCode) (f ExitCode))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (f () -> f ExitCode) -> p () (f ()) -> p () (f ExitCode)
forall b c a. (b -> c) -> p a b -> p a c
forall (p :: * -> * -> *) b c a.
Profunctor p =>
(b -> c) -> p a b -> p a c
rmap (ExitCode
ExitSuccess ExitCode -> f () -> f ExitCode
forall a b. a -> f b -> f a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$) where
  seta :: ExitCode -> Either (f ExitCode) ()
seta ExitCode
ExitSuccess = () -> Either (f ExitCode) ()
forall a b. b -> Either a b
Right ()
  seta ExitCode
t           = f ExitCode -> Either (f ExitCode) ()
forall a b. a -> Either a b
Left  (ExitCode -> f ExitCode
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ExitCode
t)
{-# INLINE _ExitSuccess #-}


-- | indicates program failure with an exit code. The exact interpretation of the code is operating-system dependent. In particular, some values may be prohibited (e.g. 0 on a POSIX-compliant system).
--
-- @
-- '_ExitFailure' :: 'Prism'' 'ExitCode'      'Int'
-- '_ExitFailure' :: 'Prism'' 'SomeException' 'Int'
-- @
_ExitFailure :: AsExitCode t => Prism' t Int
_ExitFailure :: forall t. AsExitCode t => Prism' t Int
_ExitFailure = p ExitCode (f ExitCode) -> p t (f t)
forall t. AsExitCode t => Prism' t ExitCode
Prism' t ExitCode
_ExitCode (p ExitCode (f ExitCode) -> p t (f t))
-> (p Int (f Int) -> p ExitCode (f ExitCode))
-> p Int (f Int)
-> p t (f t)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ExitCode -> Either (f ExitCode) Int)
-> (Either (f ExitCode) (f ExitCode) -> f ExitCode)
-> p (Either (f ExitCode) Int) (Either (f ExitCode) (f ExitCode))
-> p ExitCode (f ExitCode)
forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap ExitCode -> Either (f ExitCode) Int
forall {f :: * -> *}.
Applicative f =>
ExitCode -> Either (f ExitCode) Int
seta ((f ExitCode -> f ExitCode)
-> (f ExitCode -> f ExitCode)
-> Either (f ExitCode) (f ExitCode)
-> f ExitCode
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either f ExitCode -> f ExitCode
forall a. a -> a
id f ExitCode -> f ExitCode
forall a. a -> a
id) (p (Either (f ExitCode) Int) (Either (f ExitCode) (f ExitCode))
 -> p ExitCode (f ExitCode))
-> (p Int (f Int)
    -> p (Either (f ExitCode) Int) (Either (f ExitCode) (f ExitCode)))
-> p Int (f Int)
-> p ExitCode (f ExitCode)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p Int (f ExitCode)
-> p (Either (f ExitCode) Int) (Either (f ExitCode) (f ExitCode))
forall a b c. p a b -> p (Either c a) (Either c b)
forall (p :: * -> * -> *) a b c.
Choice p =>
p a b -> p (Either c a) (Either c b)
right' (p Int (f ExitCode)
 -> p (Either (f ExitCode) Int) (Either (f ExitCode) (f ExitCode)))
-> (p Int (f Int) -> p Int (f ExitCode))
-> p Int (f Int)
-> p (Either (f ExitCode) Int) (Either (f ExitCode) (f ExitCode))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (f Int -> f ExitCode) -> p Int (f Int) -> p Int (f ExitCode)
forall b c a. (b -> c) -> p a b -> p a c
forall (p :: * -> * -> *) b c a.
Profunctor p =>
(b -> c) -> p a b -> p a c
rmap ((Int -> ExitCode) -> f Int -> f ExitCode
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> ExitCode
ExitFailure) where
  seta :: ExitCode -> Either (f ExitCode) Int
seta (ExitFailure Int
i) = Int -> Either (f ExitCode) Int
forall a b. b -> Either a b
Right Int
i
  seta ExitCode
t               = f ExitCode -> Either (f ExitCode) Int
forall a b. a -> Either a b
Left  (ExitCode -> f ExitCode
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ExitCode
t)
{-# INLINE _ExitFailure #-}

pattern ExitSuccess_ :: AsExitCode s => s
pattern $mExitSuccess_ :: forall {r} {s}.
AsExitCode s =>
s -> ((# #) -> r) -> ((# #) -> r) -> r
$bExitSuccess_ :: forall s. AsExitCode s => s
ExitSuccess_ <- (has _ExitSuccess -> True) where
  ExitSuccess_ = AReview s () -> () -> s
forall b (m :: * -> *) t. MonadReader b m => AReview t b -> m t
review AReview s ()
forall t. AsExitCode t => Prism' t ()
Prism' s ()
_ExitSuccess ()

pattern ExitFailure_ :: AsExitCode s => Int -> s
pattern $mExitFailure_ :: forall {r} {s}.
AsExitCode s =>
s -> (Int -> r) -> ((# #) -> r) -> r
$bExitFailure_ :: forall s. AsExitCode s => Int -> s
ExitFailure_ a <- (preview _ExitFailure -> Just a) where
  ExitFailure_ Int
a = AReview s Int -> Int -> s
forall b (m :: * -> *) t. MonadReader b m => AReview t b -> m t
review AReview s Int
forall t. AsExitCode t => Prism' t Int
Prism' s Int
_ExitFailure Int
a