hnix/src/Nix/String.hs

117 lines
4.2 KiB
Haskell
Raw Normal View History

2018-05-13 20:13:30 +02:00
{-# LANGUAGE DeriveGeneric #-}
2018-11-17 22:08:02 +01:00
{-# LANGUAGE OverloadedStrings #-}
2018-09-16 22:30:24 +02:00
{-# OPTIONS_GHC -Wno-unused-top-binds #-}
module Nix.String (
NixString
2018-11-17 22:08:02 +01:00
, principledMempty
, StringContext(..)
, ContextFlavor(..)
, stringHasContext
2018-11-17 22:08:02 +01:00
, principledIntercalateNixString
, hackyStringIgnoreContextMaybe
, hackyStringIgnoreContext
, hackyMakeNixStringWithoutContext
2018-11-17 22:08:02 +01:00
, principledMakeNixStringWithoutContext
, principledMakeNixStringWithSingletonContext
2018-11-17 22:23:41 +01:00
, principledModifyNixContents
2018-11-17 19:29:34 +01:00
, principledStringMappend
, principledStringMConcat
2018-05-13 20:13:30 +02:00
) where
import qualified Data.HashSet as S
import Data.Hashable
import Data.Text (Text)
2018-11-17 22:08:02 +01:00
import qualified Data.Text as Text
2018-05-13 20:13:30 +02:00
import GHC.Generics
import Data.Semigroup
2018-11-17 22:23:41 +01:00
-- {-# WARNING hackyStringIgnoreContextMaybe, hackyStringIgnoreContext, hackyMakeNixStringWithoutContext "This NixString function needs to be replaced" #-}
2018-05-13 20:13:30 +02:00
-- | A 'ContextFlavor' describes the sum of possible derivations for string contexts
2018-11-17 22:08:02 +01:00
data ContextFlavor =
2018-05-13 20:13:30 +02:00
DirectPath
| DerivationOutput !Text
deriving (Show, Eq, Ord, Generic)
instance Hashable ContextFlavor
-- | A 'StringContext' ...
2018-11-17 22:08:02 +01:00
data StringContext =
2018-05-13 20:13:30 +02:00
StringContext { scPath :: !Text
, scFlavor :: !ContextFlavor
2018-11-17 22:08:02 +01:00
} deriving (Eq, Ord, Show, Generic)
2018-05-13 20:13:30 +02:00
instance Hashable StringContext
2018-11-17 22:08:02 +01:00
data NixString = NixString
2018-05-13 20:13:30 +02:00
{ nsContents :: !Text
, nsContext :: !(S.HashSet StringContext)
2018-11-17 22:08:02 +01:00
} deriving (Eq, Ord, Show, Generic)
2018-05-13 20:13:30 +02:00
instance Hashable NixString
2018-11-17 22:08:02 +01:00
-- | Combine two NixStrings using mappend
principledMempty :: NixString
principledMempty = NixString "" mempty
2018-11-17 19:04:08 +01:00
-- | Combine two NixStrings using mappend
principledStringMappend :: NixString -> NixString -> NixString
principledStringMappend (NixString s1 t1) (NixString s2 t2) = NixString (s1 <> s2) (t1 <> t2)
-- | Combine two NixStrings using mappend
hackyStringMappend :: NixString -> NixString -> NixString
hackyStringMappend (NixString s1 t1) (NixString s2 t2) = NixString (s1 <> s2) (t1 <> t2)
2018-05-13 20:13:30 +02:00
2018-11-17 22:08:02 +01:00
-- | Combine NixStrings with a separator
principledIntercalateNixString :: NixString -> [NixString] -> NixString
principledIntercalateNixString _ [] = principledMempty
principledIntercalateNixString _ [ns] = ns
principledIntercalateNixString sep nss = NixString contents ctx
where
contents = Text.intercalate (nsContents sep) (map nsContents nss)
ctx = S.unions (nsContext sep : map nsContext nss)
-- | Combine NixStrings using mconcat
hackyStringMConcat :: [NixString] -> NixString
2018-11-17 22:08:02 +01:00
hackyStringMConcat = foldr hackyStringMappend (NixString mempty mempty)
-- | Combine NixStrings using mconcat
principledStringMConcat :: [NixString] -> NixString
2018-11-17 19:39:08 +01:00
principledStringMConcat = foldr principledStringMappend (NixString mempty mempty)
--instance Semigroup NixString where
--NixString s1 t1 <> NixString s2 t2 = NixString (s1 <> s2) (t1 <> t2)
--instance Monoid NixString where
-- mempty = NixString mempty mempty
-- mappend = (<>)
2018-05-13 20:13:30 +02:00
2018-11-17 22:08:02 +01:00
-- | Extract the string contents from a NixString that has no context
hackyStringIgnoreContextMaybe :: NixString -> Maybe Text
hackyStringIgnoreContextMaybe (NixString s c) | null c = Just s
2018-11-17 22:08:02 +01:00
| otherwise = Nothing
2018-05-13 20:13:30 +02:00
2018-11-17 22:08:02 +01:00
-- | Extract the string contents from a NixString even if the NixString has an associated context
hackyStringIgnoreContext :: NixString -> Text
hackyStringIgnoreContext (NixString s _) = s
2018-05-13 20:13:30 +02:00
-- | Returns True if the NixString has an associated context
stringHasContext :: NixString -> Bool
stringHasContext (NixString _ c) = not (null c)
2018-05-13 20:13:30 +02:00
-- | Constructs a NixString without a context
hackyMakeNixStringWithoutContext :: Text -> NixString
2018-11-17 22:08:02 +01:00
hackyMakeNixStringWithoutContext = flip NixString mempty
-- | Constructs a NixString without a context
principledMakeNixStringWithoutContext :: Text -> NixString
principledMakeNixStringWithoutContext = flip NixString mempty
2018-05-13 20:13:30 +02:00
-- | Modify the string part of the NixString -- ignores the context
2018-11-17 22:23:41 +01:00
principledModifyNixContents :: (Text -> Text) -> NixString -> NixString
principledModifyNixContents f (NixString s c) = NixString (f s) c
2018-05-13 20:13:30 +02:00
2018-11-17 22:08:02 +01:00
-- | Create a NixString using a singleton context
principledMakeNixStringWithSingletonContext :: Text -> StringContext -> NixString
principledMakeNixStringWithSingletonContext s c = NixString s (S.singleton c)