{-# LANGUAGE CPP #-}

module Portage.Use (
  -- * main structures
  UseFlag(..),
  Use(..),
  dispUses,
  -- * helpers
  mkUse,
  mkNotUse,
  mkQUse
  ) where

import qualified Text.PrettyPrint as Disp
import Text.PrettyPrint ((<>))
import Distribution.Pretty (Pretty(..))

import           Control.DeepSeq (NFData(..))

#if MIN_VERSION_base(4,11,0)
import Prelude hiding ((<>))
#endif

-- | Use variable modificator
data UseFlag = UseFlag Use           -- ^ no modificator
             | E UseFlag             -- ^ = modificator (Equiv    mark)
             | Q UseFlag             -- ^ ? modificator (Question mark)
             | X UseFlag             -- ^ ! modificator (eXclamation mark)
             | N UseFlag             -- ^ - modificator 
             deriving (UseFlag -> UseFlag -> Bool
(UseFlag -> UseFlag -> Bool)
-> (UseFlag -> UseFlag -> Bool) -> Eq UseFlag
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: UseFlag -> UseFlag -> Bool
$c/= :: UseFlag -> UseFlag -> Bool
== :: UseFlag -> UseFlag -> Bool
$c== :: UseFlag -> UseFlag -> Bool
Eq,Int -> UseFlag -> ShowS
[UseFlag] -> ShowS
UseFlag -> String
(Int -> UseFlag -> ShowS)
-> (UseFlag -> String) -> ([UseFlag] -> ShowS) -> Show UseFlag
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [UseFlag] -> ShowS
$cshowList :: [UseFlag] -> ShowS
show :: UseFlag -> String
$cshow :: UseFlag -> String
showsPrec :: Int -> UseFlag -> ShowS
$cshowsPrec :: Int -> UseFlag -> ShowS
Show,Eq UseFlag
Eq UseFlag
-> (UseFlag -> UseFlag -> Ordering)
-> (UseFlag -> UseFlag -> Bool)
-> (UseFlag -> UseFlag -> Bool)
-> (UseFlag -> UseFlag -> Bool)
-> (UseFlag -> UseFlag -> Bool)
-> (UseFlag -> UseFlag -> UseFlag)
-> (UseFlag -> UseFlag -> UseFlag)
-> Ord UseFlag
UseFlag -> UseFlag -> Bool
UseFlag -> UseFlag -> Ordering
UseFlag -> UseFlag -> UseFlag
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
min :: UseFlag -> UseFlag -> UseFlag
$cmin :: UseFlag -> UseFlag -> UseFlag
max :: UseFlag -> UseFlag -> UseFlag
$cmax :: UseFlag -> UseFlag -> UseFlag
>= :: UseFlag -> UseFlag -> Bool
$c>= :: UseFlag -> UseFlag -> Bool
> :: UseFlag -> UseFlag -> Bool
$c> :: UseFlag -> UseFlag -> Bool
<= :: UseFlag -> UseFlag -> Bool
$c<= :: UseFlag -> UseFlag -> Bool
< :: UseFlag -> UseFlag -> Bool
$c< :: UseFlag -> UseFlag -> Bool
compare :: UseFlag -> UseFlag -> Ordering
$ccompare :: UseFlag -> UseFlag -> Ordering
$cp1Ord :: Eq UseFlag
Ord,ReadPrec [UseFlag]
ReadPrec UseFlag
Int -> ReadS UseFlag
ReadS [UseFlag]
(Int -> ReadS UseFlag)
-> ReadS [UseFlag]
-> ReadPrec UseFlag
-> ReadPrec [UseFlag]
-> Read UseFlag
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [UseFlag]
$creadListPrec :: ReadPrec [UseFlag]
readPrec :: ReadPrec UseFlag
$creadPrec :: ReadPrec UseFlag
readList :: ReadS [UseFlag]
$creadList :: ReadS [UseFlag]
readsPrec :: Int -> ReadS UseFlag
$creadsPrec :: Int -> ReadS UseFlag
Read)

instance NFData UseFlag where
  rnf :: UseFlag -> ()
rnf (UseFlag Use
u) = Use -> ()
forall a. NFData a => a -> ()
rnf Use
u
  rnf (E UseFlag
f) = UseFlag -> ()
forall a. NFData a => a -> ()
rnf UseFlag
f
  rnf (Q UseFlag
f) = UseFlag -> ()
forall a. NFData a => a -> ()
rnf UseFlag
f
  rnf (X UseFlag
f) = UseFlag -> ()
forall a. NFData a => a -> ()
rnf UseFlag
f
  rnf (N UseFlag
f) = UseFlag -> ()
forall a. NFData a => a -> ()
rnf UseFlag
f

instance Pretty UseFlag where
  pretty :: UseFlag -> Doc
pretty = UseFlag -> Doc
showModificator

mkUse :: Use -> UseFlag
mkUse :: Use -> UseFlag
mkUse  = Use -> UseFlag
UseFlag 

mkNotUse :: Use -> UseFlag
mkNotUse :: Use -> UseFlag
mkNotUse = UseFlag -> UseFlag
N (UseFlag -> UseFlag) -> (Use -> UseFlag) -> Use -> UseFlag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Use -> UseFlag
UseFlag

mkQUse :: Use -> UseFlag
mkQUse :: Use -> UseFlag
mkQUse = UseFlag -> UseFlag
Q (UseFlag -> UseFlag) -> (Use -> UseFlag) -> Use -> UseFlag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Use -> UseFlag
UseFlag

showModificator :: UseFlag -> Disp.Doc
showModificator :: UseFlag -> Doc
showModificator (UseFlag Use
u) = Use -> Doc
forall a. Pretty a => a -> Doc
pretty Use
u
showModificator (X UseFlag
u)     = Char -> Doc
Disp.char Char
'!' Doc -> Doc -> Doc
<> UseFlag -> Doc
forall a. Pretty a => a -> Doc
pretty UseFlag
u
showModificator (Q UseFlag
u)     = UseFlag -> Doc
forall a. Pretty a => a -> Doc
pretty UseFlag
u Doc -> Doc -> Doc
<> Char -> Doc
Disp.char Char
'?'
showModificator (E UseFlag
u)     = UseFlag -> Doc
forall a. Pretty a => a -> Doc
pretty UseFlag
u Doc -> Doc -> Doc
<> Char -> Doc
Disp.char Char
'='
showModificator (N UseFlag
u)     = Char -> Doc
Disp.char Char
'-' Doc -> Doc -> Doc
<> UseFlag -> Doc
forall a. Pretty a => a -> Doc
pretty UseFlag
u

dispUses :: [UseFlag] -> Disp.Doc
dispUses :: [UseFlag] -> Doc
dispUses [] = Doc
Disp.empty
dispUses [UseFlag]
us = Doc -> Doc
Disp.brackets (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ [Doc] -> Doc
Disp.hcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ (Doc -> [Doc] -> [Doc]
Disp.punctuate (String -> Doc
Disp.text String
", ")) ([Doc] -> [Doc]) -> [Doc] -> [Doc]
forall a b. (a -> b) -> a -> b
$ (UseFlag -> Doc) -> [UseFlag] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map UseFlag -> Doc
forall a. Pretty a => a -> Doc
pretty [UseFlag]
us

newtype Use = Use String
    deriving (Use -> Use -> Bool
(Use -> Use -> Bool) -> (Use -> Use -> Bool) -> Eq Use
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Use -> Use -> Bool
$c/= :: Use -> Use -> Bool
== :: Use -> Use -> Bool
$c== :: Use -> Use -> Bool
Eq, ReadPrec [Use]
ReadPrec Use
Int -> ReadS Use
ReadS [Use]
(Int -> ReadS Use)
-> ReadS [Use] -> ReadPrec Use -> ReadPrec [Use] -> Read Use
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Use]
$creadListPrec :: ReadPrec [Use]
readPrec :: ReadPrec Use
$creadPrec :: ReadPrec Use
readList :: ReadS [Use]
$creadList :: ReadS [Use]
readsPrec :: Int -> ReadS Use
$creadsPrec :: Int -> ReadS Use
Read, Int -> Use -> ShowS
[Use] -> ShowS
Use -> String
(Int -> Use -> ShowS)
-> (Use -> String) -> ([Use] -> ShowS) -> Show Use
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Use] -> ShowS
$cshowList :: [Use] -> ShowS
show :: Use -> String
$cshow :: Use -> String
showsPrec :: Int -> Use -> ShowS
$cshowsPrec :: Int -> Use -> ShowS
Show)

instance NFData Use where
  rnf :: Use -> ()
rnf (Use String
s) = String -> ()
forall a. NFData a => a -> ()
rnf String
s

instance Pretty Use where
  pretty :: Use -> Doc
pretty (Use String
u) = String -> Doc
Disp.text String
u

instance Ord Use where
    compare :: Use -> Use -> Ordering
compare (Use String
a) (Use String
b) = case (String
a,String
b) of
        (String
"test", String
"test") -> Ordering
EQ
        (String
"test", String
_)      -> Ordering
LT
        (String
_, String
"test")      -> Ordering
GT
        (String
_, String
_)           -> String
a String -> String -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` String
b