    {-# LANGUAGE DeriveDataTypeable #-}

    -- |  A module to deal with verbosity, how \'chatty\' a program should be.
    --    This module defines the 'Verbosity' data type, along with functions
    --    for manipulating a global verbosity value.
    module System.Console.CmdArgs.Verbosity(
        Verbosity(..), setVerbosity, getVerbosity,
        isNormal, isLoud,
        whenNormal, whenLoud
        ) where

    import Control.Monad
    import Data.Data
    import Data.IORef
    import System.IO.Unsafe

    -- | The verbosity data type
    data Verbosity
        = Quiet  -- ^ Only output essential messages (typically errors)
        | Normal -- ^ Output normal messages (typically errors and warnings)
        | Loud   -- ^ Output lots of messages (typically errors, warnings and status updates)
          deriving (Verbosity -> Verbosity -> Bool
    (Verbosity -> Verbosity -> Bool)
    -> (Verbosity -> Verbosity -> Bool) -> Eq Verbosity
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Verbosity -> Verbosity -> Bool
    == :: Verbosity -> Verbosity -> Bool
    $c/= :: Verbosity -> Verbosity -> Bool
    /= :: Verbosity -> Verbosity -> Bool
    Eq,Eq Verbosity
    Eq Verbosity
    -> (Verbosity -> Verbosity -> Ordering)
    -> (Verbosity -> Verbosity -> Bool)
    -> (Verbosity -> Verbosity -> Bool)
    -> (Verbosity -> Verbosity -> Bool)
    -> (Verbosity -> Verbosity -> Bool)
    -> (Verbosity -> Verbosity -> Verbosity)
    -> (Verbosity -> Verbosity -> Verbosity)
    -> Ord Verbosity
    Verbosity -> Verbosity -> Bool
    Verbosity -> Verbosity -> Ordering
    Verbosity -> Verbosity -> Verbosity
    forall a.
    Eq a
    -> (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: Verbosity -> Verbosity -> Ordering
    compare :: Verbosity -> Verbosity -> Ordering
    $c< :: Verbosity -> Verbosity -> Bool
    < :: Verbosity -> Verbosity -> Bool
    $c<= :: Verbosity -> Verbosity -> Bool
    <= :: Verbosity -> Verbosity -> Bool
    $c> :: Verbosity -> Verbosity -> Bool
    > :: Verbosity -> Verbosity -> Bool
    $c>= :: Verbosity -> Verbosity -> Bool
    >= :: Verbosity -> Verbosity -> Bool
    $cmax :: Verbosity -> Verbosity -> Verbosity
    max :: Verbosity -> Verbosity -> Verbosity
    $cmin :: Verbosity -> Verbosity -> Verbosity
    min :: Verbosity -> Verbosity -> Verbosity
    Ord,Verbosity
    Verbosity -> Verbosity -> Bounded Verbosity
    forall a. a -> a -> Bounded a
    $cminBound :: Verbosity
    minBound :: Verbosity
    $cmaxBound :: Verbosity
    maxBound :: Verbosity
    Bounded,Int -> Verbosity
    Verbosity -> Int
    Verbosity -> [Verbosity]
    Verbosity -> Verbosity
    Verbosity -> Verbosity -> [Verbosity]
    Verbosity -> Verbosity -> Verbosity -> [Verbosity]
    (Verbosity -> Verbosity)
    -> (Verbosity -> Verbosity)
    -> (Int -> Verbosity)
    -> (Verbosity -> Int)
    -> (Verbosity -> [Verbosity])
    -> (Verbosity -> Verbosity -> [Verbosity])
    -> (Verbosity -> Verbosity -> [Verbosity])
    -> (Verbosity -> Verbosity -> Verbosity -> [Verbosity])
    -> Enum Verbosity
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: Verbosity -> Verbosity
    succ :: Verbosity -> Verbosity
    $cpred :: Verbosity -> Verbosity
    pred :: Verbosity -> Verbosity
    $ctoEnum :: Int -> Verbosity
    toEnum :: Int -> Verbosity
    $cfromEnum :: Verbosity -> Int
    fromEnum :: Verbosity -> Int
    $cenumFrom :: Verbosity -> [Verbosity]
    enumFrom :: Verbosity -> [Verbosity]
    $cenumFromThen :: Verbosity -> Verbosity -> [Verbosity]
    enumFromThen :: Verbosity -> Verbosity -> [Verbosity]
    $cenumFromTo :: Verbosity -> Verbosity -> [Verbosity]
    enumFromTo :: Verbosity -> Verbosity -> [Verbosity]
    $cenumFromThenTo :: Verbosity -> Verbosity -> Verbosity -> [Verbosity]
    enumFromThenTo :: Verbosity -> Verbosity -> Verbosity -> [Verbosity]
    Enum,Int -> Verbosity -> ShowS
    [Verbosity] -> ShowS
    Verbosity -> String
    (Int -> Verbosity -> ShowS)
    -> (Verbosity -> String)
    -> ([Verbosity] -> ShowS)
    -> Show Verbosity
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Verbosity -> ShowS
    showsPrec :: Int -> Verbosity -> ShowS
    $cshow :: Verbosity -> String
    show :: Verbosity -> String
    $cshowList :: [Verbosity] -> ShowS
    showList :: [Verbosity] -> ShowS
    Show,ReadPrec [Verbosity]
    ReadPrec Verbosity
    Int -> ReadS Verbosity
    ReadS [Verbosity]
    (Int -> ReadS Verbosity)
    -> ReadS [Verbosity]
    -> ReadPrec Verbosity
    -> ReadPrec [Verbosity]
    -> Read Verbosity
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS Verbosity
    readsPrec :: Int -> ReadS Verbosity
    $creadList :: ReadS [Verbosity]
    readList :: ReadS [Verbosity]
    $creadPrec :: ReadPrec Verbosity
    readPrec :: ReadPrec Verbosity
    $creadListPrec :: ReadPrec [Verbosity]
    readListPrec :: ReadPrec [Verbosity]
    Read,Typeable Verbosity
    Typeable Verbosity
    -> (forall (c :: * -> *).
        (forall d b. Data d => c (d -> b) -> d -> c b)
        -> (forall g. g -> c g) -> Verbosity -> c Verbosity)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c Verbosity)
    -> (Verbosity -> Constr)
    -> (Verbosity -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c Verbosity))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Verbosity))
    -> ((forall b. Data b => b -> b) -> Verbosity -> Verbosity)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> Verbosity -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> Verbosity -> r)
    -> (forall u. (forall d. Data d => d -> u) -> Verbosity -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> Verbosity -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> Verbosity -> m Verbosity)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Verbosity -> m Verbosity)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Verbosity -> m Verbosity)
    -> Data Verbosity
    Verbosity -> Constr
    Verbosity -> DataType
    (forall b. Data b => b -> b) -> Verbosity -> Verbosity
    forall a.
    Typeable a
    -> (forall (c :: * -> *).
        (forall d b. Data d => c (d -> b) -> d -> c b)
        -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> Verbosity -> u
    forall u. (forall d. Data d => d -> u) -> Verbosity -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Verbosity -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Verbosity -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Verbosity -> m Verbosity
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Verbosity -> m Verbosity
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Verbosity
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Verbosity -> c Verbosity
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Verbosity)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Verbosity)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Verbosity -> c Verbosity
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Verbosity -> c Verbosity
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Verbosity
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Verbosity
    $ctoConstr :: Verbosity -> Constr
    toConstr :: Verbosity -> Constr
    $cdataTypeOf :: Verbosity -> DataType
    dataTypeOf :: Verbosity -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Verbosity)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Verbosity)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Verbosity)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Verbosity)
    $cgmapT :: (forall b. Data b => b -> b) -> Verbosity -> Verbosity
    gmapT :: (forall b. Data b => b -> b) -> Verbosity -> Verbosity
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Verbosity -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Verbosity -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Verbosity -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Verbosity -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> Verbosity -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> Verbosity -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Verbosity -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Verbosity -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Verbosity -> m Verbosity
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Verbosity -> m Verbosity
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Verbosity -> m Verbosity
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Verbosity -> m Verbosity
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Verbosity -> m Verbosity
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Verbosity -> m Verbosity
    Data,Typeable)

    {-# NOINLINE ref #-}
    ref :: IORef Verbosity
    ref :: IORef Verbosity
    ref = IO (IORef Verbosity) -> IORef Verbosity
    forall a. IO a -> a
    unsafePerformIO (IO (IORef Verbosity) -> IORef Verbosity)
    -> IO (IORef Verbosity) -> IORef Verbosity
    forall a b. (a -> b) -> a -> b
    $ Verbosity -> IO (IORef Verbosity)
    forall a. a -> IO (IORef a)
    newIORef Verbosity
    Normal

    -- | Set the global verbosity.
    setVerbosity :: Verbosity -> IO ()
    setVerbosity :: Verbosity -> IO ()
    setVerbosity = IORef Verbosity -> Verbosity -> IO ()
    forall a. IORef a -> a -> IO ()
    writeIORef IORef Verbosity
    ref

    -- | Get the global verbosity. Initially @Normal@ before any calls to 'setVerbosity'.
    getVerbosity :: IO Verbosity
    getVerbosity :: IO Verbosity
    getVerbosity = IORef Verbosity -> IO Verbosity
    forall a. IORef a -> IO a
    readIORef IORef Verbosity
    ref

    -- | Used to test if warnings should be output to the user.
    --   @True@ if the verbosity is set to 'Normal' or 'Loud' (when @--quiet@ is /not/ specified).
    isNormal :: IO Bool
    isNormal :: IO Bool
    isNormal = (Verbosity -> Bool) -> IO Verbosity -> IO Bool
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Verbosity -> Verbosity -> Bool
    forall a. Ord a => a -> a -> Bool
    >=Verbosity
    Normal) IO Verbosity
    getVerbosity

    -- | Used to test if status updates should be output to the user.
    --   @True@ if the verbosity is set to 'Loud' (when @--verbose@ is specified).
    isLoud :: IO Bool
    isLoud :: IO Bool
    isLoud = (Verbosity -> Bool) -> IO Verbosity -> IO Bool
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Verbosity -> Verbosity -> Bool
    forall a. Ord a => a -> a -> Bool
    >=Verbosity
    Loud) IO Verbosity
    getVerbosity

    -- | An action to perform if the verbosity is normal or higher, based on 'isNormal'.
    whenNormal :: IO () -> IO ()
    whenNormal :: IO () -> IO ()
    whenNormal IO ()
    act = do
        Bool
    b <- IO Bool
    isNormal
        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when Bool
    b IO ()
    act

    -- | An action to perform if the verbosity is loud, based on 'isLoud'.
    whenLoud :: IO () -> IO ()
    whenLoud :: IO () -> IO ()
    whenLoud IO ()
    act = do
        Bool
    b <- IO Bool
    isLoud
        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when Bool
    b IO ()
    act