{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}

-- | Mini-abstraction to aid parallel development of experimental Cardano
-- features.
--
-- == Usage example
--
-- >>> import Data.Set (Set)
-- >>> import qualified Data.Set as Set
-- >>> import Cardano.Base.FeatureFlags (CardanoFeatureFlag (..))
--
-- >>> :{
-- logic :: Set CardanoFeatureFlag -> Int -> Int
-- logic featureFlags
--   | Set.member PerasFlag featureFlags = (+ 2)
--   | otherwise = (+ 1)
-- :}
module Cardano.Base.FeatureFlags (
  CardanoFeatureFlag (..),
) where

import qualified Data.Aeson as Aeson
import GHC.Generics (Generic)
import NoThunks.Class (NoThunks)

-- | An experimental Cardano feature.
data CardanoFeatureFlag
  = -- | Feature flag for Ouroboros Leios (higher throughput).
    LeiosFlag
  | -- | Feature flag for Ouroboros Peras (faster settlement).
    PerasFlag
  | -- | Feature flag for Ouroboros Phalanx (anti-grinding).
    PhalanxFlag
  deriving stock (Int -> CardanoFeatureFlag -> ShowS
[CardanoFeatureFlag] -> ShowS
CardanoFeatureFlag -> String
(Int -> CardanoFeatureFlag -> ShowS)
-> (CardanoFeatureFlag -> String)
-> ([CardanoFeatureFlag] -> ShowS)
-> Show CardanoFeatureFlag
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CardanoFeatureFlag -> ShowS
showsPrec :: Int -> CardanoFeatureFlag -> ShowS
$cshow :: CardanoFeatureFlag -> String
show :: CardanoFeatureFlag -> String
$cshowList :: [CardanoFeatureFlag] -> ShowS
showList :: [CardanoFeatureFlag] -> ShowS
Show, ReadPrec [CardanoFeatureFlag]
ReadPrec CardanoFeatureFlag
Int -> ReadS CardanoFeatureFlag
ReadS [CardanoFeatureFlag]
(Int -> ReadS CardanoFeatureFlag)
-> ReadS [CardanoFeatureFlag]
-> ReadPrec CardanoFeatureFlag
-> ReadPrec [CardanoFeatureFlag]
-> Read CardanoFeatureFlag
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS CardanoFeatureFlag
readsPrec :: Int -> ReadS CardanoFeatureFlag
$creadList :: ReadS [CardanoFeatureFlag]
readList :: ReadS [CardanoFeatureFlag]
$creadPrec :: ReadPrec CardanoFeatureFlag
readPrec :: ReadPrec CardanoFeatureFlag
$creadListPrec :: ReadPrec [CardanoFeatureFlag]
readListPrec :: ReadPrec [CardanoFeatureFlag]
Read, CardanoFeatureFlag -> CardanoFeatureFlag -> Bool
(CardanoFeatureFlag -> CardanoFeatureFlag -> Bool)
-> (CardanoFeatureFlag -> CardanoFeatureFlag -> Bool)
-> Eq CardanoFeatureFlag
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CardanoFeatureFlag -> CardanoFeatureFlag -> Bool
== :: CardanoFeatureFlag -> CardanoFeatureFlag -> Bool
$c/= :: CardanoFeatureFlag -> CardanoFeatureFlag -> Bool
/= :: CardanoFeatureFlag -> CardanoFeatureFlag -> Bool
Eq, Eq CardanoFeatureFlag
Eq CardanoFeatureFlag =>
(CardanoFeatureFlag -> CardanoFeatureFlag -> Ordering)
-> (CardanoFeatureFlag -> CardanoFeatureFlag -> Bool)
-> (CardanoFeatureFlag -> CardanoFeatureFlag -> Bool)
-> (CardanoFeatureFlag -> CardanoFeatureFlag -> Bool)
-> (CardanoFeatureFlag -> CardanoFeatureFlag -> Bool)
-> (CardanoFeatureFlag -> CardanoFeatureFlag -> CardanoFeatureFlag)
-> (CardanoFeatureFlag -> CardanoFeatureFlag -> CardanoFeatureFlag)
-> Ord CardanoFeatureFlag
CardanoFeatureFlag -> CardanoFeatureFlag -> Bool
CardanoFeatureFlag -> CardanoFeatureFlag -> Ordering
CardanoFeatureFlag -> CardanoFeatureFlag -> CardanoFeatureFlag
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 :: CardanoFeatureFlag -> CardanoFeatureFlag -> Ordering
compare :: CardanoFeatureFlag -> CardanoFeatureFlag -> Ordering
$c< :: CardanoFeatureFlag -> CardanoFeatureFlag -> Bool
< :: CardanoFeatureFlag -> CardanoFeatureFlag -> Bool
$c<= :: CardanoFeatureFlag -> CardanoFeatureFlag -> Bool
<= :: CardanoFeatureFlag -> CardanoFeatureFlag -> Bool
$c> :: CardanoFeatureFlag -> CardanoFeatureFlag -> Bool
> :: CardanoFeatureFlag -> CardanoFeatureFlag -> Bool
$c>= :: CardanoFeatureFlag -> CardanoFeatureFlag -> Bool
>= :: CardanoFeatureFlag -> CardanoFeatureFlag -> Bool
$cmax :: CardanoFeatureFlag -> CardanoFeatureFlag -> CardanoFeatureFlag
max :: CardanoFeatureFlag -> CardanoFeatureFlag -> CardanoFeatureFlag
$cmin :: CardanoFeatureFlag -> CardanoFeatureFlag -> CardanoFeatureFlag
min :: CardanoFeatureFlag -> CardanoFeatureFlag -> CardanoFeatureFlag
Ord, Int -> CardanoFeatureFlag
CardanoFeatureFlag -> Int
CardanoFeatureFlag -> [CardanoFeatureFlag]
CardanoFeatureFlag -> CardanoFeatureFlag
CardanoFeatureFlag -> CardanoFeatureFlag -> [CardanoFeatureFlag]
CardanoFeatureFlag
-> CardanoFeatureFlag -> CardanoFeatureFlag -> [CardanoFeatureFlag]
(CardanoFeatureFlag -> CardanoFeatureFlag)
-> (CardanoFeatureFlag -> CardanoFeatureFlag)
-> (Int -> CardanoFeatureFlag)
-> (CardanoFeatureFlag -> Int)
-> (CardanoFeatureFlag -> [CardanoFeatureFlag])
-> (CardanoFeatureFlag
    -> CardanoFeatureFlag -> [CardanoFeatureFlag])
-> (CardanoFeatureFlag
    -> CardanoFeatureFlag -> [CardanoFeatureFlag])
-> (CardanoFeatureFlag
    -> CardanoFeatureFlag
    -> CardanoFeatureFlag
    -> [CardanoFeatureFlag])
-> Enum CardanoFeatureFlag
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 :: CardanoFeatureFlag -> CardanoFeatureFlag
succ :: CardanoFeatureFlag -> CardanoFeatureFlag
$cpred :: CardanoFeatureFlag -> CardanoFeatureFlag
pred :: CardanoFeatureFlag -> CardanoFeatureFlag
$ctoEnum :: Int -> CardanoFeatureFlag
toEnum :: Int -> CardanoFeatureFlag
$cfromEnum :: CardanoFeatureFlag -> Int
fromEnum :: CardanoFeatureFlag -> Int
$cenumFrom :: CardanoFeatureFlag -> [CardanoFeatureFlag]
enumFrom :: CardanoFeatureFlag -> [CardanoFeatureFlag]
$cenumFromThen :: CardanoFeatureFlag -> CardanoFeatureFlag -> [CardanoFeatureFlag]
enumFromThen :: CardanoFeatureFlag -> CardanoFeatureFlag -> [CardanoFeatureFlag]
$cenumFromTo :: CardanoFeatureFlag -> CardanoFeatureFlag -> [CardanoFeatureFlag]
enumFromTo :: CardanoFeatureFlag -> CardanoFeatureFlag -> [CardanoFeatureFlag]
$cenumFromThenTo :: CardanoFeatureFlag
-> CardanoFeatureFlag -> CardanoFeatureFlag -> [CardanoFeatureFlag]
enumFromThenTo :: CardanoFeatureFlag
-> CardanoFeatureFlag -> CardanoFeatureFlag -> [CardanoFeatureFlag]
Enum, CardanoFeatureFlag
CardanoFeatureFlag
-> CardanoFeatureFlag -> Bounded CardanoFeatureFlag
forall a. a -> a -> Bounded a
$cminBound :: CardanoFeatureFlag
minBound :: CardanoFeatureFlag
$cmaxBound :: CardanoFeatureFlag
maxBound :: CardanoFeatureFlag
Bounded, (forall x. CardanoFeatureFlag -> Rep CardanoFeatureFlag x)
-> (forall x. Rep CardanoFeatureFlag x -> CardanoFeatureFlag)
-> Generic CardanoFeatureFlag
forall x. Rep CardanoFeatureFlag x -> CardanoFeatureFlag
forall x. CardanoFeatureFlag -> Rep CardanoFeatureFlag x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. CardanoFeatureFlag -> Rep CardanoFeatureFlag x
from :: forall x. CardanoFeatureFlag -> Rep CardanoFeatureFlag x
$cto :: forall x. Rep CardanoFeatureFlag x -> CardanoFeatureFlag
to :: forall x. Rep CardanoFeatureFlag x -> CardanoFeatureFlag
Generic)
  deriving anyclass (Context -> CardanoFeatureFlag -> IO (Maybe ThunkInfo)
Proxy CardanoFeatureFlag -> String
(Context -> CardanoFeatureFlag -> IO (Maybe ThunkInfo))
-> (Context -> CardanoFeatureFlag -> IO (Maybe ThunkInfo))
-> (Proxy CardanoFeatureFlag -> String)
-> NoThunks CardanoFeatureFlag
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: Context -> CardanoFeatureFlag -> IO (Maybe ThunkInfo)
noThunks :: Context -> CardanoFeatureFlag -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> CardanoFeatureFlag -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> CardanoFeatureFlag -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy CardanoFeatureFlag -> String
showTypeOf :: Proxy CardanoFeatureFlag -> String
NoThunks)

instance Aeson.FromJSON CardanoFeatureFlag where
  parseJSON :: Value -> Parser CardanoFeatureFlag
parseJSON = String
-> (Text -> Parser CardanoFeatureFlag)
-> Value
-> Parser CardanoFeatureFlag
forall a. String -> (Text -> Parser a) -> Value -> Parser a
Aeson.withText String
"CardanoFeatureFlag" ((Text -> Parser CardanoFeatureFlag)
 -> Value -> Parser CardanoFeatureFlag)
-> (Text -> Parser CardanoFeatureFlag)
-> Value
-> Parser CardanoFeatureFlag
forall a b. (a -> b) -> a -> b
$ \case
    Text
"Leios" -> CardanoFeatureFlag -> Parser CardanoFeatureFlag
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CardanoFeatureFlag
LeiosFlag
    Text
"Peras" -> CardanoFeatureFlag -> Parser CardanoFeatureFlag
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CardanoFeatureFlag
PerasFlag
    Text
"Phalanx" -> CardanoFeatureFlag -> Parser CardanoFeatureFlag
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CardanoFeatureFlag
PhalanxFlag
    Text
t -> String -> Parser CardanoFeatureFlag
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser CardanoFeatureFlag)
-> String -> Parser CardanoFeatureFlag
forall a b. (a -> b) -> a -> b
$ String
"Unknown flag: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Text -> String
forall a. Show a => a -> String
show Text
t

instance Aeson.ToJSON CardanoFeatureFlag where
  toJSON :: CardanoFeatureFlag -> Value
toJSON = \case
    CardanoFeatureFlag
LeiosFlag -> Value
"Leios"
    CardanoFeatureFlag
PerasFlag -> Value
"Peras"
    CardanoFeatureFlag
PhalanxFlag -> Value
"Phalanx"