module Control.FeatureFlag where
import Control.Monad
import Data.Text (Text)
data FeatureToggle a = Enabled | Disabled
deriving (Read, Show, Eq)
data FeatureProvider a = FeatureProvider
{ enabledProvider :: a
, enabledProviderName :: Text
, availableProviders :: [(Text, a)]
, defaultProvider :: a
}
enable :: FeatureToggle a -> FeatureToggle a
enable = const Enabled
disable :: FeatureToggle a -> FeatureToggle a
disable = const Disabled
toggle :: FeatureToggle a -> FeatureToggle a
toggle t = case t of
Enabled -> Disabled
Disabled -> Enabled
withToggle :: FeatureToggle a
-> b
-> b
-> b
withToggle t x y = case t of
Enabled -> x
Disabled -> y
whenEnabled :: (Functor m, Monad m) => FeatureToggle a -> m b -> m ()
whenEnabled t m = case t of
Enabled -> void m
_ -> return ()
whenDisabled :: (Functor m, Monad m) => FeatureToggle a -> m b -> m ()
whenDisabled t m = case t of
Disabled -> void m
_ -> return ()
use :: Text -> FeatureProvider a -> Either (FeatureProvider a) (FeatureProvider a)
use name p = if name == "default"
then Right useDefault
else case lookup name $ availableProviders p of
Nothing -> Left useDefault
Just ep -> Right $ p { enabledProvider = ep, enabledProviderName = name }
where useDefault = p { enabledProvider = defaultProvider p, enabledProviderName = "default" }
withProvider :: FeatureProvider a -> (a -> b) -> b
withProvider p f = f $ enabledProvider p