feature-flipper-0.1.0.0: src/Control/Flipper.hs
{-|
Module : Flipper
Description : Main user interface for the Flipper library
-}
module Control.Flipper
( enabled
, enable
, disable
, toggle
, whenEnabled
, module Control.Flipper.Types
) where
import Control.Monad (void, when)
import qualified Data.Map.Strict as M
import Control.Flipper.Types (FeatureName(..), Features(..),
HasFeatureFlags(..), ModifiesFeatureFlags(..), mkFeatures)
{- |
The 'whenEnabled' function calls the supplied function, 'm ()', when the given
'FeatureName' is enabled.
When the feature specified by 'FeatureName' is disabled, 'm ()' is not
evaluated.
-}
whenEnabled :: (HasFeatureFlags m)
=> FeatureName -> m () -> m ()
whenEnabled fName f = do
isEnabled <- enabled fName
when isEnabled f
{- |
The 'enabled' function returns a Bool indicating if the queried feature is
active.
When the queried FeatureName exists, the active state is returned.
When the queried FeatureName does not exists, 'enabled' returns False.
-}
enabled :: HasFeatureFlags m
=> FeatureName -> m Bool
enabled fName = do
features <- unFeatures <$> getFeatures
if M.lookup fName features == Just True
then return True
else return False
{- |
The 'enable' function activates a feature.
When the FeatureName exists in the store, it is set to active.
When the FeatureName does not exist, it is created and set to active.
-}
enable :: ModifiesFeatureFlags m
=> FeatureName -> m ()
enable fName = update fName (\_ -> Just True)
{- |
The 'disable' function deactivates a feature.
When the FeatureName exists in the store, it is set to inactive.
When the FeatureName does not exist, it is created and set to inactive.
-}
disable :: ModifiesFeatureFlags m
=> FeatureName -> m ()
disable fName = update fName (\_ -> Just False)
{- |
The 'toggle' function flips the current state of a feature.
When the FeatureName exists in the store, it flips the feature state.
When the FeatureName does not exist, it is created and set to True.
-}
toggle :: ModifiesFeatureFlags m
=> FeatureName -> m ()
toggle fName = update fName flipIt'
where
flipIt' :: Maybe Bool -> Maybe Bool
flipIt' (Just a) = Just (not a)
flipIt' Nothing = Just True
update :: ModifiesFeatureFlags m
=> FeatureName -> (Maybe Bool -> Maybe Bool) -> m ()
update fName updateFn = do
features <- unFeatures <$> getFeatures
void . updateFeatures . Features $ M.alter updateFn fName features