{-# LANGUAGE TupleSections, OverloadedStrings #-} {-| Description: Additional functions that should probably be in @hnix@ Nix generation helpers. No guarantee of stability (internal!). -} module Nix.Expr.Additions ( stringKey, ($$=), dynamicKey, inheritStatic , simpleParamSet, multiParam , (!!.) , StrQ(..), mkStrQ, mkStrQI ) where import Data.Fix (Fix(..)) import Data.Text (Text) import Data.String (IsString(..)) import Nix.Expr import Text.Regex.TDFA.Text () import Text.Regex.TDFA ((=~)) -- hnix helpers -- TODO submit upstream -- | Make a binding, but have the key be a string, not symbol. stringKey :: Text -> NExpr -> Binding NExpr stringKey k v = NamedVar (pure $ dynamicKey k) v nullPos -- | Infix version of 'stringKey'. ($$=) :: Text -> NExpr -> Binding NExpr ($$=) = stringKey infixr 2 $$= -- | Make a dynamic key name that is only enclosed in double quotes (no antiquotes). dynamicKey :: Text -> NKeyName NExpr dynamicKey k = DynamicKey $ Plain $ DoubleQuoted [Plain k] -- | Inherit the given list of symbols. inheritStatic :: [Text] -> Binding e inheritStatic names = inherit (map StaticKey names) nullPos -- | shortcut to create a list of closed params, like @{ foo, bar, baz }:@ simpleParamSet :: [Text] -> Params NExpr simpleParamSet prms = mkParamset (fmap (, Nothing) prms) False -- | shortcut to create a list of multiple params, like @a: b: c:@ multiParam :: [Text] -> NExpr -> NExpr multiParam ps expr = foldr mkFunction expr $ map Param ps -- TODO: switch over to !. when -- https://github.com/jwiegley/hnix/commit/8b4c137a3b125f52bb78039a9d201492032b38e8 -- goes upstream -- | Like '!.', but automatically convert plain strings to static keys. (!!.) :: NExpr -> Text -> NExpr aset !!. k = Fix $ NSelect aset (pure $ (if isPlainSymbol k then StaticKey else dynamicKey) k) Nothing where -- the nix lexer regex for IDs (symbols) is -- [a-zA-Z\_][a-zA-Z0-9\_\'\-]* isPlainSymbol :: Text -> Bool isPlainSymbol s = s =~ ("^[a-zA-Z_][a-zA-Z0-9_'-]*$" :: Text) infixl 8 !!. -- | String quotation, either a plain string (S) or antiquoted (A) data StrQ = StrQ !Text | AntiQ !NExpr instance IsString StrQ where fromString = StrQ . fromString -- mkStrQtmpl :: ([Antiquoted Text NExpr] -> NString NExpr) -> [StrQ] -> NExpr mkStrQtmpl strtr = Fix . NStr . strtr . map trans where trans (StrQ t) = Plain t trans (AntiQ r) = Antiquoted r mkStrQ, mkStrQI :: [StrQ] -> NExpr -- | Create a double-quoted string from a list of antiquotes/plain strings. mkStrQ = mkStrQtmpl DoubleQuoted -- | Create a single-quoted string from a list of antiquotes/plain strings. mkStrQI = mkStrQtmpl (Indented 2)