{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# OPTIONS_GHC -Wno-deprecations #-}

module Cardano.Api.Feature
  ( Featured (..)
  , mkFeatured
  , unFeatured
  , asFeaturedInEra
  , asFeaturedInShelleyBasedEra
  )
where

import           Cardano.Api.Eon.ShelleyBasedEra
import           Cardano.Api.Eras.Core

-- | A value only if the eon includes era
data Featured eon era a where
  Featured
    :: eon era
    -- ^ The witness that the eon includes era
    -> a
    -- ^ The value to use
    -> Featured eon era a

deriving instance (Eq a, Eq (eon era)) => Eq (Featured eon era a)

deriving instance (Show a, Show (eon era)) => Show (Featured eon era a)

instance Functor (Featured eon era) where
  fmap :: forall a b. (a -> b) -> Featured eon era a -> Featured eon era b
fmap a -> b
f (Featured eon era
eon a
a) = eon era -> b -> Featured eon era b
forall (eon :: * -> *) era a. eon era -> a -> Featured eon era a
Featured eon era
eon (a -> b
f a
a)

-- | Create a Featured with automatic witness conjuring
mkFeatured
  :: forall eon era a
   . IsCardanoEra era
  => Eon eon
  => a
  -- ^ a value featured in eon
  -> Maybe (Featured eon era a)
  -- ^ 'Just' if era is in eon
mkFeatured :: forall (eon :: * -> *) era a.
(IsCardanoEra era, Eon eon) =>
a -> Maybe (Featured eon era a)
mkFeatured a
a = a -> CardanoEra era -> Maybe (Featured eon era a)
forall (eon :: * -> *) a era.
Eon eon =>
a -> CardanoEra era -> Maybe (Featured eon era a)
asFeaturedInEra a
a CardanoEra era
forall era. IsCardanoEra era => CardanoEra era
cardanoEra

unFeatured :: Featured eon era a -> a
unFeatured :: forall (eon :: * -> *) era a. Featured eon era a -> a
unFeatured (Featured eon era
_ a
a) = a
a

-- | Attempt to construct a 'FeatureValue' from a value and era.
-- If the eon is not supported in the era, then 'NoFeatureValue' is returned.
asFeaturedInEra
  :: ()
  => Eon eon
  => a
  -> CardanoEra era
  -> Maybe (Featured eon era a)
asFeaturedInEra :: forall (eon :: * -> *) a era.
Eon eon =>
a -> CardanoEra era -> Maybe (Featured eon era a)
asFeaturedInEra a
value = Maybe (Featured eon era a)
-> (eon era -> Maybe (Featured eon era a))
-> CardanoEra era
-> Maybe (Featured eon era a)
forall a era. a -> (eon era -> a) -> CardanoEra era -> a
forall (eon :: * -> *) a era.
Eon eon =>
a -> (eon era -> a) -> CardanoEra era -> a
inEonForEra Maybe (Featured eon era a)
forall a. Maybe a
Nothing (Featured eon era a -> Maybe (Featured eon era a)
forall a. a -> Maybe a
Just (Featured eon era a -> Maybe (Featured eon era a))
-> (eon era -> Featured eon era a)
-> eon era
-> Maybe (Featured eon era a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (eon era -> a -> Featured eon era a)
-> a -> eon era -> Featured eon era a
forall a b c. (a -> b -> c) -> b -> a -> c
flip eon era -> a -> Featured eon era a
forall (eon :: * -> *) era a. eon era -> a -> Featured eon era a
Featured a
value)

-- | Attempt to construct a 'FeatureValue' from a value and a shelley-based-era.
asFeaturedInShelleyBasedEra
  :: ()
  => Eon eon
  => a
  -> ShelleyBasedEra era
  -> Maybe (Featured eon era a)
asFeaturedInShelleyBasedEra :: forall (eon :: * -> *) a era.
Eon eon =>
a -> ShelleyBasedEra era -> Maybe (Featured eon era a)
asFeaturedInShelleyBasedEra a
value = a -> CardanoEra era -> Maybe (Featured eon era a)
forall (eon :: * -> *) a era.
Eon eon =>
a -> CardanoEra era -> Maybe (Featured eon era a)
asFeaturedInEra a
value (CardanoEra era -> Maybe (Featured eon era a))
-> (ShelleyBasedEra era -> CardanoEra era)
-> ShelleyBasedEra era
-> Maybe (Featured eon era a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShelleyBasedEra era -> CardanoEra era
forall era. ShelleyBasedEra era -> CardanoEra era
forall (eon :: * -> *) era.
ToCardanoEra eon =>
eon era -> CardanoEra era
toCardanoEra