1
- {-# LANGUAGE DeriveGeneric #-}
2
1
{-# LANGUAGE DeriveDataTypeable #-}
3
- module Distribution.Solver.Types.OptionalStanza
4
- ( OptionalStanza (.. )
5
- , showStanza
6
- , enableStanzas
7
- ) where
2
+ {-# LANGUAGE DeriveGeneric #-}
3
+ module Distribution.Solver.Types.OptionalStanza (
4
+ -- * OptionalStanza
5
+ OptionalStanza (.. ),
6
+ showStanza ,
7
+ showStanzas ,
8
+ enableStanzas ,
9
+ -- * Set of stanzas
10
+ OptionalStanzaSet ,
11
+ optStanzaSetFromList ,
12
+ optStanzaSetToList ,
13
+ optStanzaSetMember ,
14
+ optStanzaSetInsert ,
15
+ optStanzaSetSingleton ,
16
+ optStanzaSetIntersection ,
17
+ optStanzaSetNull ,
18
+ optStanzaSetIsSubset ,
19
+ -- * Map indexed by stanzas
20
+ OptionalStanzaMap ,
21
+ optStanzaTabulate ,
22
+ optStanzaIndex ,
23
+ optStanzaLookup ,
24
+ optStanzaKeysFilteredByValue ,
25
+ ) where
8
26
9
27
import Distribution.Solver.Compat.Prelude
10
28
import Prelude ()
11
- import Distribution.Types.ComponentRequestedSpec
12
- (ComponentRequestedSpec (.. ))
29
+
30
+ import Data.Bits (testBit , (.|.) , (.&.) )
31
+ import Distribution.Types.ComponentRequestedSpec (ComponentRequestedSpec (.. ))
32
+ import Distribution.Utils.Structured (Structured (.. ), nominalStructure )
33
+
34
+ -------------------------------------------------------------------------------
35
+ -- OptionalStanza
36
+ -------------------------------------------------------------------------------
13
37
14
38
data OptionalStanza
15
39
= TestStanzas
@@ -21,16 +45,94 @@ showStanza :: OptionalStanza -> String
21
45
showStanza TestStanzas = " test"
22
46
showStanza BenchStanzas = " bench"
23
47
24
- -- | Convert a list of 'OptionalStanza' into the corresponding
25
- -- 'ComponentRequestedSpec' which records what components are enabled.
48
+ showStanzas :: OptionalStanzaSet -> String
49
+ showStanzas = unwords . map (( " * " ++ ) . showStanza) . optStanzaSetToList
26
50
27
- -- Note: [OptionalStanza] could become PerOptionalStanza Bool.
28
- -- See https://github.com/haskell/cabal/issues/6918
29
- enableStanzas :: [OptionalStanza ] -> ComponentRequestedSpec
30
- enableStanzas optionalStanzas = ComponentRequestedSpec {
31
- testsRequested = any (== TestStanzas ) optionalStanzas
32
- , benchmarksRequested = any (== BenchStanzas ) optionalStanzas
33
- }
51
+ -- | Convert a list of 'OptionalStanza' into the corresponding
52
+ -- Cabal's 'ComponentRequestedSpec' which records what components are enabled.
53
+ --
54
+ enableStanzas :: OptionalStanzaSet -> ComponentRequestedSpec
55
+ enableStanzas optionalStanzas = ComponentRequestedSpec
56
+ { testsRequested = optStanzaSetMember TestStanzas optionalStanzas
57
+ , benchmarksRequested = optStanzaSetMember BenchStanzas optionalStanzas
58
+ }
34
59
35
60
instance Binary OptionalStanza
36
61
instance Structured OptionalStanza
62
+
63
+ -------------------------------------------------------------------------------
64
+ -- OptionalStanzaSet
65
+ -------------------------------------------------------------------------------
66
+
67
+ newtype OptionalStanzaSet = OptionalStanzaSet Word
68
+ deriving (Eq , Ord , Show )
69
+
70
+ instance Binary OptionalStanzaSet where
71
+ put (OptionalStanzaSet w) = put w
72
+ get = fmap (OptionalStanzaSet . (.&. 0x03 )) get
73
+
74
+ instance Structured OptionalStanzaSet where
75
+ structure = nominalStructure
76
+
77
+ optStanzaSetFromList :: [OptionalStanza ] -> OptionalStanzaSet
78
+ optStanzaSetFromList = foldl' (flip optStanzaSetInsert) mempty
79
+
80
+ optStanzaSetToList :: OptionalStanzaSet -> [OptionalStanza ]
81
+ optStanzaSetToList (OptionalStanzaSet 0 ) = []
82
+ optStanzaSetToList (OptionalStanzaSet 1 ) = [TestStanzas ]
83
+ optStanzaSetToList (OptionalStanzaSet 2 ) = [BenchStanzas ]
84
+ optStanzaSetToList (OptionalStanzaSet 3 ) = [TestStanzas , BenchStanzas ]
85
+ optStanzaSetToList (OptionalStanzaSet _) = []
86
+
87
+ optStanzaSetInsert :: OptionalStanza -> OptionalStanzaSet -> OptionalStanzaSet
88
+ optStanzaSetInsert x s = optStanzaSetSingleton x <> s
89
+
90
+ optStanzaSetMember :: OptionalStanza -> OptionalStanzaSet -> Bool
91
+ optStanzaSetMember TestStanzas (OptionalStanzaSet w) = testBit w 0
92
+ optStanzaSetMember BenchStanzas (OptionalStanzaSet w) = testBit w 1
93
+
94
+ optStanzaSetSingleton :: OptionalStanza -> OptionalStanzaSet
95
+ optStanzaSetSingleton TestStanzas = OptionalStanzaSet 1
96
+ optStanzaSetSingleton BenchStanzas = OptionalStanzaSet 2
97
+
98
+ optStanzaSetIntersection :: OptionalStanzaSet -> OptionalStanzaSet -> OptionalStanzaSet
99
+ optStanzaSetIntersection (OptionalStanzaSet a) (OptionalStanzaSet b) = OptionalStanzaSet (a .&. b)
100
+
101
+ optStanzaSetNull :: OptionalStanzaSet -> Bool
102
+ optStanzaSetNull (OptionalStanzaSet w) = w == 0
103
+
104
+ optStanzaSetIsSubset :: OptionalStanzaSet -> OptionalStanzaSet -> Bool
105
+ optStanzaSetIsSubset (OptionalStanzaSet a) (OptionalStanzaSet b) = (a .|. b) == b
106
+
107
+ instance Semigroup OptionalStanzaSet where
108
+ OptionalStanzaSet a <> OptionalStanzaSet b = OptionalStanzaSet (a .|. b)
109
+
110
+ instance Monoid OptionalStanzaSet where
111
+ mempty = OptionalStanzaSet 0
112
+ mappend = (<>)
113
+
114
+ -------------------------------------------------------------------------------
115
+ -- OptionalStanzaMap
116
+ -------------------------------------------------------------------------------
117
+
118
+ -- | Note: this is total map.
119
+ data OptionalStanzaMap a = OptionalStanzaMap a a
120
+ deriving (Eq , Ord , Show , Generic )
121
+
122
+ instance Binary a => Binary (OptionalStanzaMap a )
123
+ instance Structured a => Structured (OptionalStanzaMap a )
124
+
125
+ optStanzaTabulate :: (OptionalStanza -> a ) -> OptionalStanzaMap a
126
+ optStanzaTabulate f = OptionalStanzaMap (f TestStanzas ) (f BenchStanzas )
127
+
128
+ optStanzaIndex :: OptionalStanzaMap a -> OptionalStanza -> a
129
+ optStanzaIndex (OptionalStanzaMap x _) TestStanzas = x
130
+ optStanzaIndex (OptionalStanzaMap _ x) BenchStanzas = x
131
+
132
+ optStanzaLookup :: OptionalStanza -> OptionalStanzaMap a -> a
133
+ optStanzaLookup = flip optStanzaIndex
134
+
135
+ optStanzaKeysFilteredByValue :: (a -> Bool ) -> OptionalStanzaMap a -> OptionalStanzaSet
136
+ optStanzaKeysFilteredByValue p (OptionalStanzaMap x y)
137
+ | p x = if p y then OptionalStanzaSet 3 else OptionalStanzaSet 1
138
+ | otherwise = if p y then OptionalStanzaSet 2 else OptionalStanzaSet 0
0 commit comments