{-# LANGUAGE DeriveGeneric #-}
-- | License: GPL-3.0-or-later AND BSD-3-Clause
--
-- Optimization level.
module Cabal.Optimization (
    Optimization (..),
    ) where

import Control.Applicative (Alternative (..))
import Control.DeepSeq     (NFData (..))
import GHC.Generics        (Generic)

import qualified Distribution.Compat.CharParsing as C
import qualified Distribution.Parsec             as C
import qualified Distribution.Pretty             as C
import qualified Text.PrettyPrint                as PP

-- | Optimization level, may be turned on with 'True' or off with 'False',
-- or set an explicit optimization level.
data Optimization
    = OptimizationOn
    | OptimizationOff
    | OptimizationLevel Int
  deriving (Optimization -> Optimization -> Bool
(Optimization -> Optimization -> Bool)
-> (Optimization -> Optimization -> Bool) -> Eq Optimization
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Optimization -> Optimization -> Bool
$c/= :: Optimization -> Optimization -> Bool
== :: Optimization -> Optimization -> Bool
$c== :: Optimization -> Optimization -> Bool
Eq, Int -> Optimization -> ShowS
[Optimization] -> ShowS
Optimization -> String
(Int -> Optimization -> ShowS)
-> (Optimization -> String)
-> ([Optimization] -> ShowS)
-> Show Optimization
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Optimization] -> ShowS
$cshowList :: [Optimization] -> ShowS
show :: Optimization -> String
$cshow :: Optimization -> String
showsPrec :: Int -> Optimization -> ShowS
$cshowsPrec :: Int -> Optimization -> ShowS
Show, (forall x. Optimization -> Rep Optimization x)
-> (forall x. Rep Optimization x -> Optimization)
-> Generic Optimization
forall x. Rep Optimization x -> Optimization
forall x. Optimization -> Rep Optimization x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Optimization x -> Optimization
$cfrom :: forall x. Optimization -> Rep Optimization x
Generic)

instance C.Parsec Optimization where
    parsec :: m Optimization
parsec = m Optimization
boolean m Optimization -> m Optimization -> m Optimization
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> m Optimization
numeric where
        boolean :: m Optimization
boolean = Optimization -> Optimization -> Bool -> Optimization
forall p. p -> p -> Bool -> p
ite Optimization
OptimizationOn Optimization
OptimizationOff (Bool -> Optimization) -> m Bool -> m Optimization
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Bool
forall a (m :: * -> *). (Parsec a, CabalParsing m) => m a
C.parsec
        numeric :: m Optimization
numeric = Int -> Optimization
OptimizationLevel (Int -> Optimization) -> m Int -> m Optimization
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Int
forall (m :: * -> *) a. (CharParsing m, Integral a) => m a
C.integral

        ite :: p -> p -> Bool -> p
ite p
t p
_ Bool
True  = p
t
        ite p
_ p
f Bool
False = p
f

instance C.Pretty Optimization where
    pretty :: Optimization -> Doc
pretty Optimization
OptimizationOn        = Bool -> Doc
forall a. Pretty a => a -> Doc
C.pretty Bool
True
    pretty Optimization
OptimizationOff       = Bool -> Doc
forall a. Pretty a => a -> Doc
C.pretty Bool
False
    pretty (OptimizationLevel Int
l) = Int -> Doc
PP.int Int
l

-- | @since 0.2.1
instance NFData Optimization