forked from haskell/haskell-language-server
/
FeatureSet.hs
94 lines (69 loc) · 2.49 KB
/
FeatureSet.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}
module Ide.Plugin.Tactic.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
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