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

#if __GLASGOW_HASKELL__ >= 710
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns #-}
#endif

-----------------------------------------------------------------------------
-- |
-- 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
#if __GLASGOW_HASKELL__ >= 710
  , pattern ExitFailure_
  , pattern ExitSuccess_
#endif
  ) 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 :: p ExitCode (f ExitCode) -> p ExitCode (f ExitCode)
_ExitCode = p ExitCode (f ExitCode) -> p ExitCode (f ExitCode)
forall a. a -> a
id
  {-# INLINE _ExitCode #-}

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

-- | indicates successful termination;
--
-- @
-- '_ExitSuccess' :: 'Prism'' 'ExitCode'      ()
-- '_ExitSuccess' :: 'Prism'' 'SomeException' ()
-- @
_ExitSuccess :: AsExitCode t => Prism' t ()
_ExitSuccess :: Prism' t ()
_ExitSuccess = p ExitCode (f ExitCode) -> p t (f t)
forall t. AsExitCode t => 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 (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 (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 (p :: * -> * -> *) b c a.
Profunctor p =>
(b -> c) -> p a b -> p a c
rmap (ExitCode
ExitSuccess ExitCode -> f () -> f ExitCode
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 (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 :: Prism' t Int
_ExitFailure = p ExitCode (f ExitCode) -> p t (f t)
forall t. AsExitCode t => 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 (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 (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 (p :: * -> * -> *) b c a.
Profunctor p =>
(b -> c) -> p a b -> p a c
rmap ((Int -> ExitCode) -> f Int -> f ExitCode
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 (f :: * -> *) a. Applicative f => a -> f a
pure ExitCode
t)
{-# INLINE _ExitFailure #-}

#if __GLASGOW_HASKELL__ >= 710
pattern $bExitSuccess_ :: s
$mExitSuccess_ :: forall r s. AsExitCode s => s -> (Void# -> r) -> (Void# -> r) -> r
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 ()
_ExitSuccess ()

pattern $bExitFailure_ :: Int -> s
$mExitFailure_ :: forall r s. AsExitCode s => s -> (Int -> r) -> (Void# -> r) -> r
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
_ExitFailure Int
a
#endif