packages feed

hls-tactics-plugin-1.1.0.0: src/Wingman/FeatureSet.hs

{-# LANGUAGE OverloadedStrings #-}

module Wingman.FeatureSet
  ( Feature (..)
  , FeatureSet
  , hasFeature
  , defaultFeatures
  , allFeatures
  , parseFeatureSet
  , prettyFeatureSet
  ) where

import           Data.List  (intercalate)
import           Data.Maybe (listToMaybe, mapMaybe)
import           Data.Set   (Set)
import qualified Data.Set   as S
import qualified Data.Text  as T


------------------------------------------------------------------------------
-- | All the available features. A 'FeatureSet' describes the ones currently
-- available to the user.
data Feature
  = FeatureDestructAll
  | FeatureUseDataCon
  | FeatureRefineHole
  | FeatureKnownMonoid
  deriving (Eq, Ord, Show, Read, Enum, Bounded)


------------------------------------------------------------------------------
-- | A collection of enabled features.
type FeatureSet = Set Feature


------------------------------------------------------------------------------
-- | Parse a feature set.
parseFeatureSet :: T.Text -> FeatureSet
parseFeatureSet
  = mappend defaultFeatures
  . S.fromList
  . mapMaybe (readMaybe . mappend featurePrefix . rot13 . T.unpack)
  . T.split (== '/')


------------------------------------------------------------------------------
-- | Features that are globally enabled for all users.
defaultFeatures :: FeatureSet
defaultFeatures = S.fromList
  [
  ]


------------------------------------------------------------------------------
-- | All available features.
allFeatures :: FeatureSet
allFeatures = S.fromList $ enumFromTo minBound maxBound


------------------------------------------------------------------------------
-- | Pretty print a feature set.
prettyFeatureSet :: FeatureSet -> String
prettyFeatureSet
  = intercalate "/"
  . fmap (rot13 . drop (length featurePrefix) . show)
  . S.toList


------------------------------------------------------------------------------
-- | Is a given 'Feature' currently enabled?
hasFeature :: Feature -> FeatureSet -> Bool
hasFeature = S.member


------------------------------------------------------------------------------
-- | Like 'read', but not partial.
readMaybe :: Read a => String -> Maybe a
readMaybe = fmap fst . listToMaybe . reads


featurePrefix :: String
featurePrefix = "Feature"


rot13 :: String -> String
rot13 = fmap (toEnum . rot13int . fromEnum)


rot13int :: Integral a => a -> a
rot13int x
  | (fromIntegral x :: Word) - 97 < 26 = 97 + rem (x - 84) 26
  | (fromIntegral x :: Word) - 65 < 26 = 65 + rem (x - 52) 26
  | otherwise   = x