Skip to content

Commit f81cd78

Browse files
committed
Nix/String: organization
Structuring, sorting things arround.
1 parent ba09cdd commit f81cd78

File tree

1 file changed

+107
-78
lines changed

1 file changed

+107
-78
lines changed

src/Nix/String.hs

Lines changed: 107 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,10 @@ import Data.Text ( Text )
4343
import qualified Data.Text as Text
4444
import GHC.Generics
4545

46-
-- | A 'ContextFlavor' describes the sum of possible derivations for string contexts
47-
data ContextFlavor =
48-
DirectPath
49-
| AllOutputs
50-
| DerivationOutput !Text
51-
deriving (Show, Eq, Ord, Generic)
5246

53-
instance Hashable ContextFlavor
47+
-- * Types
48+
49+
-- ** Context
5450

5551
-- | A 'StringContext' ...
5652
data StringContext =
@@ -60,18 +56,14 @@ data StringContext =
6056

6157
instance Hashable StringContext
6258

63-
data NixString = NixString
64-
{ nsContents :: !Text
65-
, nsContext :: !(S.HashSet StringContext)
66-
} deriving (Eq, Ord, Show, Generic)
67-
68-
instance Semigroup NixString where
69-
NixString s1 t1 <> NixString s2 t2 = NixString (s1 <> s2) (t1 <> t2)
70-
71-
instance Monoid NixString where
72-
mempty = NixString mempty mempty
59+
-- | A 'ContextFlavor' describes the sum of possible derivations for string contexts
60+
data ContextFlavor =
61+
DirectPath
62+
| AllOutputs
63+
| DerivationOutput !Text
64+
deriving (Show, Eq, Ord, Generic)
7365

74-
instance Hashable NixString
66+
instance Hashable ContextFlavor
7567

7668
newtype NixLikeContext = NixLikeContext
7769
{ getNixLikeContext :: M.HashMap Text NixLikeContextValue
@@ -93,44 +85,65 @@ instance Semigroup NixLikeContextValue where
9385
instance Monoid NixLikeContextValue where
9486
mempty = NixLikeContextValue False False []
9587

96-
toStringContexts :: (Text, NixLikeContextValue) -> [StringContext]
97-
toStringContexts (path, nlcv) = case nlcv of
98-
NixLikeContextValue True _ _ -> StringContext path DirectPath
99-
: toStringContexts (path, nlcv { nlcvPath = False })
100-
NixLikeContextValue _ True _ -> StringContext path AllOutputs
101-
: toStringContexts (path, nlcv { nlcvAllOutputs = False })
102-
NixLikeContextValue _ _ ls | not (null ls) ->
103-
map (StringContext path . DerivationOutput) ls
104-
_ -> []
10588

106-
toNixLikeContextValue :: StringContext -> (Text, NixLikeContextValue)
107-
toNixLikeContextValue sc = (,) (scPath sc) $ case scFlavor sc of
108-
DirectPath -> NixLikeContextValue True False []
109-
AllOutputs -> NixLikeContextValue False True []
110-
DerivationOutput t -> NixLikeContextValue False False [t]
89+
-- ** StringContext accumulator
11190

112-
toNixLikeContext :: S.HashSet StringContext -> NixLikeContext
113-
toNixLikeContext stringContext = NixLikeContext
114-
$ S.foldr go mempty stringContext
115-
where
116-
go sc hm =
117-
let (t, nlcv) = toNixLikeContextValue sc in M.insertWith (<>) t nlcv hm
91+
-- | A monad for accumulating string context while producing a result string.
92+
newtype WithStringContextT m a = WithStringContextT (WriterT (S.HashSet StringContext) m a)
93+
deriving (Functor, Applicative, Monad, MonadTrans, MonadWriter (S.HashSet StringContext))
94+
95+
type WithStringContext = WithStringContextT Identity
96+
97+
98+
-- ** NixString
99+
100+
data NixString = NixString
101+
{ nsContents :: !Text
102+
, nsContext :: !(S.HashSet StringContext)
103+
} deriving (Eq, Ord, Show, Generic)
104+
105+
instance Semigroup NixString where
106+
NixString s1 t1 <> NixString s2 t2 = NixString (s1 <> s2) (t1 <> t2)
107+
108+
instance Monoid NixString where
109+
mempty = NixString mempty mempty
110+
111+
instance Hashable NixString
112+
113+
114+
-- * Functions
115+
116+
-- ** Makers
117+
118+
-- | Constructs NixString without a context
119+
makeNixStringWithoutContext :: Text -> NixString
120+
makeNixStringWithoutContext = flip NixString mempty
121+
122+
-- | Create NixString using a singleton context
123+
makeNixStringWithSingletonContext
124+
:: Text -> StringContext -> NixString
125+
makeNixStringWithSingletonContext s c = NixString s (S.singleton c)
126+
127+
-- | Create NixString from a Text and context
128+
makeNixString :: Text -> S.HashSet StringContext -> NixString
129+
makeNixString = NixString
130+
131+
132+
-- ** Checkers
133+
134+
-- | Returns True if the NixString has an associated context
135+
stringHasContext :: NixString -> Bool
136+
stringHasContext (NixString _ c) = not (null c)
118137

119-
fromNixLikeContext :: NixLikeContext -> S.HashSet StringContext
120-
fromNixLikeContext =
121-
S.fromList . join . map toStringContexts . M.toList . getNixLikeContext
138+
139+
-- ** Getters
122140

123141
getContext :: NixString -> S.HashSet StringContext
124142
getContext = nsContext
125143

126-
-- | Combine NixStrings with a separator
127-
intercalateNixString :: NixString -> [NixString] -> NixString
128-
intercalateNixString _ [] = mempty
129-
intercalateNixString _ [ns] = ns
130-
intercalateNixString sep nss = NixString contents ctx
131-
where
132-
contents = Text.intercalate (nsContents sep) (map nsContents nss)
133-
ctx = S.unions (nsContext sep : map nsContext nss)
144+
fromNixLikeContext :: NixLikeContext -> S.HashSet StringContext
145+
fromNixLikeContext =
146+
S.fromList . join . map toStringContexts . M.toList . getNixLikeContext
134147

135148
-- | Extract the string contents from a NixString that has no context
136149
getStringNoContext :: NixString -> Maybe Text
@@ -141,32 +154,35 @@ getStringNoContext (NixString s c) | null c = Just s
141154
stringIgnoreContext :: NixString -> Text
142155
stringIgnoreContext (NixString s _) = s
143156

144-
-- | Returns True if the NixString has an associated context
145-
stringHasContext :: NixString -> Bool
146-
stringHasContext (NixString _ c) = not (null c)
147-
148-
-- | Constructs a NixString without a context
149-
makeNixStringWithoutContext :: Text -> NixString
150-
makeNixStringWithoutContext = flip NixString mempty
157+
-- | Get the contents of a 'NixString' and write its context into the resulting set.
158+
extractNixString :: Monad m => NixString -> WithStringContextT m Text
159+
extractNixString (NixString s c) = WithStringContextT $ tell c >> pure s
151160

152-
-- | Modify the string part of the NixString, leaving the context unchanged
153-
modifyNixContents :: (Text -> Text) -> NixString -> NixString
154-
modifyNixContents f (NixString s c) = NixString (f s) c
155161

156-
-- | Create a NixString using a singleton context
157-
makeNixStringWithSingletonContext
158-
:: Text -> StringContext -> NixString
159-
makeNixStringWithSingletonContext s c = NixString s (S.singleton c)
162+
-- ** Setters
160163

161-
-- | Create a NixString from a Text and context
162-
makeNixString :: Text -> S.HashSet StringContext -> NixString
163-
makeNixString = NixString
164+
toStringContexts :: (Text, NixLikeContextValue) -> [StringContext]
165+
toStringContexts (path, nlcv) = case nlcv of
166+
NixLikeContextValue True _ _ -> StringContext path DirectPath
167+
: toStringContexts (path, nlcv { nlcvPath = False })
168+
NixLikeContextValue _ True _ -> StringContext path AllOutputs
169+
: toStringContexts (path, nlcv { nlcvAllOutputs = False })
170+
NixLikeContextValue _ _ ls | not (null ls) ->
171+
map (StringContext path . DerivationOutput) ls
172+
_ -> []
164173

165-
-- | A monad for accumulating string context while producing a result string.
166-
newtype WithStringContextT m a = WithStringContextT (WriterT (S.HashSet StringContext) m a)
167-
deriving (Functor, Applicative, Monad, MonadTrans, MonadWriter (S.HashSet StringContext))
174+
toNixLikeContextValue :: StringContext -> (Text, NixLikeContextValue)
175+
toNixLikeContextValue sc = (,) (scPath sc) $ case scFlavor sc of
176+
DirectPath -> NixLikeContextValue True False []
177+
AllOutputs -> NixLikeContextValue False True []
178+
DerivationOutput t -> NixLikeContextValue False False [t]
168179

169-
type WithStringContext = WithStringContextT Identity
180+
toNixLikeContext :: S.HashSet StringContext -> NixLikeContext
181+
toNixLikeContext stringContext = NixLikeContext
182+
$ S.foldr go mempty stringContext
183+
where
184+
go sc hm =
185+
let (t, nlcv) = toNixLikeContextValue sc in M.insertWith (<>) t nlcv hm
170186

171187
-- | Add 'StringContext's into the resulting set.
172188
addStringContext
@@ -177,29 +193,42 @@ addStringContext = WithStringContextT . tell
177193
addSingletonStringContext :: Monad m => StringContext -> WithStringContextT m ()
178194
addSingletonStringContext = WithStringContextT . tell . S.singleton
179195

180-
-- | Get the contents of a 'NixString' and write its context into the resulting set.
181-
extractNixString :: Monad m => NixString -> WithStringContextT m Text
182-
extractNixString (NixString s c) = WithStringContextT $ tell c >> pure s
183-
184196
-- | Run an action producing a string with a context and put those into a 'NixString'.
185197
runWithStringContextT :: Monad m => WithStringContextT m Text -> m NixString
186198
runWithStringContextT (WithStringContextT m) =
187199
uncurry NixString <$> runWriterT m
188200

201+
-- | Run an action producing a string with a context and put those into a 'NixString'.
202+
runWithStringContext :: WithStringContextT Identity Text -> NixString
203+
runWithStringContext = runIdentity . runWithStringContextT
204+
205+
206+
-- ** Modifiers
207+
208+
-- | Modify the string part of the NixString, leaving the context unchanged
209+
modifyNixContents :: (Text -> Text) -> NixString -> NixString
210+
modifyNixContents f (NixString s c) = NixString (f s) c
211+
189212
-- | Run an action that manipulates nix strings, and collect the contexts encountered.
190213
-- Warning: this may be unsafe, depending on how you handle the resulting context list.
191214
runWithStringContextT' :: Monad m => WithStringContextT m a -> m (a, S.HashSet StringContext)
192215
runWithStringContextT' (WithStringContextT m) = runWriterT m
193216

194-
-- | Run an action producing a string with a context and put those into a 'NixString'.
195-
runWithStringContext :: WithStringContextT Identity Text -> NixString
196-
runWithStringContext = runIdentity . runWithStringContextT
197-
198217
-- | Run an action that manipulates nix strings, and collect the contexts encountered.
199218
-- Warning: this may be unsafe, depending on how you handle the resulting context list.
200219
runWithStringContext' :: WithStringContextT Identity a -> (a, S.HashSet StringContext)
201220
runWithStringContext' = runIdentity . runWithStringContextT'
202221

222+
-- | Combine NixStrings with a separator
223+
intercalateNixString :: NixString -> [NixString] -> NixString
224+
intercalateNixString _ [] = mempty
225+
intercalateNixString _ [ns] = ns
226+
intercalateNixString sep nss = NixString contents ctx
227+
where
228+
contents = Text.intercalate (nsContents sep) (map nsContents nss)
229+
ctx = S.unions (nsContext sep : map nsContext nss)
230+
231+
203232
-- * Deprecated API
204233

205234
-- {-# WARNING hackyGetStringNoContext, hackyStringIgnoreContext, hackyMakeNixStringWithoutContext "This NixString function needs to be replaced" #-}

0 commit comments

Comments
 (0)