{-# LANGUAGE CPP #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MonoLocalBinds #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE PackageImports #-}
{-# LANGUAGE PartialTypeSignatures #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ViewPatterns #-}

{-# OPTIONS_GHC -fno-warn-name-shadowing #-}

-- | Code that implements Nix builtins. Lists the functions that are built into the Nix expression evaluator. Some built-ins (aka `derivation`), are always in the scope, so they can be accessed by the name. To keap the namespace clean, most built-ins are inside the `builtins` scope - a set that contains all what is a built-in.
module Nix.Builtins
  ( withNixContext
  , builtins
  )
where


import           Prelude                 hiding ( traceM )
import           Relude.Unsafe                 as Unsafe
import           Nix.Utils
import           Control.Comonad                ( Comonad )
import           Control.Monad                  ( foldM )
import           Control.Monad.Catch            ( MonadCatch(catch) )
import           Control.Monad.ListM            ( sortByM )
import           Crypto.Hash
import qualified Crypto.Hash.MD5               as MD5
import qualified Crypto.Hash.SHA1              as SHA1
import qualified Crypto.Hash.SHA256            as SHA256
import qualified Crypto.Hash.SHA512            as SHA512
import qualified Data.Aeson                    as A
import           Data.Align                     ( alignWith )
import           Data.Array
import           Data.Bits
import qualified Data.ByteString               as B
import           Data.ByteString.Base16        as Base16
import           Data.Char                      ( isDigit )
import           Data.Foldable                  ( foldrM )
import           Data.Fix                       ( foldFix )
import           Data.List                      ( partition )
import qualified Data.HashMap.Lazy             as M
import           Data.Scientific
import qualified Data.Set                      as S
import qualified Data.Text                     as Text
import qualified Data.Text.Lazy                as LazyText
import qualified Data.Text.Lazy.Builder        as Builder
import           Data.These                     ( fromThese )
import qualified Data.Time.Clock.POSIX         as Time
import qualified Data.Vector                   as V
import           NeatInterpolation              ( text )
import           Nix.Atoms
import           Nix.Convert
import           Nix.Effects
import           Nix.Effects.Basic              ( fetchTarball )
import           Nix.Exec
import           Nix.Expr.Types
import           Nix.Expr.Types.Annotated
import qualified Nix.Eval                      as Eval
import           Nix.Frames
import           Nix.Json
import           Nix.Normal
import           Nix.Options
import           Nix.Parser
import           Nix.Render
import           Nix.Scope
import           Nix.String
import           Nix.String.Coerce
import           Nix.Value
import           Nix.Value.Equal
import           Nix.Value.Monad
import           Nix.XML
import           System.Nix.Base32             as Base32
import           System.FilePath
import           System.Posix.Files             ( isRegularFile
                                                , isDirectory
                                                , isSymbolicLink
                                                )
import           Text.Regex.TDFA


-- This is a big module. There is recursive reuse:
-- @builtins -> builtinsList -> scopedImport -> withNixContext -> builtins@,
-- since @builtins@ is self-recursive: aka we ship @builtins.builtins.builtins...@.

-- * Internal

-- ** Nix Builtins Haskell type level

newtype Prim m a = Prim { Prim m a -> m a
runPrim :: m a }

data BuiltinType = Normal | TopLevel
data Builtin v =
  Builtin
    { Builtin v -> BuiltinType
_kind   :: BuiltinType
    , Builtin v -> (Text, v)
mapping :: (Text, v)
    }

-- *** @class ToBuiltin@ and its instances

-- | Types that support conversion to nix in a particular monad
class ToBuiltin t f m a | a -> m where
  toBuiltin :: Text -> a -> m (NValue t f m)

instance
  ( MonadNix e t f m
  , ToValue a m (NValue t f m)
  )
  => ToBuiltin t f m (Prim m a) where
  toBuiltin :: Text -> Prim m a -> m (NValue t f m)
toBuiltin Text
_ Prim m a
p = a -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (a -> m (NValue t f m)) -> m a -> m (NValue t f m)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Prim m a -> m a
forall (m :: * -> *) a. Prim m a -> m a
runPrim Prim m a
p

instance
  ( MonadNix e t f m
  , FromValue a m (Deeper (NValue t f m))
  , ToBuiltin t f m b
  )
  => ToBuiltin t f m (a -> b) where
  toBuiltin :: Text -> (a -> b) -> m (NValue t f m)
toBuiltin Text
name a -> b
f =
    NValue t f m -> m (NValue t f m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NValue t f m -> m (NValue t f m))
-> NValue t f m -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ Text -> (NValue t f m -> m (NValue t f m)) -> NValue t f m
forall (f :: * -> *) (m :: * -> *) t.
(Applicative f, Functor m) =>
Text -> (NValue t f m -> m (NValue t f m)) -> NValue t f m
nvBuiltin Text
name (Text -> b -> m (NValue t f m)
forall t (f :: * -> *) (m :: * -> *) a.
ToBuiltin t f m a =>
Text -> a -> m (NValue t f m)
toBuiltin Text
name (b -> m (NValue t f m)) -> (a -> b) -> a -> m (NValue t f m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f (a -> m (NValue t f m))
-> (NValue t f m -> m a) -> NValue t f m -> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Deeper (NValue t f m) -> m a
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue (Deeper (NValue t f m) -> m a)
-> (NValue t f m -> Deeper (NValue t f m)) -> NValue t f m -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NValue t f m -> Deeper (NValue t f m)
forall a. a -> Deeper a
Deeper)

-- *** @WValue@ closure wrapper to have @Ord@

-- We wrap values solely to provide an Ord instance for genericClosure
newtype WValue t f m = WValue (NValue t f m)

instance Comonad f => Eq (WValue t f m) where
  WValue (NVConstant (NFloat Float
x)) == :: WValue t f m -> WValue t f m -> Bool
== WValue (NVConstant (NInt Integer
y)) =
    Float
x Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Integer -> Float
forall a. Num a => Integer -> a
fromInteger Integer
y
  WValue (NVConstant (NInt   Integer
x)) == WValue (NVConstant (NFloat Float
y)) =
    Integer -> Float
forall a. Num a => Integer -> a
fromInteger Integer
x Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
y
  WValue (NVConstant (NInt   Integer
x)) == WValue (NVConstant (NInt   Integer
y)) = Integer
x Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
y
  WValue (NVConstant (NFloat Float
x)) == WValue (NVConstant (NFloat Float
y)) = Float
x Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
y
  WValue (NVPath     FilePath
x         ) == WValue (NVPath     FilePath
y         ) = FilePath
x FilePath -> FilePath -> Bool
forall a. Eq a => a -> a -> Bool
== FilePath
y
  WValue (NVStr NixString
x) == WValue (NVStr NixString
y) =
    NixString -> Text
stringIgnoreContext NixString
x Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== NixString -> Text
stringIgnoreContext NixString
y
  WValue t f m
_ == WValue t f m
_ = Bool
False

instance Comonad f => Ord (WValue t f m) where
  WValue (NVConstant (NFloat Float
x)) <= :: WValue t f m -> WValue t f m -> Bool
<= WValue (NVConstant (NInt Integer
y)) =
    Float
x Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer -> Float
forall a. Num a => Integer -> a
fromInteger Integer
y
  WValue (NVConstant (NInt   Integer
x)) <= WValue (NVConstant (NFloat Float
y)) =
    Integer -> Float
forall a. Num a => Integer -> a
fromInteger Integer
x Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
<= Float
y
  WValue (NVConstant (NInt   Integer
x)) <= WValue (NVConstant (NInt   Integer
y)) = Integer
x Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer
y
  WValue (NVConstant (NFloat Float
x)) <= WValue (NVConstant (NFloat Float
y)) = Float
x Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
<= Float
y
  WValue (NVPath     FilePath
x         ) <= WValue (NVPath     FilePath
y         ) = FilePath
x FilePath -> FilePath -> Bool
forall a. Ord a => a -> a -> Bool
<= FilePath
y
  WValue (NVStr NixString
x) <= WValue (NVStr NixString
y) =
    NixString -> Text
stringIgnoreContext NixString
x Text -> Text -> Bool
forall a. Ord a => a -> a -> Bool
<= NixString -> Text
stringIgnoreContext NixString
y
  WValue t f m
_ <= WValue t f m
_ = Bool
False

-- ** Helpers

nVNull
  :: MonadNix e t f m
  => NValue t f m
nVNull :: NValue t f m
nVNull = NAtom -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
NAtom -> NValue t f m
nvConstant NAtom
NNull

mkNVBool
  :: MonadNix e t f m
  => Bool
  -> NValue t f m
mkNVBool :: Bool -> NValue t f m
mkNVBool = NAtom -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
NAtom -> NValue t f m
nvConstant (NAtom -> NValue t f m) -> (Bool -> NAtom) -> Bool -> NValue t f m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> NAtom
NBool

foldNixPath
  :: forall e t f m r
   . MonadNix e t f m
  => r
  -> (FilePath -> Maybe Text -> NixPathEntryType -> r -> m r)
  -> m r
foldNixPath :: r
-> (FilePath -> Maybe Text -> NixPathEntryType -> r -> m r) -> m r
foldNixPath r
z FilePath -> Maybe Text -> NixPathEntryType -> r -> m r
f =
  do
    Maybe (NValue t f m)
mres <- Text -> m (Maybe (NValue t f m))
forall a (m :: * -> *). Scoped a m => Text -> m (Maybe a)
lookupVar Text
"__includes"
    [NixString]
dirs <-
      m [NixString]
-> (NValue t f m -> m [NixString])
-> Maybe (NValue t f m)
-> m [NixString]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
        m [NixString]
forall (f :: * -> *) a. (Applicative f, Monoid a) => f a
stub
        ((Deeper (NValue t f m) -> m [NixString]
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue (Deeper (NValue t f m) -> m [NixString])
-> (NValue t f m -> Deeper (NValue t f m))
-> NValue t f m
-> m [NixString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NValue t f m -> Deeper (NValue t f m)
forall a. a -> Deeper a
Deeper) (NValue t f m -> m [NixString])
-> (NValue t f m -> m (NValue t f m))
-> NValue t f m
-> m [NixString]
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand)
        Maybe (NValue t f m)
mres
    Maybe Text
mPath    <- Text -> m (Maybe Text)
forall (m :: * -> *). MonadEnv m => Text -> m (Maybe Text)
getEnvVar Text
"NIX_PATH"
    Maybe Text
mDataDir <- Text -> m (Maybe Text)
forall (m :: * -> *). MonadEnv m => Text -> m (Maybe Text)
getEnvVar Text
"NIX_DATA_DIR"
    FilePath
dataDir  <-
      m FilePath -> (Text -> m FilePath) -> Maybe Text -> m FilePath
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
        m FilePath
forall (m :: * -> *). MonadPaths m => m FilePath
getDataDir
        (FilePath -> m FilePath
forall (f :: * -> *) a. Applicative f => a -> f a
pure (FilePath -> m FilePath)
-> (Text -> FilePath) -> Text -> m FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> FilePath
forall a. ToString a => a -> FilePath
toString)
        Maybe Text
mDataDir

    ((Text, NixPathEntryType) -> r -> m r)
-> r -> [(Text, NixPathEntryType)] -> m r
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> b -> m b) -> b -> t a -> m b
foldrM
      (Text, NixPathEntryType) -> r -> m r
go
      r
z
      ([(Text, NixPathEntryType)] -> m r)
-> [(Text, NixPathEntryType)] -> m r
forall a b. (a -> b) -> a -> b
$ (Text -> (Text, NixPathEntryType)
fromInclude (Text -> (Text, NixPathEntryType))
-> (NixString -> Text) -> NixString -> (Text, NixPathEntryType)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NixString -> Text
stringIgnoreContext (NixString -> (Text, NixPathEntryType))
-> [NixString] -> [(Text, NixPathEntryType)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [NixString]
dirs)
        [(Text, NixPathEntryType)]
-> [(Text, NixPathEntryType)] -> [(Text, NixPathEntryType)]
forall a. Semigroup a => a -> a -> a
<> [(Text, NixPathEntryType)]
-> (Text -> [(Text, NixPathEntryType)])
-> Maybe Text
-> [(Text, NixPathEntryType)]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
            [(Text, NixPathEntryType)]
forall a. Monoid a => a
mempty
            Text -> [(Text, NixPathEntryType)]
uriAwareSplit
            Maybe Text
mPath
        [(Text, NixPathEntryType)]
-> [(Text, NixPathEntryType)] -> [(Text, NixPathEntryType)]
forall a. Semigroup a => a -> a -> a
<> [ Text -> (Text, NixPathEntryType)
fromInclude (Text -> (Text, NixPathEntryType))
-> Text -> (Text, NixPathEntryType)
forall a b. (a -> b) -> a -> b
$ Text
"nix=" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> FilePath -> Text
forall a. ToText a => a -> Text
toText FilePath
dataDir Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/nix/corepkgs" ]
 where

  fromInclude :: Text -> (Text, NixPathEntryType)
fromInclude Text
x = (Text
x, ) (NixPathEntryType -> (Text, NixPathEntryType))
-> NixPathEntryType -> (Text, NixPathEntryType)
forall a b. (a -> b) -> a -> b
$
    NixPathEntryType -> NixPathEntryType -> Bool -> NixPathEntryType
forall a. a -> a -> Bool -> a
bool
      NixPathEntryType
PathEntryPath
      NixPathEntryType
PathEntryURI
      (Text
"://" Text -> Text -> Bool
`Text.isInfixOf` Text
x)

  go :: (Text, NixPathEntryType) -> r -> m r
go (Text
x, NixPathEntryType
ty) r
rest =
    case Text -> Text -> [Text]
Text.splitOn Text
"=" Text
x of
      [Text
p] -> FilePath -> Maybe Text -> NixPathEntryType -> r -> m r
f (Text -> FilePath
forall a. ToString a => a -> FilePath
toString Text
p) Maybe Text
forall a. Monoid a => a
mempty NixPathEntryType
ty r
rest
      [Text
n, Text
p] -> FilePath -> Maybe Text -> NixPathEntryType -> r -> m r
f (Text -> FilePath
forall a. ToString a => a -> FilePath
toString Text
p) (Text -> Maybe Text
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
n) NixPathEntryType
ty r
rest
      [Text]
_ -> ErrorCall -> m r
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m r) -> ErrorCall -> m r
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"Unexpected entry in NIX_PATH: " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> Text -> FilePath
forall b a. (Show a, IsString b) => a -> b
show Text
x

attrsetGet :: MonadNix e t f m => Text -> AttrSet (NValue t f m) -> m (NValue t f m)
attrsetGet :: Text -> AttrSet (NValue t f m) -> m (NValue t f m)
attrsetGet Text
k AttrSet (NValue t f m)
s =
  m (NValue t f m)
-> (NValue t f m -> m (NValue t f m))
-> Maybe (NValue t f m)
-> m (NValue t f m)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
    (ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"Attribute '" FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> Text -> FilePath
forall a. ToString a => a -> FilePath
toString Text
k FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
"' required")
    NValue t f m -> m (NValue t f m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure
    (Text -> AttrSet (NValue t f m) -> Maybe (NValue t f m)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup Text
k AttrSet (NValue t f m)
s)

data VersionComponent
  = VersionComponentPre -- ^ The string "pre"
  | VersionComponentString Text -- ^ A string other than "pre"
  | VersionComponentNumber Integer -- ^ A number
  deriving (Int -> VersionComponent -> FilePath -> FilePath
[VersionComponent] -> FilePath -> FilePath
VersionComponent -> FilePath
(Int -> VersionComponent -> FilePath -> FilePath)
-> (VersionComponent -> FilePath)
-> ([VersionComponent] -> FilePath -> FilePath)
-> Show VersionComponent
forall a.
(Int -> a -> FilePath -> FilePath)
-> (a -> FilePath) -> ([a] -> FilePath -> FilePath) -> Show a
showList :: [VersionComponent] -> FilePath -> FilePath
$cshowList :: [VersionComponent] -> FilePath -> FilePath
show :: VersionComponent -> FilePath
$cshow :: VersionComponent -> FilePath
showsPrec :: Int -> VersionComponent -> FilePath -> FilePath
$cshowsPrec :: Int -> VersionComponent -> FilePath -> FilePath
Show, ReadPrec [VersionComponent]
ReadPrec VersionComponent
Int -> ReadS VersionComponent
ReadS [VersionComponent]
(Int -> ReadS VersionComponent)
-> ReadS [VersionComponent]
-> ReadPrec VersionComponent
-> ReadPrec [VersionComponent]
-> Read VersionComponent
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [VersionComponent]
$creadListPrec :: ReadPrec [VersionComponent]
readPrec :: ReadPrec VersionComponent
$creadPrec :: ReadPrec VersionComponent
readList :: ReadS [VersionComponent]
$creadList :: ReadS [VersionComponent]
readsPrec :: Int -> ReadS VersionComponent
$creadsPrec :: Int -> ReadS VersionComponent
Read, VersionComponent -> VersionComponent -> Bool
(VersionComponent -> VersionComponent -> Bool)
-> (VersionComponent -> VersionComponent -> Bool)
-> Eq VersionComponent
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: VersionComponent -> VersionComponent -> Bool
$c/= :: VersionComponent -> VersionComponent -> Bool
== :: VersionComponent -> VersionComponent -> Bool
$c== :: VersionComponent -> VersionComponent -> Bool
Eq, Eq VersionComponent
Eq VersionComponent
-> (VersionComponent -> VersionComponent -> Ordering)
-> (VersionComponent -> VersionComponent -> Bool)
-> (VersionComponent -> VersionComponent -> Bool)
-> (VersionComponent -> VersionComponent -> Bool)
-> (VersionComponent -> VersionComponent -> Bool)
-> (VersionComponent -> VersionComponent -> VersionComponent)
-> (VersionComponent -> VersionComponent -> VersionComponent)
-> Ord VersionComponent
VersionComponent -> VersionComponent -> Bool
VersionComponent -> VersionComponent -> Ordering
VersionComponent -> VersionComponent -> VersionComponent
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: VersionComponent -> VersionComponent -> VersionComponent
$cmin :: VersionComponent -> VersionComponent -> VersionComponent
max :: VersionComponent -> VersionComponent -> VersionComponent
$cmax :: VersionComponent -> VersionComponent -> VersionComponent
>= :: VersionComponent -> VersionComponent -> Bool
$c>= :: VersionComponent -> VersionComponent -> Bool
> :: VersionComponent -> VersionComponent -> Bool
$c> :: VersionComponent -> VersionComponent -> Bool
<= :: VersionComponent -> VersionComponent -> Bool
$c<= :: VersionComponent -> VersionComponent -> Bool
< :: VersionComponent -> VersionComponent -> Bool
$c< :: VersionComponent -> VersionComponent -> Bool
compare :: VersionComponent -> VersionComponent -> Ordering
$ccompare :: VersionComponent -> VersionComponent -> Ordering
$cp1Ord :: Eq VersionComponent
Ord)

versionComponentToString :: VersionComponent -> Text
versionComponentToString :: VersionComponent -> Text
versionComponentToString =
  \case
    VersionComponent
VersionComponentPre      -> Text
"pre"
    VersionComponentString Text
s -> Text
s
    VersionComponentNumber Integer
n -> Integer -> Text
forall b a. (Show a, IsString b) => a -> b
show Integer
n

-- | Based on https://github.com/NixOS/nix/blob/4ee4fda521137fed6af0446948b3877e0c5db803/src/libexpr/names.cc#L44
versionComponentSeparators :: String
versionComponentSeparators :: FilePath
versionComponentSeparators = FilePath
".-"

splitVersion :: Text -> [VersionComponent]
splitVersion :: Text -> [VersionComponent]
splitVersion Text
s =
  case Text -> Maybe (Char, Text)
Text.uncons Text
s of
    Maybe (Char, Text)
Nothing -> [VersionComponent]
forall a. Monoid a => a
mempty
    Just (Char
h, Text
t)

      | Char
h Char -> FilePath -> Bool
forall (f :: * -> *) a.
(Foldable f, DisallowElem f, Eq a) =>
a -> f a -> Bool
`elem` FilePath
versionComponentSeparators -> Text -> [VersionComponent]
splitVersion Text
t

      | Char -> Bool
isDigit Char
h ->
        let (Text
digits, Text
rest) = (Char -> Bool) -> Text -> (Text, Text)
Text.span Char -> Bool
isDigit Text
s
        in
        Integer -> VersionComponent
VersionComponentNumber
            (Integer -> Maybe Integer -> Integer
forall a. a -> Maybe a -> a
fromMaybe (Text -> Integer
forall a t. (HasCallStack, IsText t) => t -> a
error (Text -> Integer) -> Text -> Integer
forall a b. (a -> b) -> a -> b
$ Text
"splitVersion: couldn't parse " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
forall b a. (Show a, IsString b) => a -> b
show Text
digits) (Maybe Integer -> Integer) -> Maybe Integer -> Integer
forall a b. (a -> b) -> a -> b
$ FilePath -> Maybe Integer
forall a. Read a => FilePath -> Maybe a
readMaybe (FilePath -> Maybe Integer) -> FilePath -> Maybe Integer
forall a b. (a -> b) -> a -> b
$ Text -> FilePath
forall a. ToString a => a -> FilePath
toString Text
digits) VersionComponent -> [VersionComponent] -> [VersionComponent]
forall a. a -> [a] -> [a]
: Text -> [VersionComponent]
splitVersion Text
rest

      | Bool
otherwise ->
        let
          (Text
chars, Text
rest) =
            (Char -> Bool) -> Text -> (Text, Text)
Text.span
              (\Char
c -> Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Char -> Bool
isDigit Char
c Bool -> Bool -> Bool
|| Char
c Char -> FilePath -> Bool
forall (f :: * -> *) a.
(Foldable f, DisallowElem f, Eq a) =>
a -> f a -> Bool
`elem` FilePath
versionComponentSeparators)
              Text
s
          thisComponent :: VersionComponent
thisComponent =
            case Text
chars of
              Text
"pre" -> VersionComponent
VersionComponentPre
              Text
x     -> Text -> VersionComponent
VersionComponentString Text
x
        in
        VersionComponent
thisComponent VersionComponent -> [VersionComponent] -> [VersionComponent]
forall a. a -> [a] -> [a]
: Text -> [VersionComponent]
splitVersion Text
rest

compareVersions :: Text -> Text -> Ordering
compareVersions :: Text -> Text -> Ordering
compareVersions Text
s1 Text
s2 =
  [Ordering] -> Ordering
forall a. Monoid a => [a] -> a
mconcat ([Ordering] -> Ordering) -> [Ordering] -> Ordering
forall a b. (a -> b) -> a -> b
$
    (These VersionComponent VersionComponent -> Ordering)
-> [VersionComponent] -> [VersionComponent] -> [Ordering]
forall (f :: * -> *) a b c.
Semialign f =>
(These a b -> c) -> f a -> f b -> f c
alignWith
      These VersionComponent VersionComponent -> Ordering
f
      (Text -> [VersionComponent]
splitVersion Text
s1)
      (Text -> [VersionComponent]
splitVersion Text
s2)
 where
  z :: VersionComponent
z = Text -> VersionComponent
VersionComponentString Text
""
  f :: These VersionComponent VersionComponent -> Ordering
f = (VersionComponent -> VersionComponent -> Ordering)
-> (VersionComponent, VersionComponent) -> Ordering
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry VersionComponent -> VersionComponent -> Ordering
forall a. Ord a => a -> a -> Ordering
compare ((VersionComponent, VersionComponent) -> Ordering)
-> (These VersionComponent VersionComponent
    -> (VersionComponent, VersionComponent))
-> These VersionComponent VersionComponent
-> Ordering
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VersionComponent
-> VersionComponent
-> These VersionComponent VersionComponent
-> (VersionComponent, VersionComponent)
forall a b. a -> b -> These a b -> (a, b)
fromThese VersionComponent
z VersionComponent
z

splitDrvName :: Text -> (Text, Text)
splitDrvName :: Text -> (Text, Text)
splitDrvName Text
s =
  let
    sep :: Text
sep    = Text
"-"
    pieces :: [Text]
pieces = Text -> Text -> [Text]
Text.splitOn Text
sep Text
s
    isFirstVersionPiece :: Text -> Bool
isFirstVersionPiece Text
p =
      case Text -> Maybe (Char, Text)
Text.uncons Text
p of
        Just (Char
h, Text
_) -> Char -> Bool
isDigit Char
h
        Maybe (Char, Text)
_           -> Bool
False
    -- Like 'break', but always puts the first item into the first result
    -- list
    breakAfterFirstItem :: (a -> Bool) -> [a] -> ([a], [a])
    breakAfterFirstItem :: (a -> Bool) -> [a] -> ([a], [a])
breakAfterFirstItem a -> Bool
f =
      ([a], [a]) -> ([a] -> ([a], [a])) -> [a] -> ([a], [a])
forall (t :: * -> *) b a. Foldable t => b -> (t a -> b) -> t a -> b
list
        ([a]
forall a. Monoid a => a
mempty, [a]
forall a. Monoid a => a
mempty)
        (\ (a
h : [a]
t) -> let ([a]
a, [a]
b) = (a -> Bool) -> [a] -> ([a], [a])
forall a. (a -> Bool) -> [a] -> ([a], [a])
break a -> Bool
f [a]
t in (a
h a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
a, [a]
b))
    ([Text]
namePieces, [Text]
versionPieces) =
      (Text -> Bool) -> [Text] -> ([Text], [Text])
forall a. (a -> Bool) -> [a] -> ([a], [a])
breakAfterFirstItem Text -> Bool
isFirstVersionPiece [Text]
pieces
  in
  (Text -> [Text] -> Text
Text.intercalate Text
sep [Text]
namePieces, Text -> [Text] -> Text
Text.intercalate Text
sep [Text]
versionPieces)

splitMatches
  :: forall e t f m
   . MonadNix e t f m
  => Int
  -> [[(ByteString, (Int, Int))]]
  -> ByteString
  -> [NValue t f m]
splitMatches :: Int -> [[(ByteString, (Int, Int))]] -> ByteString -> [NValue t f m]
splitMatches Int
_ [] ByteString
haystack = [ByteString -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
ByteString -> NValue t f m
thunkStr ByteString
haystack]
splitMatches Int
_ ([] : [[(ByteString, (Int, Int))]]
_) ByteString
_ =
  FilePath -> [NValue t f m]
forall (m :: * -> *) a. MonadFail m => FilePath -> m a
fail FilePath
"Fail in splitMatches: this should never happen!"
splitMatches Int
numDropped (((ByteString
_, (Int
start, Int
len)) : [(ByteString, (Int, Int))]
captures) : [[(ByteString, (Int, Int))]]
mts) ByteString
haystack =
  ByteString -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
ByteString -> NValue t f m
thunkStr ByteString
before NValue t f m -> [NValue t f m] -> [NValue t f m]
forall a. a -> [a] -> [a]
: NValue t f m
caps NValue t f m -> [NValue t f m] -> [NValue t f m]
forall a. a -> [a] -> [a]
: Int -> [[(ByteString, (Int, Int))]] -> ByteString -> [NValue t f m]
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
Int -> [[(ByteString, (Int, Int))]] -> ByteString -> [NValue t f m]
splitMatches (Int
numDropped Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
relStart Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
len)
                                        [[(ByteString, (Int, Int))]]
mts
                                        (Int -> ByteString -> ByteString
B.drop Int
len ByteString
rest)
 where
  relStart :: Int
relStart       = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 Int
start Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
numDropped
  (ByteString
before, ByteString
rest) = Int -> ByteString -> (ByteString, ByteString)
B.splitAt Int
relStart ByteString
haystack
  caps :: NValue t f m
caps           = [NValue t f m] -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
[NValue t f m] -> NValue t f m
nvList ((ByteString, (Int, Int)) -> NValue t f m
forall t (f :: * -> *) (m :: * -> *) e a b.
(Scoped (NValue t f m) m, MonadReader e m, Has e Frames,
 Has e SrcSpan, Has e Options, MonadFix m, MonadCatch m,
 Alternative m, MonadEffects t f m, MonadThunk t m (NValue t f m),
 Comonad f, Traversable f, HasCitations m (NValue t f m) t,
 HasCitations1 m (NValue t f m) f, MonadValue (NValue t f m) m,
 Num a, Applicative f, Ord a, Show t, Typeable m, Typeable f,
 Typeable t) =>
(ByteString, (a, b)) -> NValue t f m
f ((ByteString, (Int, Int)) -> NValue t f m)
-> [(ByteString, (Int, Int))] -> [NValue t f m]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(ByteString, (Int, Int))]
captures)
  f :: (ByteString, (a, b)) -> NValue t f m
f (ByteString
a, (a
s, b
_))  =
    NValue t f m -> NValue t f m -> Bool -> NValue t f m
forall a. a -> a -> Bool -> a
bool
      NValue t f m
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m
nVNull
      (ByteString -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
ByteString -> NValue t f m
thunkStr ByteString
a)
      (a
s a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
0)

thunkStr :: Applicative f => ByteString -> NValue t f m
thunkStr :: ByteString -> NValue t f m
thunkStr ByteString
s = NixString -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
NixString -> NValue t f m
nvStr (NixString -> NValue t f m) -> NixString -> NValue t f m
forall a b. (a -> b) -> a -> b
$ Text -> NixString
makeNixStringWithoutContext (Text -> NixString) -> Text -> NixString
forall a b. (a -> b) -> a -> b
$ ByteString -> Text
forall a b. ConvertUtf8 a b => b -> a
decodeUtf8 ByteString
s

elemAt :: [a] -> Int -> Maybe a
elemAt :: [a] -> Int -> Maybe a
elemAt [a]
ls Int
i =
  Maybe a -> ([a] -> Maybe a) -> [a] -> Maybe a
forall (t :: * -> *) b a. Foldable t => b -> (t a -> b) -> t a -> b
list
    Maybe a
forall a. Maybe a
Nothing
    (a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> Maybe a) -> ([a] -> a) -> [a] -> Maybe a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> a
forall a. [a] -> a
Unsafe.head)
    (Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
drop Int
i [a]
ls)

hasKind
  :: forall a e t f m
   . (MonadNix e t f m, FromValue a m (NValue t f m))
  => NValue t f m
  -> m (NValue t f m)
hasKind :: NValue t f m -> m (NValue t f m)
hasKind NValue t f m
nv =
  do
    Maybe a
v <- NValue t f m -> m (Maybe a)
forall a (m :: * -> *) v. FromValue a m v => v -> m (Maybe a)
fromValueMay NValue t f m
nv

    Bool -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Bool -> m (NValue t f m)) -> Bool -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$
      case Maybe a
v of
        Just (a
_ :: a) -> Bool
True
        Maybe a
_             -> Bool
False


absolutePathFromValue :: MonadNix e t f m => NValue t f m -> m FilePath
absolutePathFromValue :: NValue t f m -> m FilePath
absolutePathFromValue =
  \case
    NVStr NixString
ns ->
      do
        let
          path :: FilePath
path = Text -> FilePath
forall a. ToString a => a -> FilePath
toString (Text -> FilePath) -> Text -> FilePath
forall a b. (a -> b) -> a -> b
$ NixString -> Text
stringIgnoreContext NixString
ns

        Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (FilePath -> Bool
isAbsolute FilePath
path) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ ErrorCall -> m ()
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m ()) -> ErrorCall -> m ()
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"string " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath -> FilePath
forall b a. (Show a, IsString b) => a -> b
show FilePath
path FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
" doesn't represent an absolute path"
        pure FilePath
path

    NVPath FilePath
path -> FilePath -> m FilePath
forall (f :: * -> *) a. Applicative f => a -> f a
pure FilePath
path
    NValue t f m
v           -> ErrorCall -> m FilePath
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m FilePath) -> ErrorCall -> m FilePath
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"expected a path, got " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> NValue t f m -> FilePath
forall b a. (Show a, IsString b) => a -> b
show NValue t f m
v


data FileType
  = FileTypeRegular
  | FileTypeDirectory
  | FileTypeSymlink
  | FileTypeUnknown
  deriving (Int -> FileType -> FilePath -> FilePath
[FileType] -> FilePath -> FilePath
FileType -> FilePath
(Int -> FileType -> FilePath -> FilePath)
-> (FileType -> FilePath)
-> ([FileType] -> FilePath -> FilePath)
-> Show FileType
forall a.
(Int -> a -> FilePath -> FilePath)
-> (a -> FilePath) -> ([a] -> FilePath -> FilePath) -> Show a
showList :: [FileType] -> FilePath -> FilePath
$cshowList :: [FileType] -> FilePath -> FilePath
show :: FileType -> FilePath
$cshow :: FileType -> FilePath
showsPrec :: Int -> FileType -> FilePath -> FilePath
$cshowsPrec :: Int -> FileType -> FilePath -> FilePath
Show, ReadPrec [FileType]
ReadPrec FileType
Int -> ReadS FileType
ReadS [FileType]
(Int -> ReadS FileType)
-> ReadS [FileType]
-> ReadPrec FileType
-> ReadPrec [FileType]
-> Read FileType
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [FileType]
$creadListPrec :: ReadPrec [FileType]
readPrec :: ReadPrec FileType
$creadPrec :: ReadPrec FileType
readList :: ReadS [FileType]
$creadList :: ReadS [FileType]
readsPrec :: Int -> ReadS FileType
$creadsPrec :: Int -> ReadS FileType
Read, FileType -> FileType -> Bool
(FileType -> FileType -> Bool)
-> (FileType -> FileType -> Bool) -> Eq FileType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FileType -> FileType -> Bool
$c/= :: FileType -> FileType -> Bool
== :: FileType -> FileType -> Bool
$c== :: FileType -> FileType -> Bool
Eq, Eq FileType
Eq FileType
-> (FileType -> FileType -> Ordering)
-> (FileType -> FileType -> Bool)
-> (FileType -> FileType -> Bool)
-> (FileType -> FileType -> Bool)
-> (FileType -> FileType -> Bool)
-> (FileType -> FileType -> FileType)
-> (FileType -> FileType -> FileType)
-> Ord FileType
FileType -> FileType -> Bool
FileType -> FileType -> Ordering
FileType -> FileType -> FileType
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: FileType -> FileType -> FileType
$cmin :: FileType -> FileType -> FileType
max :: FileType -> FileType -> FileType
$cmax :: FileType -> FileType -> FileType
>= :: FileType -> FileType -> Bool
$c>= :: FileType -> FileType -> Bool
> :: FileType -> FileType -> Bool
$c> :: FileType -> FileType -> Bool
<= :: FileType -> FileType -> Bool
$c<= :: FileType -> FileType -> Bool
< :: FileType -> FileType -> Bool
$c< :: FileType -> FileType -> Bool
compare :: FileType -> FileType -> Ordering
$ccompare :: FileType -> FileType -> Ordering
$cp1Ord :: Eq FileType
Ord)

instance Convertible e t f m => ToValue FileType m (NValue t f m) where
  toValue :: FileType -> m (NValue t f m)
toValue =
    NixString -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (NixString -> m (NValue t f m))
-> (FileType -> NixString) -> FileType -> m (NValue t f m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> NixString
makeNixStringWithoutContext (Text -> NixString) -> (FileType -> Text) -> FileType -> NixString
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
      \case
        FileType
FileTypeRegular   -> Text
"regular" :: Text
        FileType
FileTypeDirectory -> Text
"directory"
        FileType
FileTypeSymlink   -> Text
"symlink"
        FileType
FileTypeUnknown   -> Text
"unknown"

-- ** Builtin functions

derivationNix
  :: forall e t f m. (MonadNix e t f m, Scoped (NValue t f m) m)
  => m (NValue t f m)
derivationNix :: m (NValue t f m)
derivationNix = (NExprF (m (NValue t f m)) -> m (NValue t f m))
-> Fix NExprF -> m (NValue t f m)
forall (f :: * -> *) a. Functor f => (f a -> a) -> Fix f -> a
foldFix NExprF (m (NValue t f m)) -> m (NValue t f m)
forall v (m :: * -> *). MonadNixEval v m => NExprF (m v) -> m v
Eval.eval $$(do
    -- This is compiled in so that we only parse it once at compile-time.
    let Right expr = parseNixText [text|
      drvAttrs @ { outputs ? [ "out" ], ... }:

      let

        strict = derivationStrict drvAttrs;

        commonAttrs = drvAttrs
          // (builtins.listToAttrs outputsList)
          // { all = map (x: x.value) outputsList;
               inherit drvAttrs;
             };

        outputToAttrListElement = outputName:
          { name = outputName;
            value = commonAttrs // {
              outPath = builtins.getAttr outputName strict;
              drvPath = strict.drvPath;
              type = "derivation";
              inherit outputName;
            };
          };

        outputsList = map outputToAttrListElement outputs;

      in (builtins.head outputsList).value|]
    [|| expr ||]
  )

nixPathNix :: MonadNix e t f m => m (NValue t f m)
nixPathNix :: m (NValue t f m)
nixPathNix =
  ([NValue t f m] -> NValue t f m)
-> m [NValue t f m] -> m (NValue t f m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
    [NValue t f m] -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
[NValue t f m] -> NValue t f m
nvList
    ([NValue t f m]
-> (FilePath
    -> Maybe Text
    -> NixPathEntryType
    -> [NValue t f m]
    -> m [NValue t f m])
-> m [NValue t f m]
forall e t (f :: * -> *) (m :: * -> *) r.
MonadNix e t f m =>
r
-> (FilePath -> Maybe Text -> NixPathEntryType -> r -> m r) -> m r
foldNixPath [NValue t f m]
forall a. Monoid a => a
mempty ((FilePath
  -> Maybe Text
  -> NixPathEntryType
  -> [NValue t f m]
  -> m [NValue t f m])
 -> m [NValue t f m])
-> (FilePath
    -> Maybe Text
    -> NixPathEntryType
    -> [NValue t f m]
    -> m [NValue t f m])
-> m [NValue t f m]
forall a b. (a -> b) -> a -> b
$
      \FilePath
p Maybe Text
mn NixPathEntryType
ty [NValue t f m]
rest ->
        [NValue t f m] -> m [NValue t f m]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([NValue t f m] -> m [NValue t f m])
-> [NValue t f m] -> m [NValue t f m]
forall a b. (a -> b) -> a -> b
$
          NValue t f m -> [NValue t f m]
forall (f :: * -> *) a. Applicative f => a -> f a
pure
            (HashMap Text SourcePos
-> HashMap Text (NValue t f m) -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
HashMap Text SourcePos
-> HashMap Text (NValue t f m) -> NValue t f m
nvSet
              HashMap Text SourcePos
forall a. Monoid a => a
mempty
              ([(Text, NValue t f m)] -> HashMap Text (NValue t f m)
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
M.fromList
                [case NixPathEntryType
ty of
                  NixPathEntryType
PathEntryPath -> (Text
"path", FilePath -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
FilePath -> NValue t f m
nvPath FilePath
p)
                  NixPathEntryType
PathEntryURI  -> ( Text
"uri", FilePath -> NValue t f m
forall t (m :: * -> *). FilePath -> NValue t f m
mkNvStr FilePath
p)

                , ( Text
"prefix", FilePath -> NValue t f m
forall t (m :: * -> *). FilePath -> NValue t f m
mkNvStr (FilePath -> NValue t f m) -> FilePath -> NValue t f m
forall a b. (a -> b) -> a -> b
$ Text -> FilePath
forall a. ToString a => a -> FilePath
toString (Text -> FilePath) -> Text -> FilePath
forall a b. (a -> b) -> a -> b
$ Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe Text
"" Maybe Text
mn)
                ]
              )
            )
          [NValue t f m] -> [NValue t f m] -> [NValue t f m]
forall a. Semigroup a => a -> a -> a
<> [NValue t f m]
rest
    )
 where
  mkNvStr :: FilePath -> NValue t f m
mkNvStr = NixString -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
NixString -> NValue t f m
nvStr (NixString -> NValue t f m)
-> (FilePath -> NixString) -> FilePath -> NValue t f m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> NixString
makeNixStringWithoutContext (Text -> NixString) -> (FilePath -> Text) -> FilePath -> NixString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> Text
forall a. ToText a => a -> Text
toText

toStringNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
toStringNix :: NValue t f m -> m (NValue t f m)
toStringNix = NixString -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (NixString -> m (NValue t f m))
-> (NValue t f m -> m NixString)
-> NValue t f m
-> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< (NValue t f m -> NValue t f m -> m (NValue t f m))
-> CopyToStoreMode -> CoercionLevel -> NValue t f m -> m NixString
forall e (m :: * -> *) t (f :: * -> *).
(Framed e m, MonadStore m, MonadThrow m,
 MonadDataErrorContext t f m, MonadValue (NValue t f m) m) =>
(NValue t f m -> NValue t f m -> m (NValue t f m))
-> CopyToStoreMode -> CoercionLevel -> NValue t f m -> m NixString
coerceToString NValue t f m -> NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> NValue t f m -> m (NValue t f m)
callFunc CopyToStoreMode
DontCopyToStore CoercionLevel
CoerceAny

hasAttrNix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
hasAttrNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
hasAttrNix NValue t f m
x NValue t f m
y =
  do
    Text
key <- NixString -> m Text
forall e (m :: * -> *). Framed e m => NixString -> m Text
fromStringNoContext (NixString -> m Text) -> m NixString -> m Text
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m NixString
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
x
    (AttrSet (NValue t f m)
aset, HashMap Text SourcePos
_) <- NValue t f m -> m (AttrSet (NValue t f m), HashMap Text SourcePos)
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @(AttrSet (NValue t f m), AttrSet SourcePos) NValue t f m
y

    Bool -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Bool -> m (NValue t f m)) -> Bool -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ Text -> AttrSet (NValue t f m) -> Bool
forall k a. (Eq k, Hashable k) => k -> HashMap k a -> Bool
M.member Text
key AttrSet (NValue t f m)
aset

hasContextNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
hasContextNix :: NValue t f m -> m (NValue t f m)
hasContextNix = Bool -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Bool -> m (NValue t f m))
-> (NixString -> Bool) -> NixString -> m (NValue t f m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NixString -> Bool
stringHasContext (NixString -> m (NValue t f m))
-> (NValue t f m -> m NixString)
-> NValue t f m
-> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> m NixString
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue

getAttrNix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
getAttrNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
getAttrNix NValue t f m
x NValue t f m
y =
  do
    Text
key <- NixString -> m Text
forall e (m :: * -> *). Framed e m => NixString -> m Text
fromStringNoContext (NixString -> m Text) -> m NixString -> m Text
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m NixString
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
x
    (AttrSet (NValue t f m)
aset, HashMap Text SourcePos
_) <- NValue t f m -> m (AttrSet (NValue t f m), HashMap Text SourcePos)
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @(AttrSet (NValue t f m), AttrSet SourcePos) NValue t f m
y

    Text -> AttrSet (NValue t f m) -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
Text -> AttrSet (NValue t f m) -> m (NValue t f m)
attrsetGet Text
key AttrSet (NValue t f m)
aset

unsafeGetAttrPosNix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
unsafeGetAttrPosNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
unsafeGetAttrPosNix NValue t f m
nvX NValue t f m
nvY =
  do
    NValue t f m
x <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nvX
    NValue t f m
y <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nvY

    case (NValue t f m
x, NValue t f m
y) of
      (NVStr NixString
ns, NVSet AttrSet (NValue t f m)
_ HashMap Text SourcePos
apos) ->
        m (NValue t f m)
-> (SourcePos -> m (NValue t f m))
-> Maybe SourcePos
-> m (NValue t f m)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
          (NValue t f m -> m (NValue t f m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure NValue t f m
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m
nVNull)
          SourcePos -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue
          (Text -> HashMap Text SourcePos -> Maybe SourcePos
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup (NixString -> Text
stringIgnoreContext NixString
ns) HashMap Text SourcePos
apos)
      (NValue t f m, NValue t f m)
_xy -> ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"Invalid types for builtins.unsafeGetAttrPosNix: " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> (NValue t f m, NValue t f m) -> FilePath
forall b a. (Show a, IsString b) => a -> b
show (NValue t f m, NValue t f m)
_xy

-- This function is a bit special in that it doesn't care about the contents
-- of the list.
lengthNix
  :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
lengthNix :: NValue t f m -> m (NValue t f m)
lengthNix = Int -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Int -> m (NValue t f m))
-> ([NValue t f m] -> Int) -> [NValue t f m] -> m (NValue t f m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([NValue t f m] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length :: [NValue t f m] -> Int) ([NValue t f m] -> m (NValue t f m))
-> (NValue t f m -> m [NValue t f m])
-> NValue t f m
-> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> m [NValue t f m]
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue

addNix
  :: MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
addNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
addNix NValue t f m
nvX NValue t f m
nvY =
  do
    NValue t f m
x' <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nvX
    NValue t f m
y' <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nvY

    case (NValue t f m
x', NValue t f m
y') of
      (NVConstant (NInt   Integer
x), NVConstant (NInt   Integer
y)) -> Integer -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (             Integer
x Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
y :: Integer       )
      (NVConstant (NFloat Float
x), NVConstant (NInt   Integer
y)) -> Float -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Float -> m (NValue t f m)) -> Float -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$             Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Integer -> Float
forall a. Num a => Integer -> a
fromInteger Integer
y
      (NVConstant (NInt   Integer
x), NVConstant (NFloat Float
y)) -> Float -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Float -> m (NValue t f m)) -> Float -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ Integer -> Float
forall a. Num a => Integer -> a
fromInteger Integer
x Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
y
      (NVConstant (NFloat Float
x), NVConstant (NFloat Float
y)) -> Float -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Float -> m (NValue t f m)) -> Float -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$             Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
y
      (NValue t f m
_x                   , NValue t f m
_y                   ) -> ValueFrame t f m -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ValueFrame t f m -> m (NValue t f m))
-> ValueFrame t f m -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ NValue t f m -> NValue t f m -> ValueFrame t f m
forall t (f :: * -> *) (m :: * -> *).
NValue t f m -> NValue t f m -> ValueFrame t f m
Addition NValue t f m
_x NValue t f m
_y

mulNix
  :: MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
mulNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
mulNix NValue t f m
nvX NValue t f m
nvY =
  do
    NValue t f m
x' <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nvX
    NValue t f m
y' <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nvY

    case (NValue t f m
x', NValue t f m
y') of
      (NVConstant (NInt   Integer
x), NVConstant (NInt   Integer
y)) -> Integer -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Integer
x Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
y :: Integer       )
      (NVConstant (NFloat Float
x), NVConstant (NInt   Integer
y)) -> Float -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Integer -> Float
forall a. Num a => Integer -> a
fromInteger Integer
y)
      (NVConstant (NInt   Integer
x), NVConstant (NFloat Float
y)) -> Float -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Integer -> Float
forall a. Num a => Integer -> a
fromInteger Integer
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y)
      (NVConstant (NFloat Float
x), NVConstant (NFloat Float
y)) -> Float -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y            )
      (NValue t f m
_x                   , NValue t f m
_y                   ) -> ValueFrame t f m -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ValueFrame t f m -> m (NValue t f m))
-> ValueFrame t f m -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ NValue t f m -> NValue t f m -> ValueFrame t f m
forall t (f :: * -> *) (m :: * -> *).
NValue t f m -> NValue t f m -> ValueFrame t f m
Multiplication NValue t f m
_x NValue t f m
_y

divNix
  :: MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
divNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
divNix NValue t f m
nvX NValue t f m
nvY =
  do
    NValue t f m
x' <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nvX
    NValue t f m
y' <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nvY
    case (NValue t f m
x', NValue t f m
y') of
      (NVConstant (NInt   Integer
x), NVConstant (NInt   Integer
y)) | Integer
y Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= Integer
0 -> Integer -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (  Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor (Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
x Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
y :: Double) :: Integer)
      (NVConstant (NFloat Float
x), NVConstant (NInt   Integer
y)) | Integer
y Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= Integer
0 -> Float -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Float -> m (NValue t f m)) -> Float -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$                     Float
x Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Integer -> Float
forall a. Num a => Integer -> a
fromInteger Integer
y
      (NVConstant (NInt   Integer
x), NVConstant (NFloat Float
y)) | Float
y Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
/= Float
0 -> Float -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Float -> m (NValue t f m)) -> Float -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$         Integer -> Float
forall a. Num a => Integer -> a
fromInteger Integer
x Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
y
      (NVConstant (NFloat Float
x), NVConstant (NFloat Float
y)) | Float
y Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
/= Float
0 -> Float -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Float -> m (NValue t f m)) -> Float -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$                     Float
x Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
y
      (NValue t f m
_x                   , NValue t f m
_y                   )         -> ValueFrame t f m -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ValueFrame t f m -> m (NValue t f m))
-> ValueFrame t f m -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ NValue t f m -> NValue t f m -> ValueFrame t f m
forall t (f :: * -> *) (m :: * -> *).
NValue t f m -> NValue t f m -> ValueFrame t f m
Division NValue t f m
_x NValue t f m
_y

anyNix
  :: MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
anyNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
anyNix NValue t f m
f = Bool -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Bool -> m (NValue t f m))
-> (NValue t f m -> m Bool) -> NValue t f m -> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< (NValue t f m -> m Bool) -> [NValue t f m] -> m Bool
forall (m :: * -> *) a. Monad m => (a -> m Bool) -> [a] -> m Bool
anyMNix NValue t f m -> m Bool
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue ([NValue t f m] -> m Bool)
-> (NValue t f m -> m [NValue t f m]) -> NValue t f m -> m Bool
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< (NValue t f m -> m (NValue t f m))
-> [NValue t f m] -> m [NValue t f m]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (NValue t f m -> NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> NValue t f m -> m (NValue t f m)
callFunc NValue t f m
f) ([NValue t f m] -> m [NValue t f m])
-> (NValue t f m -> m [NValue t f m])
-> NValue t f m
-> m [NValue t f m]
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> m [NValue t f m]
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue
 where
  anyMNix :: Monad m => (a -> m Bool) -> [a] -> m Bool
  anyMNix :: (a -> m Bool) -> [a] -> m Bool
anyMNix a -> m Bool
_ []       = Bool -> m Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
  anyMNix a -> m Bool
p (a
x : [a]
xs) =
    m Bool -> m Bool -> Bool -> m Bool
forall a. a -> a -> Bool -> a
bool
      ((a -> m Bool) -> [a] -> m Bool
forall (m :: * -> *) a. Monad m => (a -> m Bool) -> [a] -> m Bool
anyMNix a -> m Bool
p [a]
xs)
      (Bool -> m Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True)
      (Bool -> m Bool) -> m Bool -> m Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< a -> m Bool
p a
x

allNix
  :: MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
allNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
allNix NValue t f m
f = Bool -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Bool -> m (NValue t f m))
-> (NValue t f m -> m Bool) -> NValue t f m -> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< (NValue t f m -> m Bool) -> [NValue t f m] -> m Bool
forall (m :: * -> *) a. Monad m => (a -> m Bool) -> [a] -> m Bool
allMNix NValue t f m -> m Bool
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue ([NValue t f m] -> m Bool)
-> (NValue t f m -> m [NValue t f m]) -> NValue t f m -> m Bool
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< (NValue t f m -> m (NValue t f m))
-> [NValue t f m] -> m [NValue t f m]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (NValue t f m -> NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> NValue t f m -> m (NValue t f m)
callFunc NValue t f m
f) ([NValue t f m] -> m [NValue t f m])
-> (NValue t f m -> m [NValue t f m])
-> NValue t f m
-> m [NValue t f m]
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> m [NValue t f m]
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue
 where
  allMNix :: Monad m => (a -> m Bool) -> [a] -> m Bool
  allMNix :: (a -> m Bool) -> [a] -> m Bool
allMNix a -> m Bool
_ []       = Bool -> m Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
  allMNix a -> m Bool
p (a
x : [a]
xs) =
    m Bool -> m Bool -> Bool -> m Bool
forall a. a -> a -> Bool -> a
bool
      (Bool -> m Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False)
      ((a -> m Bool) -> [a] -> m Bool
forall (m :: * -> *) a. Monad m => (a -> m Bool) -> [a] -> m Bool
allMNix a -> m Bool
p [a]
xs)
      (Bool -> m Bool) -> m Bool -> m Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< a -> m Bool
p a
x

foldl'Nix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
foldl'Nix :: NValue t f m -> NValue t f m -> NValue t f m -> m (NValue t f m)
foldl'Nix NValue t f m
f NValue t f m
z NValue t f m
xs =  (NValue t f m -> NValue t f m -> m (NValue t f m))
-> NValue t f m -> [NValue t f m] -> m (NValue t f m)
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM NValue t f m -> NValue t f m -> m (NValue t f m)
go NValue t f m
z ([NValue t f m] -> m (NValue t f m))
-> m [NValue t f m] -> m (NValue t f m)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m [NValue t f m]
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @[NValue t f m] NValue t f m
xs
 where
  go :: NValue t f m -> NValue t f m -> m (NValue t f m)
go NValue t f m
b NValue t f m
a = (NValue t f m -> NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> NValue t f m -> m (NValue t f m)
`callFunc` NValue t f m
a) (NValue t f m -> m (NValue t f m))
-> m (NValue t f m) -> m (NValue t f m)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> NValue t f m -> m (NValue t f m)
callFunc NValue t f m
f NValue t f m
b

headNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
headNix :: NValue t f m -> m (NValue t f m)
headNix =
  m (NValue t f m)
-> ([NValue t f m] -> m (NValue t f m))
-> [NValue t f m]
-> m (NValue t f m)
forall (t :: * -> *) b a. Foldable t => b -> (t a -> b) -> t a -> b
list
    (ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall FilePath
"builtins.head: empty list")
    (NValue t f m -> m (NValue t f m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NValue t f m -> m (NValue t f m))
-> ([NValue t f m] -> NValue t f m)
-> [NValue t f m]
-> m (NValue t f m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [NValue t f m] -> NValue t f m
forall a. [a] -> a
Unsafe.head)
    ([NValue t f m] -> m (NValue t f m))
-> (NValue t f m -> m [NValue t f m])
-> NValue t f m
-> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> m [NValue t f m]
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue

tailNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
tailNix :: NValue t f m -> m (NValue t f m)
tailNix =
  m (NValue t f m)
-> ([NValue t f m] -> m (NValue t f m))
-> [NValue t f m]
-> m (NValue t f m)
forall (t :: * -> *) b a. Foldable t => b -> (t a -> b) -> t a -> b
list
    (ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall FilePath
"builtins.tail: empty list")
    (NValue t f m -> m (NValue t f m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NValue t f m -> m (NValue t f m))
-> ([NValue t f m] -> NValue t f m)
-> [NValue t f m]
-> m (NValue t f m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [NValue t f m] -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
[NValue t f m] -> NValue t f m
nvList ([NValue t f m] -> NValue t f m)
-> ([NValue t f m] -> [NValue t f m])
-> [NValue t f m]
-> NValue t f m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [NValue t f m] -> [NValue t f m]
forall a. [a] -> [a]
Unsafe.tail)
    ([NValue t f m] -> m (NValue t f m))
-> (NValue t f m -> m [NValue t f m])
-> NValue t f m
-> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> m [NValue t f m]
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue

splitVersionNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
splitVersionNix :: NValue t f m -> m (NValue t f m)
splitVersionNix NValue t f m
v =
  do
    Text
version <- NixString -> m Text
forall e (m :: * -> *). Framed e m => NixString -> m Text
fromStringNoContext (NixString -> m Text) -> m NixString -> m Text
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m NixString
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
v
    pure $
      [NValue t f m] -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
[NValue t f m] -> NValue t f m
nvList ([NValue t f m] -> NValue t f m) -> [NValue t f m] -> NValue t f m
forall a b. (a -> b) -> a -> b
$
        NixString -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
NixString -> NValue t f m
nvStr (NixString -> NValue t f m)
-> (VersionComponent -> NixString)
-> VersionComponent
-> NValue t f m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> NixString
makeNixStringWithoutContext (Text -> NixString)
-> (VersionComponent -> Text) -> VersionComponent -> NixString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VersionComponent -> Text
versionComponentToString (VersionComponent -> NValue t f m)
-> [VersionComponent] -> [NValue t f m]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
          Text -> [VersionComponent]
splitVersion Text
version

compareVersionsNix
  :: MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
compareVersionsNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
compareVersionsNix NValue t f m
t1 NValue t f m
t2 =
  do
    Text
s1 <- NValue t f m -> m Text
mkText NValue t f m
t1
    Text
s2 <- NValue t f m -> m Text
mkText NValue t f m
t2

    let
      cmpVers :: Integer
cmpVers =
        case Text -> Text -> Ordering
compareVersions Text
s1 Text
s2 of
          Ordering
LT -> -Integer
1
          Ordering
EQ -> Integer
0
          Ordering
GT -> Integer
1

    NValue t f m -> m (NValue t f m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NValue t f m -> m (NValue t f m))
-> NValue t f m -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ NAtom -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
NAtom -> NValue t f m
nvConstant (NAtom -> NValue t f m) -> NAtom -> NValue t f m
forall a b. (a -> b) -> a -> b
$ Integer -> NAtom
NInt Integer
cmpVers

 where
  mkText :: NValue t f m -> m Text
mkText = NixString -> m Text
forall e (m :: * -> *). Framed e m => NixString -> m Text
fromStringNoContext (NixString -> m Text)
-> (NValue t f m -> m NixString) -> NValue t f m -> m Text
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> m NixString
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue

parseDrvNameNix
  :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
parseDrvNameNix :: NValue t f m -> m (NValue t f m)
parseDrvNameNix NValue t f m
drvname =
  do
    Text
s <- NixString -> m Text
forall e (m :: * -> *). Framed e m => NixString -> m Text
fromStringNoContext (NixString -> m Text) -> m NixString -> m Text
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m NixString
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
drvname

    let
      (Text
name :: Text, Text
version :: Text) = Text -> (Text, Text)
splitDrvName Text
s

    forall a (m :: * -> *) v. ToValue a m v => a -> m v
forall (m :: * -> *) v.
ToValue (AttrSet (NValue t f m)) m v =>
AttrSet (NValue t f m) -> m v
toValue @(AttrSet (NValue t f m)) (AttrSet (NValue t f m) -> m (NValue t f m))
-> AttrSet (NValue t f m) -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$
      [(Text, NValue t f m)] -> AttrSet (NValue t f m)
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
M.fromList
        [ ( Text
"name" :: Text
          , Text -> NValue t f m
forall t (m :: * -> *). Text -> NValue t f m
mkNVStr Text
name
          )
        , ( Text
"version"
          , Text -> NValue t f m
forall t (m :: * -> *). Text -> NValue t f m
mkNVStr Text
version
          )
        ]

 where
  mkNVStr :: Text -> NValue t f m
mkNVStr = NixString -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
NixString -> NValue t f m
nvStr (NixString -> NValue t f m)
-> (Text -> NixString) -> Text -> NValue t f m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> NixString
makeNixStringWithoutContext

matchNix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
matchNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
matchNix NValue t f m
pat NValue t f m
str =
  do
    Text
p <- NixString -> m Text
forall e (m :: * -> *). Framed e m => NixString -> m Text
fromStringNoContext (NixString -> m Text) -> m NixString -> m Text
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m NixString
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
pat
    NixString
ns <- NValue t f m -> m NixString
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
str

    -- NOTE: 2018-11-19: Currently prim_match in nix/src/libexpr/primops.cc
    -- ignores the context of its second argument. This is probably a bug but we're
    -- going to preserve the behavior here until it is fixed upstream.
    -- Relevant issue: https://github.com/NixOS/nix/issues/2547
    let
      s :: Text
s  = NixString -> Text
stringIgnoreContext NixString
ns
      re :: Regex
re = Text -> Regex
forall regex compOpt execOpt source.
RegexMaker regex compOpt execOpt source =>
source -> regex
makeRegex Text
p :: Regex
      mkMatch :: Text -> m v
mkMatch Text
t =
        m v -> m v -> Bool -> m v
forall a. a -> a -> Bool -> a
bool
          (() -> m v
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue ()) -- Shorthand for Null
          (NixString -> m v
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (NixString -> m v) -> NixString -> m v
forall a b. (a -> b) -> a -> b
$ Text -> NixString
makeNixStringWithoutContext Text
t)
          (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Text -> Bool
Text.null Text
t)

    m (NValue t f m)
-> ((Text, Array Int (Text, (Int, Int)), Text) -> m (NValue t f m))
-> Maybe (Text, Array Int (Text, (Int, Int)), Text)
-> m (NValue t f m)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
      (NValue t f m -> m (NValue t f m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure NValue t f m
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m
nVNull)
      (\case
        (Text
"", Array Int (Text, (Int, Int))
sarr, Text
"") ->
          do
            let s :: [Text]
s = (Text, (Int, Int)) -> Text
forall a b. (a, b) -> a
fst ((Text, (Int, Int)) -> Text) -> [(Text, (Int, Int))] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Array Int (Text, (Int, Int)) -> [(Text, (Int, Int))]
forall i e. Array i e -> [e]
elems Array Int (Text, (Int, Int))
sarr
            [NValue t f m] -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
[NValue t f m] -> NValue t f m
nvList ([NValue t f m] -> NValue t f m)
-> m [NValue t f m] -> m (NValue t f m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
              (Text -> m (NValue t f m)) -> [Text] -> m [NValue t f m]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse
                Text -> m (NValue t f m)
forall (m :: * -> *) v.
(ToValue () m v, ToValue NixString m v) =>
Text -> m v
mkMatch
                (([Text] -> [Text])
-> ([Text] -> [Text]) -> Bool -> [Text] -> [Text]
forall a. a -> a -> Bool -> a
bool
                    [Text] -> [Text]
forall a. a -> a
id -- (length <= 1) allowed & passes-through here the full string
                    [Text] -> [Text]
forall a. [a] -> [a]
Unsafe.tail
                    ([Text] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Text]
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1)
                    [Text]
s
                )
        (Text, Array Int (Text, (Int, Int)), Text)
_ -> (NValue t f m -> m (NValue t f m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure NValue t f m
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m
nVNull)
      )
      (Regex -> Text -> Maybe (Text, Array Int (Text, (Int, Int)), Text)
forall regex source.
RegexLike regex source =>
regex -> source -> Maybe (source, MatchText source, source)
matchOnceText Regex
re Text
s)

splitNix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
splitNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
splitNix NValue t f m
pat NValue t f m
str =
  do
    Text
p <- NixString -> m Text
forall e (m :: * -> *). Framed e m => NixString -> m Text
fromStringNoContext (NixString -> m Text) -> m NixString -> m Text
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m NixString
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
pat
    NixString
ns <- NValue t f m -> m NixString
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
str
        -- NOTE: Currently prim_split in nix/src/libexpr/primops.cc ignores the
        -- context of its second argument. This is probably a bug but we're
        -- going to preserve the behavior here until it is fixed upstream.
        -- Relevant issue: https://github.com/NixOS/nix/issues/2547
    let
      s :: Text
s = NixString -> Text
stringIgnoreContext NixString
ns
      regex :: Regex
regex       = Text -> Regex
forall regex compOpt execOpt source.
RegexMaker regex compOpt execOpt source =>
source -> regex
makeRegex Text
p :: Regex
      haystack :: ByteString
haystack = Text -> ByteString
forall a b. ConvertUtf8 a b => a -> b
encodeUtf8 Text
s

    NValue t f m -> m (NValue t f m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NValue t f m -> m (NValue t f m))
-> NValue t f m -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ [NValue t f m] -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
[NValue t f m] -> NValue t f m
nvList ([NValue t f m] -> NValue t f m) -> [NValue t f m] -> NValue t f m
forall a b. (a -> b) -> a -> b
$ Int -> [[(ByteString, (Int, Int))]] -> ByteString -> [NValue t f m]
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
Int -> [[(ByteString, (Int, Int))]] -> ByteString -> [NValue t f m]
splitMatches Int
0 (Array Int (ByteString, (Int, Int)) -> [(ByteString, (Int, Int))]
forall i e. Array i e -> [e]
elems (Array Int (ByteString, (Int, Int)) -> [(ByteString, (Int, Int))])
-> [Array Int (ByteString, (Int, Int))]
-> [[(ByteString, (Int, Int))]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Regex -> ByteString -> [Array Int (ByteString, (Int, Int))]
forall regex source.
RegexLike regex source =>
regex -> source -> [MatchText source]
matchAllText Regex
regex ByteString
haystack) ByteString
haystack

substringNix :: forall e t f m. MonadNix e t f m => Int -> Int -> NixString -> Prim m NixString
substringNix :: Int -> Int -> NixString -> Prim m NixString
substringNix Int
start Int
len NixString
str =
  m NixString -> Prim m NixString
forall (m :: * -> *) a. m a -> Prim m a
Prim (m NixString -> Prim m NixString)
-> m NixString -> Prim m NixString
forall a b. (a -> b) -> a -> b
$
    m NixString -> m NixString -> Bool -> m NixString
forall a. a -> a -> Bool -> a
bool
      (ErrorCall -> m NixString
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m NixString) -> ErrorCall -> m NixString
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"builtins.substring: negative start position: " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> Int -> FilePath
forall b a. (Show a, IsString b) => a -> b
show Int
start)
      (NixString -> m NixString
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NixString -> m NixString) -> NixString -> m NixString
forall a b. (a -> b) -> a -> b
$ (Text -> Text) -> NixString -> NixString
modifyNixContents (Text -> Text
take (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Text -> Text
Text.drop Int
start) NixString
str)
      (Int
start Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0)
 where
  take :: Text -> Text
take =
    (Text -> Text) -> (Text -> Text) -> Bool -> Text -> Text
forall a. a -> a -> Bool -> a
bool
      Text -> Text
forall a. a -> a
id  --NOTE: negative values of 'len' are OK, and mean "take everything"
      (Int -> Text -> Text
Text.take Int
len)
      (Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0)

attrNamesNix
  :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
attrNamesNix :: NValue t f m -> m (NValue t f m)
attrNamesNix =
  ((Deeper (NValue t f m) -> NValue t f m)
-> m (Deeper (NValue t f m)) -> m (NValue t f m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Deeper (NValue t f m) -> NValue t f m
forall a. Deeper a -> a
getDeeper (m (Deeper (NValue t f m)) -> m (NValue t f m))
-> (HashMap Text (NValue t f m) -> m (Deeper (NValue t f m)))
-> HashMap Text (NValue t f m)
-> m (NValue t f m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [NixString] -> m (Deeper (NValue t f m))
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue ([NixString] -> m (Deeper (NValue t f m)))
-> (HashMap Text (NValue t f m) -> [NixString])
-> HashMap Text (NValue t f m)
-> m (Deeper (NValue t f m))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> NixString) -> [Text] -> [NixString]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> NixString
makeNixStringWithoutContext ([Text] -> [NixString])
-> (HashMap Text (NValue t f m) -> [Text])
-> HashMap Text (NValue t f m)
-> [NixString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Text] -> [Text]
forall a. Ord a => [a] -> [a]
sort ([Text] -> [Text])
-> (HashMap Text (NValue t f m) -> [Text])
-> HashMap Text (NValue t f m)
-> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap Text (NValue t f m) -> [Text]
forall k v. HashMap k v -> [k]
M.keys)
  (HashMap Text (NValue t f m) -> m (NValue t f m))
-> (NValue t f m -> m (HashMap Text (NValue t f m)))
-> NValue t f m
-> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall a (m :: * -> *) v. FromValue a m v => v -> m a
forall (m :: * -> *) v.
FromValue (HashMap Text (NValue t f m)) m v =>
v -> m (HashMap Text (NValue t f m))
fromValue @(AttrSet (NValue t f m))

attrValuesNix
  :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
attrValuesNix :: NValue t f m -> m (NValue t f m)
attrValuesNix NValue t f m
nvattrs =
  do
    AttrSet (NValue t f m)
attrs <- NValue t f m -> m (AttrSet (NValue t f m))
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @(AttrSet (NValue t f m)) NValue t f m
nvattrs
    [NValue t f m] -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue ([NValue t f m] -> m (NValue t f m))
-> [NValue t f m] -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$
      (Text, NValue t f m) -> NValue t f m
forall a b. (a, b) -> b
snd ((Text, NValue t f m) -> NValue t f m)
-> [(Text, NValue t f m)] -> [NValue t f m]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
        ((Text, NValue t f m) -> Text)
-> [(Text, NValue t f m)] -> [(Text, NValue t f m)]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn
          ((Text, NValue t f m) -> Text
forall a b. (a, b) -> a
fst @Text @(NValue t f m))
          (AttrSet (NValue t f m) -> [(Text, NValue t f m)]
forall k v. HashMap k v -> [(k, v)]
M.toList AttrSet (NValue t f m)
attrs)

mapNix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
mapNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
mapNix NValue t f m
f =
  [NValue t f m] -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue ([NValue t f m] -> m (NValue t f m))
-> (NValue t f m -> m [NValue t f m])
-> NValue t f m
-> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
    (NValue t f m -> m (NValue t f m))
-> [NValue t f m] -> m [NValue t f m]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse
      (forall v (m :: * -> *). MonadValue v m => m v -> m v
forall (m :: * -> *).
MonadValue (NValue t f m) m =>
m (NValue t f m) -> m (NValue t f m)
defer @(NValue t f m)
      (m (NValue t f m) -> m (NValue t f m))
-> (NValue t f m -> m (NValue t f m))
-> NValue t f m
-> m (NValue t f m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NixLevel -> ErrorCall -> m (NValue t f m) -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s) =>
NixLevel -> s -> m a -> m a
withFrame NixLevel
Debug (FilePath -> ErrorCall
ErrorCall FilePath
"While applying f in map:\n")
      (m (NValue t f m) -> m (NValue t f m))
-> (NValue t f m -> m (NValue t f m))
-> NValue t f m
-> m (NValue t f m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NValue t f m -> NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> NValue t f m -> m (NValue t f m)
callFunc NValue t f m
f
      )
      ([NValue t f m] -> m [NValue t f m])
-> (NValue t f m -> m [NValue t f m])
-> NValue t f m
-> m [NValue t f m]
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall a (m :: * -> *) v. FromValue a m v => v -> m a
forall (m :: * -> *) v.
FromValue [NValue t f m] m v =>
v -> m [NValue t f m]
fromValue @[NValue t f m]

mapAttrsNix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
mapAttrsNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
mapAttrsNix NValue t f m
f NValue t f m
xs =
  do
    AttrSet (NValue t f m)
nixAttrset <- NValue t f m -> m (AttrSet (NValue t f m))
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @(AttrSet (NValue t f m)) NValue t f m
xs
    let
      keyVals :: [(Text, NValue t f m)]
keyVals = AttrSet (NValue t f m) -> [(Text, NValue t f m)]
forall k v. HashMap k v -> [(k, v)]
M.toList AttrSet (NValue t f m)
nixAttrset
      keys :: [Text]
keys = (Text, NValue t f m) -> Text
forall a b. (a, b) -> a
fst ((Text, NValue t f m) -> Text) -> [(Text, NValue t f m)] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Text, NValue t f m)]
keyVals

      applyFunToKeyVal :: (Text, NValue t f m) -> m (NValue t f m)
applyFunToKeyVal (Text
key, NValue t f m
val) =
        do
          NValue t f m
runFunForKey <- NValue t f m -> NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> NValue t f m -> m (NValue t f m)
callFunc NValue t f m
f (NValue t f m -> m (NValue t f m))
-> NValue t f m -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ NixString -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
NixString -> NValue t f m
nvStr (NixString -> NValue t f m) -> NixString -> NValue t f m
forall a b. (a -> b) -> a -> b
$ Text -> NixString
makeNixStringWithoutContext Text
key
          NValue t f m -> NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> NValue t f m -> m (NValue t f m)
callFunc NValue t f m
runFunForKey NValue t f m
val

    [NValue t f m]
newVals <-
      ((Text, NValue t f m) -> m (NValue t f m))
-> [(Text, NValue t f m)] -> m [NValue t f m]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse
        (forall v (m :: * -> *). MonadValue v m => m v -> m v
forall (m :: * -> *).
MonadValue (NValue t f m) m =>
m (NValue t f m) -> m (NValue t f m)
defer @(NValue t f m) (m (NValue t f m) -> m (NValue t f m))
-> ((Text, NValue t f m) -> m (NValue t f m))
-> (Text, NValue t f m)
-> m (NValue t f m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NixLevel -> ErrorCall -> m (NValue t f m) -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s) =>
NixLevel -> s -> m a -> m a
withFrame NixLevel
Debug (FilePath -> ErrorCall
ErrorCall FilePath
"While applying f in mapAttrs:\n") (m (NValue t f m) -> m (NValue t f m))
-> ((Text, NValue t f m) -> m (NValue t f m))
-> (Text, NValue t f m)
-> m (NValue t f m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text, NValue t f m) -> m (NValue t f m)
applyFunToKeyVal)
        [(Text, NValue t f m)]
keyVals

    AttrSet (NValue t f m) -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (AttrSet (NValue t f m) -> m (NValue t f m))
-> AttrSet (NValue t f m) -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ [(Text, NValue t f m)] -> AttrSet (NValue t f m)
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
M.fromList ([(Text, NValue t f m)] -> AttrSet (NValue t f m))
-> [(Text, NValue t f m)] -> AttrSet (NValue t f m)
forall a b. (a -> b) -> a -> b
$ [Text] -> [NValue t f m] -> [(Text, NValue t f m)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Text]
keys [NValue t f m]
newVals

filterNix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
filterNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
filterNix NValue t f m
f =
  [NValue t f m] -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue ([NValue t f m] -> m (NValue t f m))
-> (NValue t f m -> m [NValue t f m])
-> NValue t f m
-> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
    (NValue t f m -> m Bool) -> [NValue t f m] -> m [NValue t f m]
forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM
      (NValue t f m -> m Bool
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue (NValue t f m -> m Bool)
-> (NValue t f m -> m (NValue t f m)) -> NValue t f m -> m Bool
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> NValue t f m -> m (NValue t f m)
callFunc NValue t f m
f)
      ([NValue t f m] -> m [NValue t f m])
-> (NValue t f m -> m [NValue t f m])
-> NValue t f m
-> m [NValue t f m]
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> m [NValue t f m]
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue

catAttrsNix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
catAttrsNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
catAttrsNix NValue t f m
attrName NValue t f m
xs =
  do
    Text
n <- NixString -> m Text
forall e (m :: * -> *). Framed e m => NixString -> m Text
fromStringNoContext (NixString -> m Text) -> m NixString -> m Text
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m NixString
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
attrName
    [NValue t f m]
l <- NValue t f m -> m [NValue t f m]
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @[NValue t f m] NValue t f m
xs

    [NValue t f m] -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
[NValue t f m] -> NValue t f m
nvList ([NValue t f m] -> NValue t f m)
-> ([Maybe (NValue t f m)] -> [NValue t f m])
-> [Maybe (NValue t f m)]
-> NValue t f m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe (NValue t f m)] -> [NValue t f m]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe (NValue t f m)] -> NValue t f m)
-> m [Maybe (NValue t f m)] -> m (NValue t f m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
      (NValue t f m -> m (Maybe (NValue t f m)))
-> [NValue t f m] -> m [Maybe (NValue t f m)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse
        ((HashMap Text (NValue t f m) -> Maybe (NValue t f m))
-> m (HashMap Text (NValue t f m)) -> m (Maybe (NValue t f m))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Text -> HashMap Text (NValue t f m) -> Maybe (NValue t f m)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup Text
n) (m (HashMap Text (NValue t f m)) -> m (Maybe (NValue t f m)))
-> (NValue t f m -> m (HashMap Text (NValue t f m)))
-> NValue t f m
-> m (Maybe (NValue t f m))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NValue t f m -> m (HashMap Text (NValue t f m))
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue (NValue t f m -> m (Maybe (NValue t f m)))
-> (NValue t f m -> m (NValue t f m))
-> NValue t f m
-> m (Maybe (NValue t f m))
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand)
        [NValue t f m]
l

baseNameOfNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
baseNameOfNix :: NValue t f m -> m (NValue t f m)
baseNameOfNix NValue t f m
x =
  do
    NixString
ns <- (NValue t f m -> NValue t f m -> m (NValue t f m))
-> CopyToStoreMode -> CoercionLevel -> NValue t f m -> m NixString
forall e (m :: * -> *) t (f :: * -> *).
(Framed e m, MonadStore m, MonadThrow m,
 MonadDataErrorContext t f m, MonadValue (NValue t f m) m) =>
(NValue t f m -> NValue t f m -> m (NValue t f m))
-> CopyToStoreMode -> CoercionLevel -> NValue t f m -> m NixString
coerceToString NValue t f m -> NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> NValue t f m -> m (NValue t f m)
callFunc CopyToStoreMode
DontCopyToStore CoercionLevel
CoerceStringy NValue t f m
x
    pure $
      NixString -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
NixString -> NValue t f m
nvStr (NixString -> NValue t f m) -> NixString -> NValue t f m
forall a b. (a -> b) -> a -> b
$
        (Text -> Text) -> NixString -> NixString
modifyNixContents
          (FilePath -> Text
forall a. ToText a => a -> Text
toText (FilePath -> Text) -> (Text -> FilePath) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> FilePath
takeFileName (FilePath -> FilePath) -> (Text -> FilePath) -> Text -> FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> FilePath
forall a. ToString a => a -> FilePath
toString)
          NixString
ns

bitAndNix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
bitAndNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
bitAndNix NValue t f m
x NValue t f m
y =
  do
    Integer
a <- NValue t f m -> m Integer
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @Integer NValue t f m
x
    Integer
b <- NValue t f m -> m Integer
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @Integer NValue t f m
y

    Integer -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Integer
a Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
b)

bitOrNix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
bitOrNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
bitOrNix NValue t f m
x NValue t f m
y =
  do
    Integer
a <- NValue t f m -> m Integer
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @Integer NValue t f m
x
    Integer
b <- NValue t f m -> m Integer
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @Integer NValue t f m
y

    Integer -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Integer
a Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.|. Integer
b)

bitXorNix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
bitXorNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
bitXorNix NValue t f m
x NValue t f m
y =
  do
    Integer
a <- NValue t f m -> m Integer
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @Integer NValue t f m
x
    Integer
b <- NValue t f m -> m Integer
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @Integer NValue t f m
y

    Integer -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Integer
a Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
`xor` Integer
b)

builtinsBuiltinNix
  :: forall e t f m
   . MonadNix e t f m
  => m (NValue t f m)
builtinsBuiltinNix :: m (NValue t f m)
builtinsBuiltinNix = ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall FilePath
"HNix does not provide builtins.builtins at the moment. Using builtins directly should be preferred"

dirOfNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
dirOfNix :: NValue t f m -> m (NValue t f m)
dirOfNix NValue t f m
nvdir =
  do
    NValue t f m
dir <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nvdir

    case NValue t f m
dir of
      NVStr NixString
ns -> NValue t f m -> m (NValue t f m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NValue t f m -> m (NValue t f m))
-> NValue t f m -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ NixString -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
NixString -> NValue t f m
nvStr (NixString -> NValue t f m) -> NixString -> NValue t f m
forall a b. (a -> b) -> a -> b
$ (Text -> Text) -> NixString -> NixString
modifyNixContents (FilePath -> Text
forall a. ToText a => a -> Text
toText (FilePath -> Text) -> (Text -> FilePath) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> FilePath
takeDirectory (FilePath -> FilePath) -> (Text -> FilePath) -> Text -> FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> FilePath
forall a. ToString a => a -> FilePath
toString) NixString
ns
      NVPath FilePath
path -> NValue t f m -> m (NValue t f m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NValue t f m -> m (NValue t f m))
-> NValue t f m -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
FilePath -> NValue t f m
nvPath (FilePath -> NValue t f m) -> FilePath -> NValue t f m
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath
takeDirectory FilePath
path
      NValue t f m
v -> ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"dirOf: expected string or path, got " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> NValue t f m -> FilePath
forall b a. (Show a, IsString b) => a -> b
show NValue t f m
v

-- jww (2018-04-28): This should only be a string argument, and not coerced?
unsafeDiscardStringContextNix
  :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
unsafeDiscardStringContextNix :: NValue t f m -> m (NValue t f m)
unsafeDiscardStringContextNix NValue t f m
mnv = do
  NixString
ns <- NValue t f m -> m NixString
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
mnv
  NixString -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (NixString -> m (NValue t f m)) -> NixString -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ Text -> NixString
makeNixStringWithoutContext (Text -> NixString) -> Text -> NixString
forall a b. (a -> b) -> a -> b
$ NixString -> Text
stringIgnoreContext NixString
ns

-- | Evaluate `a` to WHNF to collect its topmost effect.
seqNix
  :: MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
seqNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
seqNix NValue t f m
a NValue t f m
b = NValue t f m
b NValue t f m -> m (NValue t f m) -> m (NValue t f m)
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
a

-- | Evaluate 'a' to NF to collect all of its effects, therefore data cycles are ignored.
deepSeqNix
  :: MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
deepSeqNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
deepSeqNix NValue t f m
a NValue t f m
b = NValue t f m
b NValue t f m -> m () -> m (NValue t f m)
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ NValue t f m -> m ()
forall e (m :: * -> *) t (f :: * -> *).
(Framed e m, MonadThunk t m (NValue t f m),
 MonadDataErrorContext t f m, Ord (ThunkId m)) =>
NValue t f m -> m ()
normalForm_ NValue t f m
a

elemNix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
elemNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
elemNix NValue t f m
x = Bool -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Bool -> m (NValue t f m))
-> (NValue t f m -> m Bool) -> NValue t f m -> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< (NValue t f m -> m Bool) -> [NValue t f m] -> m Bool
forall a. Monad m => (a -> m Bool) -> [a] -> m Bool
anyMNix (NValue t f m -> NValue t f m -> m Bool
forall t (m :: * -> *) (f :: * -> *).
(MonadThunk t m (NValue t f m), Comonad f) =>
NValue t f m -> NValue t f m -> m Bool
valueEqM NValue t f m
x) ([NValue t f m] -> m Bool)
-> (NValue t f m -> m [NValue t f m]) -> NValue t f m -> m Bool
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> m [NValue t f m]
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue
 where
  anyMNix :: Monad m => (a -> m Bool) -> [a] -> m Bool
  anyMNix :: (a -> m Bool) -> [a] -> m Bool
anyMNix a -> m Bool
_ []       = Bool -> m Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
  anyMNix a -> m Bool
p (a
x : [a]
xs) =
    m Bool -> m Bool -> Bool -> m Bool
forall a. a -> a -> Bool -> a
bool
      ((a -> m Bool) -> [a] -> m Bool
forall a. Monad m => (a -> m Bool) -> [a] -> m Bool
anyMNix a -> m Bool
p [a]
xs)
      (Bool -> m Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True)
      (Bool -> m Bool) -> m Bool -> m Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< a -> m Bool
p a
x

elemAtNix
  :: MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
elemAtNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
elemAtNix NValue t f m
xs NValue t f m
n =
  do
    Int
n' <- NValue t f m -> m Int
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
n
    [NValue t f m]
xs' <- NValue t f m -> m [NValue t f m]
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
xs
    m (NValue t f m)
-> (NValue t f m -> m (NValue t f m))
-> Maybe (NValue t f m)
-> m (NValue t f m)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
      (ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"builtins.elem: Index " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> Int -> FilePath
forall b a. (Show a, IsString b) => a -> b
show Int
n' FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
" too large for list of length " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> Int -> FilePath
forall b a. (Show a, IsString b) => a -> b
show ([NValue t f m] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [NValue t f m]
xs'))
      NValue t f m -> m (NValue t f m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure
      ([NValue t f m] -> Int -> Maybe (NValue t f m)
forall a. [a] -> Int -> Maybe a
elemAt [NValue t f m]
xs' Int
n')

genListNix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
genListNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
genListNix NValue t f m
f NValue t f m
nixN =
  do
    Integer
n <- NValue t f m -> m Integer
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @Integer NValue t f m
nixN
    m (NValue t f m) -> m (NValue t f m) -> Bool -> m (NValue t f m)
forall a. a -> a -> Bool -> a
bool
      (ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"builtins.genList: Expected a non-negative number, got " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> Integer -> FilePath
forall b a. (Show a, IsString b) => a -> b
show Integer
n)
      ([NValue t f m] -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue ([NValue t f m] -> m (NValue t f m))
-> m [NValue t f m] -> m (NValue t f m)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Integer -> m (NValue t f m)) -> [Integer] -> m [NValue t f m]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (m (NValue t f m) -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => m v -> m v
defer (m (NValue t f m) -> m (NValue t f m))
-> (NValue t f m -> m (NValue t f m))
-> NValue t f m
-> m (NValue t f m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NValue t f m -> NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> NValue t f m -> m (NValue t f m)
callFunc NValue t f m
f (NValue t f m -> m (NValue t f m))
-> (Integer -> m (NValue t f m)) -> Integer -> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Integer -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue) [Integer
0 .. Integer
n Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1])
      (Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
0)

genericClosureNix
  :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
genericClosureNix :: NValue t f m -> m (NValue t f m)
genericClosureNix NValue t f m
c =
  do
  AttrSet (NValue t f m)
s <- NValue t f m -> m (AttrSet (NValue t f m))
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @(AttrSet (NValue t f m)) NValue t f m
c

  case (Text -> AttrSet (NValue t f m) -> Maybe (NValue t f m)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup Text
"startSet" AttrSet (NValue t f m)
s, Text -> AttrSet (NValue t f m) -> Maybe (NValue t f m)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup Text
"operator" AttrSet (NValue t f m)
s) of
    (Maybe (NValue t f m)
Nothing    , Maybe (NValue t f m)
Nothing        ) -> ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall FilePath
"builtins.genericClosure: Attributes 'startSet' and 'operator' required"
    (Maybe (NValue t f m)
Nothing    , Just NValue t f m
_         ) -> ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall FilePath
"builtins.genericClosure: Attribute 'startSet' required"
    (Just NValue t f m
_     , Maybe (NValue t f m)
Nothing        ) -> ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall FilePath
"builtins.genericClosure: Attribute 'operator' required"
    (Just NValue t f m
startSet, Just NValue t f m
operator) ->
      do
        [NValue t f m]
ss <- forall a (m :: * -> *) v. FromValue a m v => v -> m a
forall (m :: * -> *) v.
FromValue [NValue t f m] m v =>
v -> m [NValue t f m]
fromValue @[NValue t f m] (NValue t f m -> m [NValue t f m])
-> m (NValue t f m) -> m [NValue t f m]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
startSet
        NValue t f m
op <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
operator

        forall a (m :: * -> *) v. ToValue a m v => a -> m v
forall (m :: * -> *) v.
ToValue [NValue t f m] m v =>
[NValue t f m] -> m v
toValue @[NValue t f m] ([NValue t f m] -> m (NValue t f m))
-> m [NValue t f m] -> m (NValue t f m)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Set (WValue t f m), [NValue t f m]) -> [NValue t f m]
forall a b. (a, b) -> b
snd ((Set (WValue t f m), [NValue t f m]) -> [NValue t f m])
-> m (Set (WValue t f m), [NValue t f m]) -> m [NValue t f m]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NValue t f m
-> Set (WValue t f m)
-> [NValue t f m]
-> m (Set (WValue t f m), [NValue t f m])
go NValue t f m
op Set (WValue t f m)
forall a. Set a
S.empty [NValue t f m]
ss
 where
  go
    :: NValue t f m
    -> Set (WValue t f m)
    -> [NValue t f m]
    -> m (Set (WValue t f m), [NValue t f m])
  go :: NValue t f m
-> Set (WValue t f m)
-> [NValue t f m]
-> m (Set (WValue t f m), [NValue t f m])
go NValue t f m
_  Set (WValue t f m)
ks []       = (Set (WValue t f m), [NValue t f m])
-> m (Set (WValue t f m), [NValue t f m])
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Set (WValue t f m)
ks, [NValue t f m]
forall a. Monoid a => a
mempty)
  go NValue t f m
op Set (WValue t f m)
ks (NValue t f m
t : [NValue t f m]
ts) =
    do
      NValue t f m
v <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
t
      NValue t f m
k <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand (NValue t f m -> m (NValue t f m))
-> m (NValue t f m) -> m (NValue t f m)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Text -> AttrSet (NValue t f m) -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
Text -> AttrSet (NValue t f m) -> m (NValue t f m)
attrsetGet Text
"key" (AttrSet (NValue t f m) -> m (NValue t f m))
-> m (AttrSet (NValue t f m)) -> m (NValue t f m)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m (AttrSet (NValue t f m))
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @(AttrSet (NValue t f m)) NValue t f m
v

      m (Set (WValue t f m), [NValue t f m])
-> m (Set (WValue t f m), [NValue t f m])
-> Bool
-> m (Set (WValue t f m), [NValue t f m])
forall a. a -> a -> Bool -> a
bool
        (do
          [NValue t f m]
ys <- forall a (m :: * -> *) v. FromValue a m v => v -> m a
forall (m :: * -> *) v.
FromValue [NValue t f m] m v =>
v -> m [NValue t f m]
fromValue @[NValue t f m] (NValue t f m -> m [NValue t f m])
-> m (NValue t f m) -> m [NValue t f m]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> NValue t f m -> m (NValue t f m)
callFunc NValue t f m
op NValue t f m
v
          NValue t f m -> NValue t f m -> m ()
forall e (m :: * -> *) t (f :: * -> *).
(Framed e m, MonadDataErrorContext t f m) =>
NValue t f m -> NValue t f m -> m ()
checkComparable NValue t f m
k
            (case Set (WValue t f m) -> [WValue t f m]
forall a. Set a -> [a]
S.toList Set (WValue t f m)
ks of
              []           -> NValue t f m
k
              WValue NValue t f m
j : [WValue t f m]
_ -> NValue t f m
j
            )
          (NValue t f m
t NValue t f m -> [NValue t f m] -> [NValue t f m]
forall a. a -> [a] -> [a]
:) ([NValue t f m] -> [NValue t f m])
-> m (Set (WValue t f m), [NValue t f m])
-> m (Set (WValue t f m), [NValue t f m])
forall (f :: * -> *) (g :: * -> *) a b.
(Functor f, Functor g) =>
(a -> b) -> f (g a) -> f (g b)
<<$>> NValue t f m
-> Set (WValue t f m)
-> [NValue t f m]
-> m (Set (WValue t f m), [NValue t f m])
go NValue t f m
op (WValue t f m -> Set (WValue t f m) -> Set (WValue t f m)
forall a. Ord a => a -> Set a -> Set a
S.insert (NValue t f m -> WValue t f m
forall t (f :: * -> *) (m :: * -> *). NValue t f m -> WValue t f m
WValue NValue t f m
k) Set (WValue t f m)
ks) ([NValue t f m]
ts [NValue t f m] -> [NValue t f m] -> [NValue t f m]
forall a. Semigroup a => a -> a -> a
<> [NValue t f m]
ys)
        )
        (NValue t f m
-> Set (WValue t f m)
-> [NValue t f m]
-> m (Set (WValue t f m), [NValue t f m])
go NValue t f m
op Set (WValue t f m)
ks [NValue t f m]
ts)
        (WValue t f m -> Set (WValue t f m) -> Bool
forall a. Ord a => a -> Set a -> Bool
S.member (NValue t f m -> WValue t f m
forall t (f :: * -> *) (m :: * -> *). NValue t f m -> WValue t f m
WValue NValue t f m
k) Set (WValue t f m)
ks)

-- | Takes:
-- 1. List of strings to match.
-- 2. List of strings to replace corresponding match occurance. (arg 1 & 2 lists matched by index)
-- 3. String to process
-- -> returns the string with requested replacements.
--
-- Example:
-- builtins.replaceStrings ["ll" "e"] [" " "i"] "Hello world" == "Hi o world".
replaceStringsNix
  :: MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
replaceStringsNix :: NValue t f m -> NValue t f m -> NValue t f m -> m (NValue t f m)
replaceStringsNix NValue t f m
tfrom NValue t f m
tto NValue t f m
ts =
  do
    -- NixStrings have context - remember
    ([NixString]
fromKeys :: [NixString]) <- Deeper (NValue t f m) -> m [NixString]
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue (NValue t f m -> Deeper (NValue t f m)
forall a. a -> Deeper a
Deeper NValue t f m
tfrom)
    ([NixString]
toVals   :: [NixString]) <- Deeper (NValue t f m) -> m [NixString]
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue (NValue t f m -> Deeper (NValue t f m)
forall a. a -> Deeper a
Deeper NValue t f m
tto)
    (NixString
string   ::  NixString ) <- NValue t f m -> m NixString
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
ts

    Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ([NixString] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [NixString]
fromKeys Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= [NixString] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [NixString]
toVals) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ ErrorCall -> m ()
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m ()) -> ErrorCall -> m ()
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall FilePath
"builtins.replaceStrings: Arguments `from`&`to` construct a key-value map, so the number of their elements must always match."

    let
      --  2021-02-18: NOTE: if there is no match - the process does not changes the context, simply slides along the string.
      --  So it isbe more effective to pass the context as the first argument.
      --  And moreover, the `passOneCharNgo` passively passes the context, to context can be removed from it and inherited directly.
      --  Then the solution would've been elegant, but the Nix bug prevents elegant implementation.
      go :: HashSet StringContext -> Text -> Builder -> NixString
go HashSet StringContext
ctx Text
input Builder
output =
        NixString
-> ((Text, NixString, Text) -> NixString)
-> Maybe (Text, NixString, Text)
-> NixString
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
            -- Passively pass the chars
          NixString
passOneChar
          (Text, NixString, Text) -> NixString
replace
          Maybe (Text, NixString, Text)
maybePrefixMatch

       where
        -- When prefix matched something - returns (match, replacement, reminder)
        maybePrefixMatch :: Maybe (Text, NixString, Text)
        maybePrefixMatch :: Maybe (Text, NixString, Text)
maybePrefixMatch = (Text, NixString) -> (Text, NixString, Text)
formMatchReplaceTailInfo ((Text, NixString) -> (Text, NixString, Text))
-> Maybe (Text, NixString) -> Maybe (Text, NixString, Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Text, NixString) -> Bool)
-> [(Text, NixString)] -> Maybe (Text, NixString)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find ((Text -> Text -> Bool
`Text.isPrefixOf` Text
input) (Text -> Bool)
-> ((Text, NixString) -> Text) -> (Text, NixString) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text, NixString) -> Text
forall a b. (a, b) -> a
fst) [(Text, NixString)]
fromKeysToValsMap
         where
          formMatchReplaceTailInfo :: (Text, NixString) -> (Text, NixString, Text)
formMatchReplaceTailInfo = (\(Text
m, NixString
r) -> (Text
m, NixString
r, Int -> Text -> Text
Text.drop (Text -> Int
Text.length Text
m) Text
input))

          fromKeysToValsMap :: [(Text, NixString)]
fromKeysToValsMap = [Text] -> [NixString] -> [(Text, NixString)]
forall a b. [a] -> [b] -> [(a, b)]
zip (NixString -> Text
stringIgnoreContext (NixString -> Text) -> [NixString] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [NixString]
fromKeys) [NixString]
toVals

        -- Not passing args => It is constant that gets embedded into `go` => It is simple `go` tail recursion
        passOneChar :: NixString
passOneChar =
          NixString
-> ((Char, Text) -> NixString) -> Maybe (Char, Text) -> NixString
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
            (HashSet StringContext -> Builder -> NixString
finish HashSet StringContext
ctx Builder
output)  -- The base case - there is no chars left to process -> finish
            (\(Char
c, Text
i) -> HashSet StringContext -> Text -> Builder -> NixString
go HashSet StringContext
ctx Text
i (Builder
output Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Char -> Builder
Builder.singleton Char
c)) -- If there are chars - pass one char & continue
            (Text -> Maybe (Char, Text)
Text.uncons Text
input)  -- chip first char

        --  2021-02-18: NOTE: rly?: toStrict . toLazyText
        --  Maybe `text-builder`, `text-show`?
        finish :: HashSet StringContext -> Builder -> NixString
finish HashSet StringContext
ctx Builder
output = Text -> HashSet StringContext -> NixString
makeNixString (Text -> Text
LazyText.toStrict (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Builder -> Text
Builder.toLazyText Builder
output) HashSet StringContext
ctx

        replace :: (Text, NixString, Text) -> NixString
replace (Text
key, NixString
replacementNS, Text
unprocessedInput) = Text -> Builder -> NixString
replaceWithNixBug Text
unprocessedInput Builder
updatedOutput

         where
          replaceWithNixBug :: Text -> Builder -> NixString
replaceWithNixBug =
            (Text -> Builder -> NixString)
-> (Text -> Builder -> NixString)
-> Bool
-> Text
-> Builder
-> NixString
forall a. a -> a -> Bool -> a
bool
              (HashSet StringContext -> Text -> Builder -> NixString
go HashSet StringContext
updatedCtx)  -- tail recursion
              -- Allowing match on "" is a inherited bug of Nix,
              -- when "" is checked - it always matches. And so - when it checks - it always insers a replacement, and then process simply passesthrough the char that was under match.
              --
              -- repl> builtins.replaceStrings ["" "e"] [" " "i"] "Hello world"
              -- " H e l l o   w o r l d "
              -- repl> builtins.replaceStrings ["ll" ""] [" " "i"] "Hello world"
              -- "iHie ioi iwioirilidi"
              --  2021-02-18: NOTE: There is no tests for this
              Text -> Builder -> NixString
bugPassOneChar  -- augmented recursion
              Bool
isNixBugCase

          isNixBugCase :: Bool
isNixBugCase = Text
key Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
forall a. Monoid a => a
mempty

          updatedOutput :: Builder
updatedOutput  = Builder
output Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
replacement
          updatedCtx :: HashSet StringContext
updatedCtx     = HashSet StringContext
ctx HashSet StringContext
-> HashSet StringContext -> HashSet StringContext
forall a. Semigroup a => a -> a -> a
<> HashSet StringContext
replacementCtx

          replacement :: Builder
replacement    = Text -> Builder
Builder.fromText (Text -> Builder) -> Text -> Builder
forall a b. (a -> b) -> a -> b
$ NixString -> Text
stringIgnoreContext NixString
replacementNS
          replacementCtx :: HashSet StringContext
replacementCtx = NixString -> HashSet StringContext
getContext NixString
replacementNS

          -- The bug modifies the content => bug demands `pass` to be a real function =>
          -- `go` calls `pass` function && `pass` calls `go` function
          -- => mutual recusion case, so placed separately.
          bugPassOneChar :: Text -> Builder -> NixString
bugPassOneChar Text
input Builder
output =
            NixString
-> ((Char, Text) -> NixString) -> Maybe (Char, Text) -> NixString
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
              (HashSet StringContext -> Builder -> NixString
finish HashSet StringContext
updatedCtx Builder
output)  -- The base case - there is no chars left to process -> finish
              (\(Char
c, Text
i) -> HashSet StringContext -> Text -> Builder -> NixString
go HashSet StringContext
updatedCtx Text
i (Builder
output Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Char -> Builder
Builder.singleton Char
c)) -- If there are chars - pass one char & continue
              (Text -> Maybe (Char, Text)
Text.uncons Text
input)  -- chip first char

    NixString -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (NixString -> m (NValue t f m)) -> NixString -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ HashSet StringContext -> Text -> Builder -> NixString
go (NixString -> HashSet StringContext
getContext NixString
string) (NixString -> Text
stringIgnoreContext NixString
string) Builder
forall a. Monoid a => a
mempty

removeAttrsNix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
removeAttrsNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
removeAttrsNix NValue t f m
set NValue t f m
v =
  do
    (AttrSet (NValue t f m)
m, HashMap Text SourcePos
p) <- NValue t f m -> m (AttrSet (NValue t f m), HashMap Text SourcePos)
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @(AttrSet (NValue t f m), AttrSet SourcePos) NValue t f m
set
    ([NixString]
nsToRemove :: [NixString]) <- Deeper (NValue t f m) -> m [NixString]
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue (Deeper (NValue t f m) -> m [NixString])
-> Deeper (NValue t f m) -> m [NixString]
forall a b. (a -> b) -> a -> b
$ NValue t f m -> Deeper (NValue t f m)
forall a. a -> Deeper a
Deeper NValue t f m
v
    [Text]
toRemove <- (NixString -> m Text) -> [NixString] -> m [Text]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse NixString -> m Text
forall e (m :: * -> *). Framed e m => NixString -> m Text
fromStringNoContext [NixString]
nsToRemove
    (AttrSet (NValue t f m), HashMap Text SourcePos)
-> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (AttrSet (NValue t f m) -> [Text] -> AttrSet (NValue t f m)
forall v. HashMap Text v -> [Text] -> HashMap Text v
go AttrSet (NValue t f m)
m [Text]
toRemove, HashMap Text SourcePos -> [Text] -> HashMap Text SourcePos
forall v. HashMap Text v -> [Text] -> HashMap Text v
go HashMap Text SourcePos
p [Text]
toRemove)
 where
  go :: HashMap Text v -> [Text] -> HashMap Text v
go = (HashMap Text v -> Text -> HashMap Text v)
-> HashMap Text v -> [Text] -> HashMap Text v
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' ((Text -> HashMap Text v -> HashMap Text v)
-> HashMap Text v -> Text -> HashMap Text v
forall a b c. (a -> b -> c) -> b -> a -> c
flip Text -> HashMap Text v -> HashMap Text v
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> HashMap k v
M.delete)

intersectAttrsNix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
intersectAttrsNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
intersectAttrsNix NValue t f m
set1 NValue t f m
set2 =
  do
    (AttrSet (NValue t f m)
s1, HashMap Text SourcePos
p1) <- NValue t f m -> m (AttrSet (NValue t f m), HashMap Text SourcePos)
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @(AttrSet (NValue t f m), AttrSet SourcePos) NValue t f m
set1
    (AttrSet (NValue t f m)
s2, HashMap Text SourcePos
p2) <- NValue t f m -> m (AttrSet (NValue t f m), HashMap Text SourcePos)
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @(AttrSet (NValue t f m), AttrSet SourcePos) NValue t f m
set2

    NValue t f m -> m (NValue t f m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NValue t f m -> m (NValue t f m))
-> NValue t f m -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ HashMap Text SourcePos -> AttrSet (NValue t f m) -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
HashMap Text SourcePos
-> HashMap Text (NValue t f m) -> NValue t f m
nvSet (HashMap Text SourcePos
p2 HashMap Text SourcePos
-> HashMap Text SourcePos -> HashMap Text SourcePos
forall k v w.
(Eq k, Hashable k) =>
HashMap k v -> HashMap k w -> HashMap k v
`M.intersection` HashMap Text SourcePos
p1) (AttrSet (NValue t f m)
s2 AttrSet (NValue t f m)
-> AttrSet (NValue t f m) -> AttrSet (NValue t f m)
forall k v w.
(Eq k, Hashable k) =>
HashMap k v -> HashMap k w -> HashMap k v
`M.intersection` AttrSet (NValue t f m)
s1)

functionArgsNix
  :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
functionArgsNix :: NValue t f m -> m (NValue t f m)
functionArgsNix NValue t f m
nvfun =
  do
    NValue t f m
fun <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nvfun
    case NValue t f m
fun of
      NVClosure Params ()
p NValue t f m -> m (NValue t f m)
_ ->
        forall a (m :: * -> *) v. ToValue a m v => a -> m v
forall (m :: * -> *) v.
ToValue (AttrSet (NValue t f m)) m v =>
AttrSet (NValue t f m) -> m v
toValue @(AttrSet (NValue t f m)) (AttrSet (NValue t f m) -> m (NValue t f m))
-> AttrSet (NValue t f m) -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ Bool -> NValue t f m
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
Bool -> NValue t f m
mkNVBool (Bool -> NValue t f m)
-> HashMap Text Bool -> AttrSet (NValue t f m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
          case Params ()
p of
            Param Text
name     -> Text -> Bool -> HashMap Text Bool
forall k v. Hashable k => k -> v -> HashMap k v
M.singleton Text
name Bool
False
            ParamSet ParamSet ()
s Bool
_ Maybe Text
_ -> Maybe () -> Bool
forall a. Maybe a -> Bool
isJust (Maybe () -> Bool) -> HashMap Text (Maybe ()) -> HashMap Text Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParamSet () -> HashMap Text (Maybe ())
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
M.fromList ParamSet ()
s
      NValue t f m
_v -> ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"builtins.functionArgs: expected function, got " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> NValue t f m -> FilePath
forall b a. (Show a, IsString b) => a -> b
show NValue t f m
_v

toFileNix
  :: MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
toFileNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
toFileNix NValue t f m
name NValue t f m
s =
  do
    Text
name' <- NixString -> m Text
forall e (m :: * -> *). Framed e m => NixString -> m Text
fromStringNoContext (NixString -> m Text) -> m NixString -> m Text
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m NixString
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
name
    NixString
s'    <- NValue t f m -> m NixString
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
s
    StorePath
mres  <-
      FilePath -> FilePath -> m StorePath
forall e (m :: * -> *).
(Framed e m, MonadStore m) =>
FilePath -> FilePath -> m StorePath
toFile_
        (Text -> FilePath
forall a. ToString a => a -> FilePath
toString Text
name')
        (Text -> FilePath
forall a. ToString a => a -> FilePath
toString (Text -> FilePath) -> Text -> FilePath
forall a b. (a -> b) -> a -> b
$ NixString -> Text
stringIgnoreContext NixString
s')

    let
      t :: Text
t  = FilePath -> Text
forall a. ToText a => a -> Text
toText (FilePath -> Text) -> FilePath -> Text
forall a b. (a -> b) -> a -> b
$ StorePath -> FilePath
unStorePath StorePath
mres
      sc :: StringContext
sc = Text -> ContextFlavor -> StringContext
StringContext Text
t ContextFlavor
DirectPath

    NixString -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (NixString -> m (NValue t f m)) -> NixString -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ Text -> StringContext -> NixString
makeNixStringWithSingletonContext Text
t StringContext
sc

toPathNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
toPathNix :: NValue t f m -> m (NValue t f m)
toPathNix = forall a (m :: * -> *) v. ToValue a m v => a -> m v
forall (m :: * -> *) v. ToValue Path m v => Path -> m v
toValue @Path (Path -> m (NValue t f m))
-> (NValue t f m -> m Path) -> NValue t f m -> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall a (m :: * -> *) v. FromValue a m v => v -> m a
forall (m :: * -> *) v. FromValue Path m v => v -> m Path
fromValue @Path

pathExistsNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
pathExistsNix :: NValue t f m -> m (NValue t f m)
pathExistsNix NValue t f m
nvpath =
  do
    NValue t f m
path <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nvpath
    Bool -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Bool -> m (NValue t f m)) -> m Bool -> m (NValue t f m)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
      case NValue t f m
path of
        NVPath FilePath
p  -> FilePath -> m Bool
forall (m :: * -> *). MonadFile m => FilePath -> m Bool
pathExists FilePath
p
        NVStr  NixString
ns -> FilePath -> m Bool
forall (m :: * -> *). MonadFile m => FilePath -> m Bool
pathExists (Text -> FilePath
forall a. ToString a => a -> FilePath
toString (Text -> FilePath) -> Text -> FilePath
forall a b. (a -> b) -> a -> b
$ NixString -> Text
stringIgnoreContext NixString
ns)
        NValue t f m
_v -> ErrorCall -> m Bool
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m Bool) -> ErrorCall -> m Bool
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"builtins.pathExists: expected path, got " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> NValue t f m -> FilePath
forall b a. (Show a, IsString b) => a -> b
show NValue t f m
_v

isAttrsNix
  :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
isAttrsNix :: NValue t f m -> m (NValue t f m)
isAttrsNix = forall a e t (f :: * -> *) (m :: * -> *).
(MonadNix e t f m, FromValue a m (NValue t f m)) =>
NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
(MonadNix e t f m,
 FromValue (AttrSet (NValue t f m)) m (NValue t f m)) =>
NValue t f m -> m (NValue t f m)
hasKind @(AttrSet (NValue t f m))

isListNix
  :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
isListNix :: NValue t f m -> m (NValue t f m)
isListNix = forall a e t (f :: * -> *) (m :: * -> *).
(MonadNix e t f m, FromValue a m (NValue t f m)) =>
NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
(MonadNix e t f m, FromValue [NValue t f m] m (NValue t f m)) =>
NValue t f m -> m (NValue t f m)
hasKind @[NValue t f m]

isIntNix
  :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
isIntNix :: NValue t f m -> m (NValue t f m)
isIntNix = forall a e t (f :: * -> *) (m :: * -> *).
(MonadNix e t f m, FromValue a m (NValue t f m)) =>
NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
(MonadNix e t f m, FromValue Int m (NValue t f m)) =>
NValue t f m -> m (NValue t f m)
hasKind @Int

isFloatNix
  :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
isFloatNix :: NValue t f m -> m (NValue t f m)
isFloatNix = forall a e t (f :: * -> *) (m :: * -> *).
(MonadNix e t f m, FromValue a m (NValue t f m)) =>
NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
(MonadNix e t f m, FromValue Float m (NValue t f m)) =>
NValue t f m -> m (NValue t f m)
hasKind @Float

isBoolNix
  :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
isBoolNix :: NValue t f m -> m (NValue t f m)
isBoolNix = forall a e t (f :: * -> *) (m :: * -> *).
(MonadNix e t f m, FromValue a m (NValue t f m)) =>
NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
(MonadNix e t f m, FromValue Bool m (NValue t f m)) =>
NValue t f m -> m (NValue t f m)
hasKind @Bool

isNullNix
  :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
isNullNix :: NValue t f m -> m (NValue t f m)
isNullNix = forall a e t (f :: * -> *) (m :: * -> *).
(MonadNix e t f m, FromValue a m (NValue t f m)) =>
NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
(MonadNix e t f m, FromValue () m (NValue t f m)) =>
NValue t f m -> m (NValue t f m)
hasKind @()

-- isString cannot use `hasKind` because it coerces derivationNixs to strings.
isStringNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
isStringNix :: NValue t f m -> m (NValue t f m)
isStringNix NValue t f m
nv =
  do
    NValue t f m
v <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nv

    Bool -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Bool -> m (NValue t f m)) -> Bool -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$
      case NValue t f m
v of
        NVStr{} -> Bool
True
        NValue t f m
_       -> Bool
False

isFunctionNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
isFunctionNix :: NValue t f m -> m (NValue t f m)
isFunctionNix NValue t f m
nv =
  do
    NValue t f m
v <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nv

    Bool -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (Bool -> m (NValue t f m)) -> Bool -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$
      case NValue t f m
v of
        NVClosure{} -> Bool
True
        NValue t f m
_           -> Bool
False

throwNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
throwNix :: NValue t f m -> m (NValue t f m)
throwNix NValue t f m
mnv =
  do
    NixString
ns <- (NValue t f m -> NValue t f m -> m (NValue t f m))
-> CopyToStoreMode -> CoercionLevel -> NValue t f m -> m NixString
forall e (m :: * -> *) t (f :: * -> *).
(Framed e m, MonadStore m, MonadThrow m,
 MonadDataErrorContext t f m, MonadValue (NValue t f m) m) =>
(NValue t f m -> NValue t f m -> m (NValue t f m))
-> CopyToStoreMode -> CoercionLevel -> NValue t f m -> m NixString
coerceToString NValue t f m -> NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> NValue t f m -> m (NValue t f m)
callFunc CopyToStoreMode
CopyToStore CoercionLevel
CoerceStringy NValue t f m
mnv

    ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m))
-> (Text -> ErrorCall) -> Text -> m (NValue t f m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> (Text -> FilePath) -> Text -> ErrorCall
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> FilePath
forall a. ToString a => a -> FilePath
toString (Text -> m (NValue t f m)) -> Text -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ NixString -> Text
stringIgnoreContext NixString
ns

importNix
  :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
importNix :: NValue t f m -> m (NValue t f m)
importNix = NValue t f m -> NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> NValue t f m -> m (NValue t f m)
scopedImportNix (HashMap Text SourcePos
-> HashMap Text (NValue t f m) -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
HashMap Text SourcePos
-> HashMap Text (NValue t f m) -> NValue t f m
nvSet HashMap Text SourcePos
forall a. Monoid a => a
mempty HashMap Text (NValue t f m)
forall a. Monoid a => a
mempty)

scopedImportNix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
scopedImportNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
scopedImportNix NValue t f m
asetArg NValue t f m
pathArg =
  do
    AttrSet (NValue t f m)
s        <- NValue t f m -> m (AttrSet (NValue t f m))
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @(AttrSet (NValue t f m)) NValue t f m
asetArg
    (Path FilePath
p) <- NValue t f m -> m Path
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
pathArg

    FilePath
path  <- FilePath -> m FilePath
forall t (f :: * -> *) (m :: * -> *).
MonadEffects t f m =>
FilePath -> m FilePath
pathToDefaultNix @t @f @m FilePath
p
    FilePath
path' <-
      m FilePath
-> (NValue t f m -> m FilePath)
-> Maybe (NValue t f m)
-> m FilePath
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
        (do
          FilePath -> m ()
forall (m :: * -> *). Monad m => FilePath -> m ()
traceM FilePath
"No known current directory"
          pure FilePath
path
        )
        (\ NValue t f m
res ->
          do
            (Path FilePath
p') <- NValue t f m -> m Path
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue (NValue t f m -> m Path) -> m (NValue t f m) -> m Path
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
res

            FilePath -> m ()
forall (m :: * -> *). Monad m => FilePath -> m ()
traceM (FilePath -> m ()) -> FilePath -> m ()
forall a b. (a -> b) -> a -> b
$ FilePath
"Current file being evaluated is: " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath -> FilePath
forall b a. (Show a, IsString b) => a -> b
show FilePath
p'
            pure $ FilePath -> FilePath
takeDirectory FilePath
p' FilePath -> FilePath -> FilePath
</> FilePath
path
        )
        (Maybe (NValue t f m) -> m FilePath)
-> m (Maybe (NValue t f m)) -> m FilePath
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Text -> m (Maybe (NValue t f m))
forall a (m :: * -> *). Scoped a m => Text -> m (Maybe a)
lookupVar Text
"__cur_file"

    forall a (m :: * -> *) r. Scoped a m => m r -> m r
forall (m :: * -> *) r. Scoped (NValue t f m) m => m r -> m r
clearScopes @(NValue t f m)
      (m (NValue t f m) -> m (NValue t f m))
-> m (NValue t f m) -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ Maybe FilePath -> m (NValue t f m) -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *) r.
(MonadNix e t f m, Has e Options) =>
Maybe FilePath -> m r -> m r
withNixContext (FilePath -> Maybe FilePath
forall (f :: * -> *) a. Applicative f => a -> f a
pure FilePath
path')
      (m (NValue t f m) -> m (NValue t f m))
-> m (NValue t f m) -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ AttrSet (NValue t f m) -> m (NValue t f m) -> m (NValue t f m)
forall a (m :: * -> *) r. Scoped a m => AttrSet a -> m r -> m r
pushScope AttrSet (NValue t f m)
s
      (m (NValue t f m) -> m (NValue t f m))
-> m (NValue t f m) -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> m (NValue t f m)
forall t (f :: * -> *) (m :: * -> *).
MonadEffects t f m =>
FilePath -> m (NValue t f m)
importPath @t @f @m FilePath
path'

getEnvNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
getEnvNix :: NValue t f m -> m (NValue t f m)
getEnvNix NValue t f m
v =
  do
    Text
s <- NixString -> m Text
forall e (m :: * -> *). Framed e m => NixString -> m Text
fromStringNoContext (NixString -> m Text) -> m NixString -> m Text
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m NixString
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
v
    Maybe Text
mres <- Text -> m (Maybe Text)
forall (m :: * -> *). MonadEnv m => Text -> m (Maybe Text)
getEnvVar Text
s

    NixString -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (NixString -> m (NValue t f m)) -> NixString -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ Text -> NixString
makeNixStringWithoutContext (Text -> NixString) -> Text -> NixString
forall a b. (a -> b) -> a -> b
$
      Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe Text
forall a. Monoid a => a
mempty Maybe Text
mres

sortNix
  :: MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
sortNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
sortNix NValue t f m
comp = [NValue t f m] -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue ([NValue t f m] -> m (NValue t f m))
-> (NValue t f m -> m [NValue t f m])
-> NValue t f m
-> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< (NValue t f m -> NValue t f m -> m Ordering)
-> [NValue t f m] -> m [NValue t f m]
forall (m :: * -> *) a.
Monad m =>
(a -> a -> m Ordering) -> [a] -> m [a]
sortByM (NValue t f m -> NValue t f m -> NValue t f m -> m Ordering
forall e (m :: * -> *) t (f :: * -> *).
(MonadReader e m, MonadValue (NValue t f m) m,
 HasCitations1 m (NValue t f m) f, HasCitations m (NValue t f m) t,
 Traversable f, Comonad f, MonadThunk t m (NValue t f m),
 MonadEffects t f m, Alternative m, MonadCatch m, MonadFix m,
 Scoped (NValue t f m) m, Has e Frames, Has e Options,
 Has e SrcSpan, Applicative f, Show t, Typeable f, Typeable m,
 Typeable t) =>
NValue t f m -> NValue t f m -> NValue t f m -> m Ordering
cmp NValue t f m
comp) ([NValue t f m] -> m [NValue t f m])
-> (NValue t f m -> m [NValue t f m])
-> NValue t f m
-> m [NValue t f m]
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> m [NValue t f m]
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue
 where
  cmp :: NValue t f m -> NValue t f m -> NValue t f m -> m Ordering
cmp NValue t f m
f NValue t f m
a NValue t f m
b =
    do
      NValue t f m
isLessThan <- (NValue t f m -> NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> NValue t f m -> m (NValue t f m)
`callFunc` NValue t f m
b) (NValue t f m -> m (NValue t f m))
-> m (NValue t f m) -> m (NValue t f m)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> NValue t f m -> m (NValue t f m)
callFunc NValue t f m
f NValue t f m
a
      m Ordering -> m Ordering -> Bool -> m Ordering
forall a. a -> a -> Bool -> a
bool
        (do
          NValue t f m
isGreaterThan <- (NValue t f m -> NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> NValue t f m -> m (NValue t f m)
`callFunc` NValue t f m
a) (NValue t f m -> m (NValue t f m))
-> m (NValue t f m) -> m (NValue t f m)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> NValue t f m -> m (NValue t f m)
callFunc NValue t f m
f NValue t f m
b
          NValue t f m -> m Bool
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
isGreaterThan m Bool -> (Bool -> Ordering) -> m Ordering
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&>
            Ordering -> Ordering -> Bool -> Ordering
forall a. a -> a -> Bool -> a
bool
              Ordering
EQ
              Ordering
GT
        )
        (Ordering -> m Ordering
forall (f :: * -> *) a. Applicative f => a -> f a
pure Ordering
LT)
        (Bool -> m Ordering) -> m Bool -> m Ordering
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m Bool
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
isLessThan

lessThanNix
  :: MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
lessThanNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
lessThanNix NValue t f m
ta NValue t f m
tb =
  do
    NValue t f m
va <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
ta
    NValue t f m
vb <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
tb

    let
      badType :: m Bool
badType = ErrorCall -> m Bool
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m Bool) -> ErrorCall -> m Bool
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"builtins.lessThan: expected two numbers or two strings, " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
"got " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> NValue t f m -> FilePath
forall b a. (Show a, IsString b) => a -> b
show NValue t f m
va FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
" and " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> NValue t f m -> FilePath
forall b a. (Show a, IsString b) => a -> b
show NValue t f m
vb

    Bool -> NValue t f m
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
Bool -> NValue t f m
mkNVBool (Bool -> NValue t f m) -> m Bool -> m (NValue t f m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
      case (NValue t f m
va, NValue t f m
vb) of
        (NVConstant NAtom
ca, NVConstant NAtom
cb) ->
          case (NAtom
ca, NAtom
cb) of
            (NInt   Integer
a, NInt Integer
b  ) -> Bool -> m Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> m Bool) -> Bool -> m Bool
forall a b. (a -> b) -> a -> b
$             Integer
a Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
b
            (NFloat Float
a, NInt Integer
b  ) -> Bool -> m Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> m Bool) -> Bool -> m Bool
forall a b. (a -> b) -> a -> b
$             Float
a Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
< Integer -> Float
forall a. Num a => Integer -> a
fromInteger Integer
b
            (NInt   Integer
a, NFloat Float
b) -> Bool -> m Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> m Bool) -> Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ Integer -> Float
forall a. Num a => Integer -> a
fromInteger Integer
a Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
< Float
b
            (NFloat Float
a, NFloat Float
b) -> Bool -> m Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> m Bool) -> Bool -> m Bool
forall a b. (a -> b) -> a -> b
$             Float
a Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
< Float
b
            (NAtom, NAtom)
_                    -> m Bool
badType
        (NVStr NixString
a, NVStr NixString
b) -> Bool -> m Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> m Bool) -> Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ NixString -> Text
stringIgnoreContext NixString
a Text -> Text -> Bool
forall a. Ord a => a -> a -> Bool
< NixString -> Text
stringIgnoreContext NixString
b
        (NValue t f m, NValue t f m)
_ -> m Bool
badType

concatListsNix
  :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
concatListsNix :: NValue t f m -> m (NValue t f m)
concatListsNix =
  [NValue t f m] -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue ([NValue t f m] -> m (NValue t f m))
-> ([[NValue t f m]] -> [NValue t f m])
-> [[NValue t f m]]
-> m (NValue t f m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[NValue t f m]] -> [NValue t f m]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[NValue t f m]] -> m (NValue t f m))
-> (NValue t f m -> m [[NValue t f m]])
-> NValue t f m
-> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
    (NValue t f m -> m [NValue t f m])
-> [NValue t f m] -> m [[NValue t f m]]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse
      (forall a (m :: * -> *) v. FromValue a m v => v -> m a
forall (m :: * -> *) v.
FromValue [NValue t f m] m v =>
v -> m [NValue t f m]
fromValue @[NValue t f m] (NValue t f m -> m [NValue t f m])
-> (NValue t f m -> m (NValue t f m))
-> NValue t f m
-> m [NValue t f m]
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand)
      ([NValue t f m] -> m [[NValue t f m]])
-> (NValue t f m -> m [NValue t f m])
-> NValue t f m
-> m [[NValue t f m]]
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall a (m :: * -> *) v. FromValue a m v => v -> m a
forall (m :: * -> *) v.
FromValue [NValue t f m] m v =>
v -> m [NValue t f m]
fromValue @[NValue t f m]

concatMapNix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
concatMapNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
concatMapNix NValue t f m
f =
  [NValue t f m] -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue ([NValue t f m] -> m (NValue t f m))
-> ([[NValue t f m]] -> [NValue t f m])
-> [[NValue t f m]]
-> m (NValue t f m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[NValue t f m]] -> [NValue t f m]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[NValue t f m]] -> m (NValue t f m))
-> (NValue t f m -> m [[NValue t f m]])
-> NValue t f m
-> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
    (NValue t f m -> m [NValue t f m])
-> [NValue t f m] -> m [[NValue t f m]]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse
      NValue t f m -> m [NValue t f m]
applyFunc
      ([NValue t f m] -> m [[NValue t f m]])
-> (NValue t f m -> m [NValue t f m])
-> NValue t f m
-> m [[NValue t f m]]
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall a (m :: * -> *) v. FromValue a m v => v -> m a
forall (m :: * -> *) v.
FromValue [NValue t f m] m v =>
v -> m [NValue t f m]
fromValue @[NValue t f m]
 where
  applyFunc :: NValue t f m  -> m [NValue t f m]
  applyFunc :: NValue t f m -> m [NValue t f m]
applyFunc =  NValue t f m -> m [NValue t f m]
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue (NValue t f m -> m [NValue t f m])
-> (NValue t f m -> m (NValue t f m))
-> NValue t f m
-> m [NValue t f m]
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> NValue t f m -> m (NValue t f m)
callFunc NValue t f m
f

listToAttrsNix
  :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
listToAttrsNix :: NValue t f m -> m (NValue t f m)
listToAttrsNix NValue t f m
lst =
  do
    [NValue t f m]
l <- NValue t f m -> m [NValue t f m]
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @[NValue t f m] NValue t f m
lst
    ([(Text, NValue t f m)] -> NValue t f m)
-> m [(Text, NValue t f m)] -> m (NValue t f m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
      (HashMap Text SourcePos
-> HashMap Text (NValue t f m) -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
HashMap Text SourcePos
-> HashMap Text (NValue t f m) -> NValue t f m
nvSet HashMap Text SourcePos
forall a. Monoid a => a
mempty (HashMap Text (NValue t f m) -> NValue t f m)
-> ([(Text, NValue t f m)] -> HashMap Text (NValue t f m))
-> [(Text, NValue t f m)]
-> NValue t f m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Text, NValue t f m)] -> HashMap Text (NValue t f m)
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
M.fromList ([(Text, NValue t f m)] -> HashMap Text (NValue t f m))
-> ([(Text, NValue t f m)] -> [(Text, NValue t f m)])
-> [(Text, NValue t f m)]
-> HashMap Text (NValue t f m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Text, NValue t f m)] -> [(Text, NValue t f m)]
forall a. [a] -> [a]
reverse)
      ((NValue t f m -> m (Text, NValue t f m))
-> [NValue t f m] -> m [(Text, NValue t f m)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse
        (\ NValue t f m
nvattrset ->
          do
            HashMap Text (NValue t f m)
a <- forall a (m :: * -> *) v. FromValue a m v => v -> m a
forall (m :: * -> *) v.
FromValue (HashMap Text (NValue t f m)) m v =>
v -> m (HashMap Text (NValue t f m))
fromValue @(AttrSet (NValue t f m)) (NValue t f m -> m (HashMap Text (NValue t f m)))
-> m (NValue t f m) -> m (HashMap Text (NValue t f m))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nvattrset
            Text
name <- NixString -> m Text
forall e (m :: * -> *). Framed e m => NixString -> m Text
fromStringNoContext (NixString -> m Text) -> m NixString -> m Text
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m NixString
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue (NValue t f m -> m NixString) -> m (NValue t f m) -> m NixString
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand (NValue t f m -> m (NValue t f m))
-> m (NValue t f m) -> m (NValue t f m)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Text -> HashMap Text (NValue t f m) -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
Text -> AttrSet (NValue t f m) -> m (NValue t f m)
attrsetGet Text
"name" HashMap Text (NValue t f m)
a
            NValue t f m
val  <- Text -> HashMap Text (NValue t f m) -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
Text -> AttrSet (NValue t f m) -> m (NValue t f m)
attrsetGet Text
"value" HashMap Text (NValue t f m)
a

            pure (Text
name, NValue t f m
val)
        )
        [NValue t f m]
l
      )

-- prim_hashString from nix/src/libexpr/primops.cc
-- fail if context in the algo arg
-- propagate context from the s arg
-- | The result coming out of hashString is base16 encoded
hashStringNix
  :: forall e t f m. MonadNix e t f m => NixString -> NixString -> Prim m NixString
hashStringNix :: NixString -> NixString -> Prim m NixString
hashStringNix NixString
nsAlgo NixString
ns =
  m NixString -> Prim m NixString
forall (m :: * -> *) a. m a -> Prim m a
Prim (m NixString -> Prim m NixString)
-> m NixString -> Prim m NixString
forall a b. (a -> b) -> a -> b
$
    do
      Text
algo <- NixString -> m Text
forall e (m :: * -> *). Framed e m => NixString -> m Text
fromStringNoContext NixString
nsAlgo
      let
        f :: (Text -> Text) -> m NixString
f Text -> Text
g = NixString -> m NixString
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NixString -> m NixString) -> NixString -> m NixString
forall a b. (a -> b) -> a -> b
$ (Text -> Text) -> NixString -> NixString
modifyNixContents Text -> Text
g NixString
ns

      case Text
algo of
        --  2021-03-04: Pattern can not be taken-out because hashes represented as different types
        Text
"md5"    -> (Text -> Text) -> m NixString
f (MD5 -> Text
forall b a. (Show a, IsString b) => a -> b
show (MD5 -> Text) -> (Text -> MD5) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Show MD5, HashAlgorithm MD5) => Text -> MD5
forall a. (Show a, HashAlgorithm a) => Text -> a
mkHash @MD5.MD5)
        Text
"sha1"   -> (Text -> Text) -> m NixString
f (SHA1 -> Text
forall b a. (Show a, IsString b) => a -> b
show (SHA1 -> Text) -> (Text -> SHA1) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Show SHA1, HashAlgorithm SHA1) => Text -> SHA1
forall a. (Show a, HashAlgorithm a) => Text -> a
mkHash @SHA1.SHA1)
        Text
"sha256" -> (Text -> Text) -> m NixString
f (SHA256 -> Text
forall b a. (Show a, IsString b) => a -> b
show (SHA256 -> Text) -> (Text -> SHA256) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Show SHA256, HashAlgorithm SHA256) => Text -> SHA256
forall a. (Show a, HashAlgorithm a) => Text -> a
mkHash @SHA256.SHA256)
        Text
"sha512" -> (Text -> Text) -> m NixString
f (SHA512 -> Text
forall b a. (Show a, IsString b) => a -> b
show (SHA512 -> Text) -> (Text -> SHA512) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Show SHA512, HashAlgorithm SHA512) => Text -> SHA512
forall a. (Show a, HashAlgorithm a) => Text -> a
mkHash @SHA512.SHA512)

        Text
_ -> ErrorCall -> m NixString
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m NixString) -> ErrorCall -> m NixString
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"builtins.hashString: expected \"md5\", \"sha1\", \"sha256\", or \"sha512\", got " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> Text -> FilePath
forall b a. (Show a, IsString b) => a -> b
show Text
algo

       where
        -- This intermidiary `a` is only needed because of the type application
        mkHash :: (Show a, HashAlgorithm a) => Text -> a
        mkHash :: Text -> a
mkHash Text
s = ByteString -> a
forall a. HashAlgorithm a => ByteString -> a
hash (Text -> ByteString
forall a b. ConvertUtf8 a b => a -> b
encodeUtf8 Text
s)


placeHolderNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
placeHolderNix :: NValue t f m -> m (NValue t f m)
placeHolderNix NValue t f m
p =
  do
    Text
t <- NixString -> m Text
forall e (m :: * -> *). Framed e m => NixString -> m Text
fromStringNoContext (NixString -> m Text) -> m NixString -> m Text
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m NixString
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
p
    NixString
h <-
      Prim m NixString -> m NixString
forall (m :: * -> *) a. Prim m a -> m a
runPrim
        (NixString -> NixString -> Prim m NixString
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NixString -> NixString -> Prim m NixString
hashStringNix
          (Text -> NixString
makeNixStringWithoutContext Text
"sha256"           )
          (Text -> NixString
makeNixStringWithoutContext (Text
"nix-output:" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
t))
        )
    NixString -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue
      (NixString -> m (NValue t f m)) -> NixString -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ Text -> NixString
makeNixStringWithoutContext
      (Text -> NixString) -> Text -> NixString
forall a b. (a -> b) -> a -> b
$ Char -> Text -> Text
Text.cons Char
'/'
      (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ ByteString -> Text
Base32.encode
      -- Please, stop Text -> Bytestring here after migration to Text
      (ByteString -> Text) -> ByteString -> Text
forall a b. (a -> b) -> a -> b
$ case ByteString -> Either FilePath ByteString
Base16.decode (NixString -> ByteString
bytes NixString
h) of -- The result coming out of hashString is base16 encoded
#if MIN_VERSION_base16_bytestring(1,0,0)
        -- Please, stop Text -> String here after migration to Text
        Left FilePath
e -> Text -> ByteString
forall a t. (HasCallStack, IsText t) => t -> a
error (Text -> ByteString) -> Text -> ByteString
forall a b. (a -> b) -> a -> b
$ Text
"Couldn't Base16 decode the text: '" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> NixString -> Text
body NixString
h Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"'.\nThe Left fail content: '" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> FilePath -> Text
forall b a. (Show a, IsString b) => a -> b
show FilePath
e Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"'."
        Right ByteString
d -> ByteString
d
#else
        (d, "") -> d
        (_, e) -> error $ "Couldn't Base16 decode the text: '" <> body h <> "'.\nUndecodable remainder: '" <> show e <> "'."
#endif
    where
      bytes :: NixString -> ByteString
      bytes :: NixString -> ByteString
bytes = Text -> ByteString
forall a b. ConvertUtf8 a b => a -> b
encodeUtf8 (Text -> ByteString)
-> (NixString -> Text) -> NixString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NixString -> Text
body

      body :: NixString -> Text
body NixString
h = NixString -> Text
stringIgnoreContext NixString
h

readFileNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
readFileNix :: NValue t f m -> m (NValue t f m)
readFileNix = ByteString -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (ByteString -> m (NValue t f m))
-> (NValue t f m -> m ByteString)
-> NValue t f m
-> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< FilePath -> m ByteString
forall (m :: * -> *). MonadFile m => FilePath -> m ByteString
Nix.Render.readFile (FilePath -> m ByteString)
-> (NValue t f m -> m FilePath) -> NValue t f m -> m ByteString
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> m FilePath
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> m FilePath
absolutePathFromValue (NValue t f m -> m FilePath)
-> (NValue t f m -> m (NValue t f m)) -> NValue t f m -> m FilePath
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand

findFileNix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
findFileNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
findFileNix NValue t f m
nvaset NValue t f m
nvfilepath =
  do
    NValue t f m
aset <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nvaset
    NValue t f m
filePath <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nvfilepath

    case (NValue t f m
aset, NValue t f m
filePath) of
      (NVList [NValue t f m]
x, NVStr NixString
ns) ->
        do
          FilePath
mres <- [NValue t f m] -> FilePath -> m FilePath
forall t (f :: * -> *) (m :: * -> *).
MonadEffects t f m =>
[NValue t f m] -> FilePath -> m FilePath
findPath @t @f @m [NValue t f m]
x (Text -> FilePath
forall a. ToString a => a -> FilePath
toString (NixString -> Text
stringIgnoreContext NixString
ns))

          pure $ FilePath -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
FilePath -> NValue t f m
nvPath FilePath
mres

      (NVList [NValue t f m]
_, NValue t f m
_y     ) -> ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"expected a string, got " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> NValue t f m -> FilePath
forall b a. (Show a, IsString b) => a -> b
show NValue t f m
_y
      (NValue t f m
_x      , NVStr NixString
_) -> ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"expected a list, got " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> NValue t f m -> FilePath
forall b a. (Show a, IsString b) => a -> b
show NValue t f m
_x
      (NValue t f m
_x      , NValue t f m
_y     ) -> ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"Invalid types for builtins.findFile: " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> (NValue t f m, NValue t f m) -> FilePath
forall b a. (Show a, IsString b) => a -> b
show (NValue t f m
_x, NValue t f m
_y)

readDirNix
  :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
readDirNix :: NValue t f m -> m (NValue t f m)
readDirNix NValue t f m
nvpath =
  do
    FilePath
path           <- NValue t f m -> m FilePath
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> m FilePath
absolutePathFromValue (NValue t f m -> m FilePath) -> m (NValue t f m) -> m FilePath
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nvpath
    [FilePath]
items          <- FilePath -> m [FilePath]
forall (m :: * -> *). MonadFile m => FilePath -> m [FilePath]
listDirectory FilePath
path

    let
      detectFileTypes :: FilePath -> m (Text, FileType)
detectFileTypes FilePath
item =
        do
          FileStatus
s <- FilePath -> m FileStatus
forall (m :: * -> *). MonadFile m => FilePath -> m FileStatus
getSymbolicLinkStatus (FilePath -> m FileStatus) -> FilePath -> m FileStatus
forall a b. (a -> b) -> a -> b
$ FilePath
path FilePath -> FilePath -> FilePath
</> FilePath
item
          let
            t :: FileType
t =
              if
                | FileStatus -> Bool
isRegularFile FileStatus
s  -> FileType
FileTypeRegular
                | FileStatus -> Bool
isDirectory FileStatus
s    -> FileType
FileTypeDirectory
                | FileStatus -> Bool
isSymbolicLink FileStatus
s -> FileType
FileTypeSymlink
                | Bool
otherwise        -> FileType
FileTypeUnknown

          (Text, FileType) -> m (Text, FileType)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (FilePath -> Text
forall a. ToText a => a -> Text
toText FilePath
item, FileType
t)

    [(Text, FileType)]
itemsWithTypes <-
      (FilePath -> m (Text, FileType))
-> [FilePath] -> m [(Text, FileType)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse
        FilePath -> m (Text, FileType)
detectFileTypes
        [FilePath]
items

    Deeper (NValue t f m) -> NValue t f m
forall a. Deeper a -> a
getDeeper (Deeper (NValue t f m) -> NValue t f m)
-> m (Deeper (NValue t f m)) -> m (NValue t f m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HashMap Text FileType -> m (Deeper (NValue t f m))
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue ([(Text, FileType)] -> HashMap Text FileType
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
M.fromList [(Text, FileType)]
itemsWithTypes)

fromJSONNix
  :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
fromJSONNix :: NValue t f m -> m (NValue t f m)
fromJSONNix NValue t f m
nvjson =
  do
    NValue t f m
j <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nvjson
    Text
jText <- NixString -> m Text
forall e (m :: * -> *). Framed e m => NixString -> m Text
fromStringNoContext (NixString -> m Text) -> m NixString -> m Text
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m NixString
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
j

    (FilePath -> m (NValue t f m))
-> (Value -> m (NValue t f m))
-> Either FilePath Value
-> m (NValue t f m)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
      (\ FilePath
jsonError -> ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"builtins.fromJSON: " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
jsonError)
      Value -> m (NValue t f m)
jsonToNValue
      -- do we really need to marshall Text -> ByteString -> Aeson.Value (that is a Text)
      (FromJSON Value => ByteString -> Either FilePath Value
forall a. FromJSON a => ByteString -> Either FilePath a
A.eitherDecodeStrict' @A.Value (ByteString -> Either FilePath Value)
-> ByteString -> Either FilePath Value
forall a b. (a -> b) -> a -> b
$ Text -> ByteString
forall a b. ConvertUtf8 a b => a -> b
encodeUtf8 Text
jText)

 where
  jsonToNValue :: Value -> m (NValue t f m)
jsonToNValue = \case
    A.Object Object
m -> HashMap Text SourcePos
-> HashMap Text (NValue t f m) -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
HashMap Text SourcePos
-> HashMap Text (NValue t f m) -> NValue t f m
nvSet HashMap Text SourcePos
forall a. Monoid a => a
mempty (HashMap Text (NValue t f m) -> NValue t f m)
-> m (HashMap Text (NValue t f m)) -> m (NValue t f m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Value -> m (NValue t f m))
-> Object -> m (HashMap Text (NValue t f m))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse Value -> m (NValue t f m)
jsonToNValue Object
m
    A.Array  Array
l -> [NValue t f m] -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
[NValue t f m] -> NValue t f m
nvList ([NValue t f m] -> NValue t f m)
-> m [NValue t f m] -> m (NValue t f m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Value -> m (NValue t f m)) -> [Value] -> m [NValue t f m]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse Value -> m (NValue t f m)
jsonToNValue (Array -> [Value]
forall a. Vector a -> [a]
V.toList Array
l)
    A.String Text
s -> NValue t f m -> m (NValue t f m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NValue t f m -> m (NValue t f m))
-> NValue t f m -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ NixString -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
NixString -> NValue t f m
nvStr (NixString -> NValue t f m) -> NixString -> NValue t f m
forall a b. (a -> b) -> a -> b
$ Text -> NixString
makeNixStringWithoutContext Text
s
    A.Number Scientific
n ->
      NValue t f m -> m (NValue t f m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NValue t f m -> m (NValue t f m))
-> NValue t f m -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$
        NAtom -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
NAtom -> NValue t f m
nvConstant (NAtom -> NValue t f m) -> NAtom -> NValue t f m
forall a b. (a -> b) -> a -> b
$
          (Float -> NAtom)
-> (Integer -> NAtom) -> Either Float Integer -> NAtom
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
            Float -> NAtom
NFloat
            Integer -> NAtom
NInt
            (Scientific -> Either Float Integer
forall r i. (RealFloat r, Integral i) => Scientific -> Either r i
floatingOrInteger Scientific
n)
    A.Bool   Bool
b -> NValue t f m -> m (NValue t f m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NValue t f m -> m (NValue t f m))
-> NValue t f m -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ Bool -> NValue t f m
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
Bool -> NValue t f m
mkNVBool Bool
b
    Value
A.Null     -> NValue t f m -> m (NValue t f m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure NValue t f m
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m
nVNull

toJSONNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
toJSONNix :: NValue t f m -> m (NValue t f m)
toJSONNix = ((NixString -> NValue t f m) -> m NixString -> m (NValue t f m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap NixString -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
NixString -> NValue t f m
nvStr (m NixString -> m (NValue t f m))
-> (NValue t f m -> m NixString)
-> NValue t f m
-> m (NValue t f m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NValue t f m -> m NixString
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> m NixString
nvalueToJSONNixString) (NValue t f m -> m (NValue t f m))
-> (NValue t f m -> m (NValue t f m))
-> NValue t f m
-> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand

toXMLNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
toXMLNix :: NValue t f m -> m (NValue t f m)
toXMLNix = ((NValue t f m -> NValue t f m)
-> m (NValue t f m) -> m (NValue t f m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (NixString -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
NixString -> NValue t f m
nvStr (NixString -> NValue t f m)
-> (NValue t f m -> NixString) -> NValue t f m -> NValue t f m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NValue t f m -> NixString
forall t (f :: * -> *) (m :: * -> *).
MonadDataContext f m =>
NValue t f m -> NixString
toXML) (m (NValue t f m) -> m (NValue t f m))
-> (NValue t f m -> m (NValue t f m))
-> NValue t f m
-> m (NValue t f m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NValue t f m -> m (NValue t f m)
forall e (m :: * -> *) t (f :: * -> *).
(Framed e m, MonadThunk t m (NValue t f m),
 MonadDataErrorContext t f m, HasCitations m (NValue t f m) t,
 HasCitations1 m (NValue t f m) f, Ord (ThunkId m)) =>
NValue t f m -> m (NValue t f m)
normalForm) (NValue t f m -> m (NValue t f m))
-> (NValue t f m -> m (NValue t f m))
-> NValue t f m
-> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand

typeOfNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
typeOfNix :: NValue t f m -> m (NValue t f m)
typeOfNix NValue t f m
nvv =
  do
    NValue t f m
v <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nvv
    let
      detectType :: Text
detectType =
        case NValue t f m
v of
          NVConstant NAtom
a ->
            case NAtom
a of
              NURI   Text
_ -> Text
"string"
              NInt   Integer
_ -> Text
"int"
              NFloat Float
_ -> Text
"float"
              NBool  Bool
_ -> Text
"bool"
              NAtom
NNull    -> Text
"null"
          NVStr     NixString
_   -> Text
"string"
          NVList    [NValue t f m]
_   -> Text
"list"
          NVSet     AttrSet (NValue t f m)
_ HashMap Text SourcePos
_ -> Text
"set"
          NVClosure{}   -> Text
"lambda"
          NVPath    FilePath
_   -> Text
"path"
          NVBuiltin Text
_ NValue t f m -> m (NValue t f m)
_ -> Text
"lambda"
          NValue t f m
_             -> Text -> Text
forall a t. (HasCallStack, IsText t) => t -> a
error Text
"Pattern synonyms obscure complete patterns"

    NixString -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (NixString -> m (NValue t f m)) -> NixString -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ Text -> NixString
makeNixStringWithoutContext Text
detectType

tryEvalNix
  :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
tryEvalNix :: NValue t f m -> m (NValue t f m)
tryEvalNix NValue t f m
e = m (NValue t f m)
-> (SomeException -> m (NValue t f m)) -> m (NValue t f m)
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> (e -> m a) -> m a
catch (NValue t f m -> NValue t f m
forall t (f :: * -> *) (m :: * -> *) e.
(Scoped (NValue t f m) m, MonadReader e m, Has e Frames,
 Has e SrcSpan, Has e Options, MonadFix m, MonadCatch m,
 Alternative m, MonadEffects t f m, MonadThunk t m (NValue t f m),
 Comonad f, Traversable f, HasCitations m (NValue t f m) t,
 HasCitations1 m (NValue t f m) f, MonadValue (NValue t f m) m,
 Applicative f, Show t, Typeable m, Typeable f, Typeable t) =>
NValue t f m -> NValue t f m
onSuccess (NValue t f m -> NValue t f m)
-> m (NValue t f m) -> m (NValue t f m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
e) (NValue t f m -> m (NValue t f m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NValue t f m -> m (NValue t f m))
-> (SomeException -> NValue t f m)
-> SomeException
-> m (NValue t f m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SomeException -> NValue t f m
onError)
 where
  onSuccess :: NValue t f m -> NValue t f m
onSuccess NValue t f m
v =
    HashMap Text SourcePos
-> HashMap Text (NValue t f m) -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
HashMap Text SourcePos
-> HashMap Text (NValue t f m) -> NValue t f m
nvSet
      HashMap Text SourcePos
forall a. Monoid a => a
mempty
      (HashMap Text (NValue t f m) -> NValue t f m)
-> HashMap Text (NValue t f m) -> NValue t f m
forall a b. (a -> b) -> a -> b
$ [(Text, NValue t f m)] -> HashMap Text (NValue t f m)
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
M.fromList
        [ (Text
"success", Bool -> NValue t f m
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
Bool -> NValue t f m
mkNVBool Bool
True)
        , (Text
"value", NValue t f m
v)
        ]

  onError :: SomeException -> NValue t f m
  onError :: SomeException -> NValue t f m
onError SomeException
_ =
    HashMap Text SourcePos
-> HashMap Text (NValue t f m) -> NValue t f m
forall (f :: * -> *) t (m :: * -> *).
Applicative f =>
HashMap Text SourcePos
-> HashMap Text (NValue t f m) -> NValue t f m
nvSet
      HashMap Text SourcePos
forall a. Monoid a => a
mempty
      (HashMap Text (NValue t f m) -> NValue t f m)
-> HashMap Text (NValue t f m) -> NValue t f m
forall a b. (a -> b) -> a -> b
$ [(Text, NValue t f m)] -> HashMap Text (NValue t f m)
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
M.fromList
        ([(Text, NValue t f m)] -> HashMap Text (NValue t f m))
-> [(Text, NValue t f m)] -> HashMap Text (NValue t f m)
forall a b. (a -> b) -> a -> b
$ ((NValue t f m -> (Text, NValue t f m))
-> NValue t f m -> (Text, NValue t f m)
forall a b. (a -> b) -> a -> b
$ Bool -> NValue t f m
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
Bool -> NValue t f m
mkNVBool Bool
False) ((NValue t f m -> (Text, NValue t f m)) -> (Text, NValue t f m))
-> [NValue t f m -> (Text, NValue t f m)] -> [(Text, NValue t f m)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
          [ (Text
"success",)
          , (Text
"value"  ,)
          ]

traceNix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m
  -> m (NValue t f m)
traceNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
traceNix NValue t f m
msg NValue t f m
action =
  do
    MonadEffects t f m => FilePath -> m ()
forall t (f :: * -> *) (m :: * -> *).
MonadEffects t f m =>
FilePath -> m ()
traceEffect @t @f @m (FilePath -> m ()) -> (NixString -> FilePath) -> NixString -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> FilePath
forall a. ToString a => a -> FilePath
toString (Text -> FilePath) -> (NixString -> Text) -> NixString -> FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NixString -> Text
stringIgnoreContext (NixString -> m ()) -> m NixString -> m ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m NixString
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
msg
    pure NValue t f m
action

-- Please, can function remember fail context
addErrorContextNix
  :: forall e t f m
   . MonadNix e t f m
  => NValue t f m
  -> NValue t f m  -- action
  -> m (NValue t f m)
addErrorContextNix :: NValue t f m -> NValue t f m -> m (NValue t f m)
addErrorContextNix NValue t f m
_ = NValue t f m -> m (NValue t f m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure

execNix
  :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
execNix :: NValue t f m -> m (NValue t f m)
execNix NValue t f m
xs =
  do
    [NValue t f m]
ls <- NValue t f m -> m [NValue t f m]
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @[NValue t f m] NValue t f m
xs
    [NixString]
xs <- (NValue t f m -> m NixString) -> [NValue t f m] -> m [NixString]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse ((NValue t f m -> NValue t f m -> m (NValue t f m))
-> CopyToStoreMode -> CoercionLevel -> NValue t f m -> m NixString
forall e (m :: * -> *) t (f :: * -> *).
(Framed e m, MonadStore m, MonadThrow m,
 MonadDataErrorContext t f m, MonadValue (NValue t f m) m) =>
(NValue t f m -> NValue t f m -> m (NValue t f m))
-> CopyToStoreMode -> CoercionLevel -> NValue t f m -> m NixString
coerceToString NValue t f m -> NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> NValue t f m -> m (NValue t f m)
callFunc CopyToStoreMode
DontCopyToStore CoercionLevel
CoerceStringy) [NValue t f m]
ls
    -- 2018-11-19: NOTE: Still need to do something with the context here
    -- See prim_exec in nix/src/libexpr/primops.cc
    -- Requires the implementation of EvalState::realiseContext
    [Text] -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
(MonadNix e t f m, MonadInstantiate m) =>
[Text] -> m (NValue t f m)
exec (NixString -> Text
stringIgnoreContext (NixString -> Text) -> [NixString] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [NixString]
xs)

fetchurlNix
  :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
fetchurlNix :: NValue t f m -> m (NValue t f m)
fetchurlNix =
  (\case
    NVSet AttrSet (NValue t f m)
s HashMap Text SourcePos
_ -> Maybe (NValue t f m) -> NValue t f m -> m (NValue t f m)
go (Text -> AttrSet (NValue t f m) -> Maybe (NValue t f m)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup Text
"sha256" AttrSet (NValue t f m)
s) (NValue t f m -> m (NValue t f m))
-> m (NValue t f m) -> m (NValue t f m)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand (NValue t f m -> m (NValue t f m))
-> m (NValue t f m) -> m (NValue t f m)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Text -> AttrSet (NValue t f m) -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
Text -> AttrSet (NValue t f m) -> m (NValue t f m)
attrsetGet Text
"url" AttrSet (NValue t f m)
s
    v :: NValue t f m
v@NVStr{} -> Maybe (NValue t f m) -> NValue t f m -> m (NValue t f m)
go Maybe (NValue t f m)
forall a. Maybe a
Nothing NValue t f m
v
    NValue t f m
v -> ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"builtins.fetchurl: Expected URI or set, got " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> NValue t f m -> FilePath
forall b a. (Show a, IsString b) => a -> b
show NValue t f m
v
  ) (NValue t f m -> m (NValue t f m))
-> (NValue t f m -> m (NValue t f m))
-> NValue t f m
-> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand

 where
  go :: Maybe (NValue t f m) -> NValue t f m -> m (NValue t f m)
  go :: Maybe (NValue t f m) -> NValue t f m -> m (NValue t f m)
go Maybe (NValue t f m)
_msha =
    \case
      NVStr NixString
ns ->
        (ErrorCall -> m (NValue t f m))
-> (StorePath -> m (NValue t f m))
-> Either ErrorCall StorePath
-> m (NValue t f m)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either -- msha
          ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError
          StorePath -> m (NValue t f m)
forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue
          (Either ErrorCall StorePath -> m (NValue t f m))
-> m (Either ErrorCall StorePath) -> m (NValue t f m)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Text -> m (Either ErrorCall StorePath)
forall (m :: * -> *).
MonadHttp m =>
Text -> m (Either ErrorCall StorePath)
getURL (Text -> m (Either ErrorCall StorePath))
-> m Text -> m (Either ErrorCall StorePath)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NixString -> m Text
forall e (m :: * -> *).
(MonadReader e m, Has e Frames, MonadThrow m) =>
NixString -> m Text
noContextAttrs NixString
ns

      NValue t f m
v -> ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"builtins.fetchurl: Expected URI or string, got " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> NValue t f m -> FilePath
forall b a. (Show a, IsString b) => a -> b
show NValue t f m
v

  noContextAttrs :: NixString -> m Text
noContextAttrs NixString
ns =
    m Text -> (Text -> m Text) -> Maybe Text -> m Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
      (ErrorCall -> m Text
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m Text) -> ErrorCall -> m Text
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall FilePath
"builtins.fetchurl: unsupported arguments to url")
      Text -> m Text
forall (f :: * -> *) a. Applicative f => a -> f a
pure
      (NixString -> Maybe Text
getStringNoContext NixString
ns)

partitionNix
  :: forall e t f m
   . MonadNix e t