{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}

module Stack.Types.CabalConfigKey
  ( CabalConfigKey (..)
  , parseCabalConfigKey
  ) where

import           Data.Aeson.Types
                   ( FromJSON (..), FromJSONKey (..), FromJSONKeyFunction (..)
                   , withText
                   )
import qualified Data.Text as T
import           Stack.Prelude

-- | Which packages do configure opts apply to?

data CabalConfigKey
  = CCKTargets -- ^ See AGOTargets

  | CCKLocals -- ^ See AGOLocals

  | CCKEverything -- ^ See AGOEverything

  | CCKPackage !PackageName -- ^ A specific package

  deriving (Int -> CabalConfigKey -> ShowS
[CabalConfigKey] -> ShowS
CabalConfigKey -> String
(Int -> CabalConfigKey -> ShowS)
-> (CabalConfigKey -> String)
-> ([CabalConfigKey] -> ShowS)
-> Show CabalConfigKey
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CabalConfigKey -> ShowS
showsPrec :: Int -> CabalConfigKey -> ShowS
$cshow :: CabalConfigKey -> String
show :: CabalConfigKey -> String
$cshowList :: [CabalConfigKey] -> ShowS
showList :: [CabalConfigKey] -> ShowS
Show, ReadPrec [CabalConfigKey]
ReadPrec CabalConfigKey
Int -> ReadS CabalConfigKey
ReadS [CabalConfigKey]
(Int -> ReadS CabalConfigKey)
-> ReadS [CabalConfigKey]
-> ReadPrec CabalConfigKey
-> ReadPrec [CabalConfigKey]
-> Read CabalConfigKey
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS CabalConfigKey
readsPrec :: Int -> ReadS CabalConfigKey
$creadList :: ReadS [CabalConfigKey]
readList :: ReadS [CabalConfigKey]
$creadPrec :: ReadPrec CabalConfigKey
readPrec :: ReadPrec CabalConfigKey
$creadListPrec :: ReadPrec [CabalConfigKey]
readListPrec :: ReadPrec [CabalConfigKey]
Read, CabalConfigKey -> CabalConfigKey -> Bool
(CabalConfigKey -> CabalConfigKey -> Bool)
-> (CabalConfigKey -> CabalConfigKey -> Bool) -> Eq CabalConfigKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CabalConfigKey -> CabalConfigKey -> Bool
== :: CabalConfigKey -> CabalConfigKey -> Bool
$c/= :: CabalConfigKey -> CabalConfigKey -> Bool
/= :: CabalConfigKey -> CabalConfigKey -> Bool
Eq, Eq CabalConfigKey
Eq CabalConfigKey
-> (CabalConfigKey -> CabalConfigKey -> Ordering)
-> (CabalConfigKey -> CabalConfigKey -> Bool)
-> (CabalConfigKey -> CabalConfigKey -> Bool)
-> (CabalConfigKey -> CabalConfigKey -> Bool)
-> (CabalConfigKey -> CabalConfigKey -> Bool)
-> (CabalConfigKey -> CabalConfigKey -> CabalConfigKey)
-> (CabalConfigKey -> CabalConfigKey -> CabalConfigKey)
-> Ord CabalConfigKey
CabalConfigKey -> CabalConfigKey -> Bool
CabalConfigKey -> CabalConfigKey -> Ordering
CabalConfigKey -> CabalConfigKey -> CabalConfigKey
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 :: CabalConfigKey -> CabalConfigKey -> Ordering
compare :: CabalConfigKey -> CabalConfigKey -> Ordering
$c< :: CabalConfigKey -> CabalConfigKey -> Bool
< :: CabalConfigKey -> CabalConfigKey -> Bool
$c<= :: CabalConfigKey -> CabalConfigKey -> Bool
<= :: CabalConfigKey -> CabalConfigKey -> Bool
$c> :: CabalConfigKey -> CabalConfigKey -> Bool
> :: CabalConfigKey -> CabalConfigKey -> Bool
$c>= :: CabalConfigKey -> CabalConfigKey -> Bool
>= :: CabalConfigKey -> CabalConfigKey -> Bool
$cmax :: CabalConfigKey -> CabalConfigKey -> CabalConfigKey
max :: CabalConfigKey -> CabalConfigKey -> CabalConfigKey
$cmin :: CabalConfigKey -> CabalConfigKey -> CabalConfigKey
min :: CabalConfigKey -> CabalConfigKey -> CabalConfigKey
Ord)

instance FromJSON CabalConfigKey where
  parseJSON :: Value -> Parser CabalConfigKey
parseJSON = String
-> (Text -> Parser CabalConfigKey)
-> Value
-> Parser CabalConfigKey
forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"CabalConfigKey" Text -> Parser CabalConfigKey
forall (m :: * -> *).
(Monad m, MonadFail m) =>
Text -> m CabalConfigKey
parseCabalConfigKey

instance FromJSONKey CabalConfigKey where
  fromJSONKey :: FromJSONKeyFunction CabalConfigKey
fromJSONKey = (Text -> Parser CabalConfigKey)
-> FromJSONKeyFunction CabalConfigKey
forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser Text -> Parser CabalConfigKey
forall (m :: * -> *).
(Monad m, MonadFail m) =>
Text -> m CabalConfigKey
parseCabalConfigKey

parseCabalConfigKey :: (Monad m, MonadFail m) => Text -> m CabalConfigKey
parseCabalConfigKey :: forall (m :: * -> *).
(Monad m, MonadFail m) =>
Text -> m CabalConfigKey
parseCabalConfigKey Text
"$targets" = CabalConfigKey -> m CabalConfigKey
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CabalConfigKey
CCKTargets
parseCabalConfigKey Text
"$locals" = CabalConfigKey -> m CabalConfigKey
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CabalConfigKey
CCKLocals
parseCabalConfigKey Text
"$everything" = CabalConfigKey -> m CabalConfigKey
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CabalConfigKey
CCKEverything
parseCabalConfigKey Text
name =
  case String -> Maybe PackageName
parsePackageName (String -> Maybe PackageName) -> String -> Maybe PackageName
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack Text
name of
    Maybe PackageName
Nothing -> String -> m CabalConfigKey
forall a. String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> m CabalConfigKey) -> String -> m CabalConfigKey
forall a b. (a -> b) -> a -> b
$ String
"Invalid CabalConfigKey: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
forall a. Show a => a -> String
show Text
name
    Just PackageName
x -> CabalConfigKey -> m CabalConfigKey
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CabalConfigKey -> m CabalConfigKey)
-> CabalConfigKey -> m CabalConfigKey
forall a b. (a -> b) -> a -> b
$ PackageName -> CabalConfigKey
CCKPackage PackageName
x