packages feed

hercules-ci-cnix-expr 0.5.0.0 → 0.5.1.0

raw patch · 6 files changed

+270/−137 lines, 6 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Hercules.CNix.Expr: instance GHC.Read.Read a => GHC.Read.Read (Hercules.CNix.Expr.ViaJSON a)
- Hercules.CNix.Expr: instance GHC.Show.Show a => GHC.Show.Show (Hercules.CNix.Expr.ViaJSON a)
- Hercules.CNix.Expr: instance Hercules.CNix.Expr.FromValue Hercules.CNix.Expr.Typed.NixInt GHC.Int.Int64
- Hercules.CNix.Expr: instance Hercules.CNix.Expr.ToRawValue Foreign.C.Types.CBool
- Hercules.CNix.Expr: instance Hercules.CNix.Expr.ToRawValue Foreign.C.Types.CDouble
- Hercules.CNix.Expr: instance Hercules.CNix.Expr.ToRawValue GHC.Int.Int64
- Hercules.CNix.Expr: instance Hercules.CNix.Expr.ToValue Foreign.C.Types.CBool
- Hercules.CNix.Expr: instance Hercules.CNix.Expr.ToValue Foreign.C.Types.CDouble
- Hercules.CNix.Expr: instance Hercules.CNix.Expr.ToValue GHC.Int.Int64
- Hercules.CNix.Expr.Raw: instance GHC.Generics.Generic Hercules.CNix.Expr.Raw.RawValueType
- Hercules.CNix.Expr.Raw: instance GHC.Show.Show Hercules.CNix.Expr.Raw.RawValueType
- Hercules.CNix.Expr.Schema: instance (s GHC.Types.~ t) => GHC.OverloadedLabels.IsLabel s (Hercules.CNix.Expr.Schema.AttrLabel t)
- Hercules.CNix.Expr.Schema: instance GHC.Exception.Type.Exception Hercules.CNix.Expr.Schema.NixException
- Hercules.CNix.Expr.Schema: instance GHC.Show.Show Hercules.CNix.Expr.Schema.NixException
- Hercules.CNix.Expr.Schema: instance GHC.Show.Show Hercules.CNix.Expr.Schema.Provenance
- Hercules.CNix.Expr.Schema: instance Hercules.CNix.Expr.Schema.FromPSObject GHC.Int.Int64 GHC.Int.Int64
- Hercules.CNix.Expr.Schema: instance Hercules.CNix.Expr.Schema.PossibleTypesForSchema GHC.Int.Int64
- Hercules.CNix.Expr.Typed: instance Hercules.CNix.Expr.Typed.CheckType GHC.Int.Int64
- Hercules.CNix.Expr.Typed: instance Hercules.CNix.Expr.Typed.HasRawValueType GHC.Int.Int64
+ Hercules.CNix.Expr: instance GHC.Internal.Read.Read a => GHC.Internal.Read.Read (Hercules.CNix.Expr.ViaJSON a)
+ Hercules.CNix.Expr: instance GHC.Internal.Show.Show a => GHC.Internal.Show.Show (Hercules.CNix.Expr.ViaJSON a)
+ Hercules.CNix.Expr: instance Hercules.CNix.Expr.FromValue Hercules.CNix.Expr.Typed.NixInt GHC.Internal.Int.Int64
+ Hercules.CNix.Expr: instance Hercules.CNix.Expr.ToRawValue GHC.Internal.Foreign.C.Types.CBool
+ Hercules.CNix.Expr: instance Hercules.CNix.Expr.ToRawValue GHC.Internal.Foreign.C.Types.CDouble
+ Hercules.CNix.Expr: instance Hercules.CNix.Expr.ToRawValue GHC.Internal.Int.Int64
+ Hercules.CNix.Expr: instance Hercules.CNix.Expr.ToValue GHC.Internal.Foreign.C.Types.CBool
+ Hercules.CNix.Expr: instance Hercules.CNix.Expr.ToValue GHC.Internal.Foreign.C.Types.CDouble
+ Hercules.CNix.Expr: instance Hercules.CNix.Expr.ToValue GHC.Internal.Int.Int64
+ Hercules.CNix.Expr.Raw: instance GHC.Internal.Generics.Generic Hercules.CNix.Expr.Raw.RawValueType
+ Hercules.CNix.Expr.Raw: instance GHC.Internal.Show.Show Hercules.CNix.Expr.Raw.RawValueType
+ Hercules.CNix.Expr.Schema: instance (s GHC.Types.~ t) => GHC.Internal.OverloadedLabels.IsLabel s (Hercules.CNix.Expr.Schema.AttrLabel t)
+ Hercules.CNix.Expr.Schema: instance GHC.Internal.Exception.Type.Exception Hercules.CNix.Expr.Schema.NixException
+ Hercules.CNix.Expr.Schema: instance GHC.Internal.Show.Show Hercules.CNix.Expr.Schema.NixException
+ Hercules.CNix.Expr.Schema: instance GHC.Internal.Show.Show Hercules.CNix.Expr.Schema.Provenance
+ Hercules.CNix.Expr.Schema: instance Hercules.CNix.Expr.Schema.FromPSObject GHC.Internal.Int.Int64 GHC.Internal.Int.Int64
+ Hercules.CNix.Expr.Schema: instance Hercules.CNix.Expr.Schema.PossibleTypesForSchema GHC.Internal.Int.Int64
+ Hercules.CNix.Expr.Typed: instance Hercules.CNix.Expr.Typed.CheckType GHC.Internal.Int.Int64
+ Hercules.CNix.Expr.Typed: instance Hercules.CNix.Expr.Typed.HasRawValueType GHC.Internal.Int.Int64

Files

CHANGELOG.md view
@@ -5,6 +5,10 @@  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## 0.5.1.0 - 2026-01-06++- Nix support up to 2.33+ ## 0.5.0.0 - 2025-07-18  - `init` now installs synchronous signal handlers for you. You may remove your call to `installDefaultSigINTHandler`.
hercules-ci-cnix-expr.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.4  name:           hercules-ci-cnix-expr-version:        0.5.0.0+version:        0.5.1.0 synopsis:       Bindings for the Nix evaluator category:       Nix, CI, Testing, DevOps homepage:       https://docs.hercules-ci.com@@ -25,10 +25,19 @@   description: Whether to enable IDE workarounds. You shouldn't need this.   default: False +flag nix-2_31+  description: nix-store >= 2.31+  default: False+  manual: False+ -- match the C++ language standard Nix is using common cxx-opts-  cxx-options:-    -std=c++2a+  if flag(nix-2_31)+    cxx-options:+      -std=c++23+  else+    cxx-options:+      -std=c++2a    cxx-options:     -Wall@@ -41,12 +50,22 @@   if impl(ghc >= 8.10)     ghc-options:       -optcxx-Wall-      -optcxx-std=c++2a+    if flag(nix-2_31)+      ghc-options:+        -optcxx-std=c++23+    else+      ghc-options:+        -optcxx-std=c++2a   else     -- Remove soon     ghc-options:-      -optc-std=c++2a       -optc-Wall+    if flag(nix-2_31)+      ghc-options:+        -optc-std=c++23+    else+      ghc-options:+        -optc-std=c++2a     if os(darwin)       ghc-options: -pgmc=clang++ @@ -97,11 +116,11 @@     extra-libraries:         boost_context   pkgconfig-depends:-      nix-store >= 2.28-    , nix-expr >= 2.28+      nix-store >= 2.28 && < 2.34+    , nix-expr >= 2.28 && < 2.34     -- TODO: replace nix-main stack overflow detection?-    , nix-main >= 2.28-    , nix-flake >= 2.28+    , nix-main >= 2.28 && < 2.34+    , nix-flake >= 2.28 && < 2.34   test-suite hercules-ci-cnix-expr-unit-tests
include/hercules-ci-cnix/expr.hxx view
@@ -1,9 +1,13 @@ #pragma once  #include <nix/store/derivations.hh>+#include <nix/expr/value.hh>  #include <hercules-ci-cnix/store.hxx>  typedef nix::Strings::iterator StringsIterator; typedef nix::DerivationOutputs::iterator DerivationOutputsIterator; typedef nix::StringPairs::iterator StringPairsIterator;+#if NIX_IS_AT_LEAST(2, 30, 0)+typedef nix::ListView ListViewType;+#endif
src/Hercules/CNix/Expr.hs view
@@ -8,7 +8,6 @@ {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-}- -- redundant-constraints: False positive in default signature for `toRawValue` {-# OPTIONS_GHC -Wno-redundant-constraints #-} @@ -53,10 +52,10 @@     getLocalFlake,     getFlakeFromGit,     getFlakeFromArchiveUrl,-    ToRawValue(..),-    ToValue(..),-    FromValue(..),-    ViaJSON(..),+    ToRawValue (..),+    ToValue (..),+    FromValue (..),+    ViaJSON (..),      -- * Re-exports     RawValue,@@ -73,6 +72,8 @@  import Conduit import qualified Data.Aeson as A+import Data.Aeson.KeyMap (toMapText)+import qualified Data.ByteString.Unsafe as BS import Data.Coerce (coerce) import qualified Data.HashMap.Lazy as H import qualified Data.Map as M@@ -81,19 +82,17 @@ import qualified Data.Vector as V import Foreign (nullPtr) import qualified Foreign.C.String+import qualified Hercules.CNix as CNix import Hercules.CNix.Encapsulation (moveToForeignPtrWrapper) import Hercules.CNix.Expr.Context import Hercules.CNix.Expr.Raw import Hercules.CNix.Expr.Typed import Hercules.CNix.Store import Hercules.CNix.Store.Context-import qualified Hercules.CNix as CNix import qualified Language.C.Inline.Cpp as C import qualified Language.C.Inline.Cpp.Exception as C import Protolude hiding (evalState) import System.Directory (makeAbsolute)-import Data.Aeson.KeyMap (toMapText)-import qualified Data.ByteString.Unsafe as BS  C.context (Hercules.CNix.Store.Context.context <> Hercules.CNix.Expr.Context.evalContext) @@ -200,12 +199,10 @@         }|]         pass --{- | Configure the stack overflow handler to sleep before returning, allowing-  other threads to continue for a bit.--  No-op before Nix 2.12--}+-- | Configure the stack overflow handler to sleep before returning, allowing+--  other threads to continue for a bit.+--+--  No-op before Nix 2.12 setExtraStackOverflowHandlerToSleep :: IO () setExtraStackOverflowHandlerToSleep =   void@@ -259,15 +256,16 @@   }|]  -- | (private) Make an EvalState and leak it.-newEvalState :: MonadIO m => Store -> m (Ptr EvalState)-newEvalState (Store store) = liftIO-  [C.throwBlock| EvalState* {-    nix::LookupPath emptyLookupPath;-    return new EvalState(emptyLookupPath, *$(refStore* store), fetchSettings, evalSettings);+newEvalState :: (MonadIO m) => Store -> m (Ptr EvalState)+newEvalState (Store store) =+  liftIO+    [C.throwBlock| EvalState* {+      nix::LookupPath emptyLookupPath;+      return new EvalState(emptyLookupPath, *$(refStore* store), fetchSettings, evalSettings);   } |]  -- | (private) Don't leak it.-deleteEvalState :: MonadIO m => (Ptr EvalState) -> m ()+deleteEvalState :: (MonadIO m) => (Ptr EvalState) -> m () deleteEvalState st = liftIO [C.throwBlock| void { delete $(EvalState* st); } |]  withEvalState ::@@ -277,20 +275,26 @@ withEvalState store = bracket (newEvalState store) deleteEvalState  withEvalStateConduit ::-  MonadResource m =>+  (MonadResource m) =>   Store ->   (Ptr EvalState -> ConduitT i o m r) ->   ConduitT i o m r withEvalStateConduit store = bracketP (newEvalState store) deleteEvalState  -- | Insert an allowed path. Only has an effect when in restricted or pure mode.+{- ORMOLU_DISABLE -} addAllowedPath :: Ptr EvalState -> ByteString -> IO () addAllowedPath evalState path =   [C.throwBlock| void {     std::string path = std::string($bs-ptr:path, $bs-len:path);     EvalState &evalState = *$(EvalState *evalState);+#if NIX_IS_AT_LEAST(2, 32, 0)+    evalState.allowPathLegacy(path);+#else     evalState.allowPath(path);+#endif   }|]+{- ORMOLU_ENABLE -}  addInternalAllowedPaths :: Ptr EvalState -> IO () addInternalAllowedPaths _evalState = do@@ -348,6 +352,7 @@           return $(EvalState *evalState)->isFunctor(*$(Value *v));         }|] +{- ORMOLU_DISABLE -} getRecurseForDerivations :: Ptr EvalState -> Value NixAttrs -> IO Bool getRecurseForDerivations evalState (Value (RawValue v)) =   (0 /=)@@ -355,6 +360,14 @@           Value *v = $(Value *v);           EvalState &evalState = *$(EvalState *evalState);           auto attrs = v->attrs();+#if NIX_IS_AT_LEAST(2, 32, 0)+          auto iter = attrs->get(evalState.s.recurseForDerivations);+          if (!iter) {+            return 0;+          } else {+            return evalState.forceBool(*iter->value, iter->pos, "while evaluating whether to traverse into an attribute set to find more derivations");+          }+#else           // Bindings::const_iterator iter; // 2.24           auto iter = attrs->find(evalState.sRecurseForDerivations);           if (iter == attrs->end()) {@@ -366,8 +379,11 @@             // nixpkgs master 67e2de195a4aa0a50ffb1e1ba0b4fb531dca67dc             return evalState.forceBool(*iter->value, iter->pos, "while evaluating whether to traverse into an attribute set to find more derivations");           }+#endif         } |]+{- ORMOLU_ENABLE -} +{- ORMOLU_DISABLE -} getAttr :: Ptr EvalState -> Value NixAttrs -> ByteString -> IO (Maybe RawValue) getAttr evalState (Value (RawValue v)) k =   mkNullableRawValue@@ -376,6 +392,14 @@       EvalState &evalState = *$(EvalState *evalState);       Symbol k = evalState.symbols.create($bs-cstr:k);       auto attrs = v.attrs();+#if NIX_IS_AT_LEAST(2, 32, 0)+      auto iter = attrs->get(k);+      if (!iter) {+        return nullptr;+      } else {+        return iter->value;+      }+#else       // Bindings::const_iterator iter; // 2.24       auto iter = attrs->find(k);       if (iter == attrs->end()) {@@ -383,32 +407,64 @@       } else {         return iter->value;       }+#endif     }|]+{- ORMOLU_ENABLE -}  -- | Converts 'nullPtr' to 'Nothing'; actual values to @Just (a :: 'RawValue')@ mkNullableRawValue :: Ptr Value' -> IO (Maybe RawValue) mkNullableRawValue p | p == nullPtr = pure Nothing mkNullableRawValue p = Just <$> mkRawValue p +{- ORMOLU_DISABLE -} getAttrs :: Ptr EvalState -> Value NixAttrs -> IO (Map ByteString RawValue) getAttrs evalState (Value (RawValue v)) = do+#if NIX_IS_AT_LEAST(2, 32, 0)+  -- In Nix 2.32+, we need to collect all attrs in C++ since iteration changed+  size <- [C.exp| size_t { $(Value *v)->attrs()->size() }|]+  let collect :: C.CSize -> Map ByteString RawValue -> IO (Map ByteString RawValue)+      collect i acc | i >= size = pure acc+      collect i acc = do+        name <-+          BS.unsafePackMallocCString+            =<< [C.block| const char *{+              EvalState &evalState = *$(EvalState *evalState);+              auto iter = $(Value *v)->attrs()->begin();+              for (size_t j = 0; j < $(size_t i); j++) ++iter;+              SymbolStr str = evalState.symbols[iter->name];+              return stringdup(static_cast<std::string>(str));+            }|]+        value <- mkRawValue =<< [C.block| Value *{+              auto iter = $(Value *v)->attrs()->begin();+              for (size_t j = 0; j < $(size_t i); j++) ++iter;+              return new (NoGC) Value(*iter->value);+            }|]+        let acc' = M.insert name value acc+        seq acc' pass+        collect (i + 1) acc'+  collect 0 mempty+#else   begin <- [C.exp| const Attr *{ $(Value *v)->attrs()->begin() }|]   end <- [C.exp| const Attr *{ $(Value *v)->attrs()->end() }|]   let gather :: Map ByteString RawValue -> Ptr Attr' -> IO (Map ByteString RawValue)       gather acc i | i == end = pure acc       gather acc i = do-        name <- BS.unsafePackMallocCString =<< [C.block| const char *{-          EvalState &evalState = *$(EvalState *evalState);-          SymbolStr str = evalState.symbols[$(Attr *i)->name];-          return stringdup(static_cast<std::string>(str));-        }|]+        name <-+          BS.unsafePackMallocCString+            =<< [C.block| const char *{+              EvalState &evalState = *$(EvalState *evalState);+              SymbolStr str = evalState.symbols[$(Attr *i)->name];+              return stringdup(static_cast<std::string>(str));+            }|]         value <- mkRawValue =<< [C.exp| Value *{ new (NoGC) Value(*$(Attr *i)->value) } |]         let acc' = M.insert name value acc         seq acc' pass         gather acc' =<< [C.exp| Attr *{ &$(Attr *i)[1] }|]   gather mempty begin+#endif+{- ORMOLU_ENABLE -} -getDrvFile :: MonadIO m => Ptr EvalState -> RawValue -> m StorePath+getDrvFile :: (MonadIO m) => Ptr EvalState -> RawValue -> m StorePath getDrvFile evalState (RawValue v) = liftIO do   moveToForeignPtrWrapper     =<< [C.throwBlock| nix::StorePath *{@@ -438,12 +494,26 @@       Right _ -> do         pure $ Right Nothing +#if NIX_IS_AT_LEAST(2, 30, 0) getList :: Value NixList -> IO [RawValue] getList (Value (RawValue nixList)) = do   len <- [C.exp| int { $(Value *nixList)->listSize() }|]+  bracket+    [C.exp| ListViewType * { new ListViewType($(Value *nixList)->listView()) }|]+    (\listView -> [C.exp| void { delete $(ListViewType *listView) }|])+    (\listView -> do+      let getElem i = mkRawValue =<< [C.exp| Value * { (*$(ListViewType *listView))[$(int i)] }|]+      for [0 .. (len - 1)] \i -> do+        getElem i+    )+#else+getList :: Value NixList -> IO [RawValue]+getList (Value (RawValue nixList)) = do+  len <- [C.exp| int { $(Value *nixList)->listSize() }|]   let getElem i = mkRawValue =<< [C.exp| Value * { $(Value *nixList)->listElems()[$(int i)] }|]   for [0 .. (len - 1)] \i -> do     getElem i+#endif  getAttrList :: Ptr EvalState -> Value NixAttrs -> ByteString -> IO (Either SomeException (Maybe [RawValue])) getAttrList evalState attrset attrName = do@@ -498,18 +568,24 @@       return r;     }|] +{- ORMOLU_DISABLE -} mkPath :: Ptr EvalState -> ByteString -> IO (Value NixPath) mkPath evalState path =   Value     <$> ( mkRawValue             =<< [C.throwBlock| Value *{-      Value *r = new (NoGC) Value();-      std::string s($bs-ptr:path, $bs-len:path);-      EvalState & state = *$(EvalState *evalState);-      r->mkPath(state.rootPath(CanonPath(s)));-      return r;-  }|]+              Value *r = new (NoGC) Value();+              std::string s($bs-ptr:path, $bs-len:path);+              EvalState & state = *$(EvalState *evalState);+#if NIX_IS_AT_LEAST(2, 33, 0)+              r->mkPath(state.rootPath(CanonPath(s)), state.mem);+#else+              r->mkPath(state.rootPath(CanonPath(s)));+#endif+              return r;+          }|]         )+{- ORMOLU_ENABLE -}  getFlakeFromFlakeRef :: Ptr EvalState -> ByteString -> IO RawValue getFlakeFromFlakeRef evalState flakeRef = do@@ -542,35 +618,34 @@   absPath <- encodeUtf8 . toS <$> makeAbsolute (toS path)   mkRawValue     =<< [C.throwBlock| Value *{-    EvalState &evalState = *$(EvalState *evalState);-    Value *r = new (NoGC) Value();-    std::string path($bs-ptr:absPath, $bs-len:absPath);-    auto flakeRef = nix::parseFlakeRef(-      fetchSettings,-      path,-      {},-      true);-    nix::flake::callFlake(evalState,-      nix::flake::lockFlake(-        flakeSettings,-        evalState,-        flakeRef,-        nix::flake::LockFlags {-          .updateLockFile = false,-          .useRegistries = false,-          .allowUnlocked = false,-        }),-      *r);-    return r;-  }|]+      EvalState &evalState = *$(EvalState *evalState);+      Value *r = new (NoGC) Value();+      std::string path($bs-ptr:absPath, $bs-len:absPath);+      auto flakeRef = nix::parseFlakeRef(+        fetchSettings,+        path,+        {},+        true);+      nix::flake::callFlake(evalState,+        nix::flake::lockFlake(+          flakeSettings,+          evalState,+          flakeRef,+          nix::flake::LockFlags {+            .updateLockFile = false,+            .useRegistries = false,+            .allowUnlocked = false,+          }),+        *r);+      return r;+    }|]  getFlakeFromGit :: Ptr EvalState -> Text -> Text -> Text -> IO RawValue getFlakeFromGit evalState url ref rev =-  let-    urlb = encodeUtf8 url-    refb = encodeUtf8 ref-    revb = encodeUtf8 rev-  in [C.throwBlock| Value *{+  let urlb = encodeUtf8 url+      refb = encodeUtf8 ref+      revb = encodeUtf8 rev+   in [C.throwBlock| Value *{     EvalState &evalState = *$(EvalState *evalState);     Value *r = new (NoGC) Value();     std::string url($bs-ptr:urlb, $bs-len:urlb);@@ -599,7 +674,7 @@       *r);     return r;   }|]-    >>= mkRawValue+        >>= mkRawValue  getFlakeFromArchiveUrl :: Ptr EvalState -> Text -> IO RawValue getFlakeFromArchiveUrl evalState url = do@@ -612,15 +687,15 @@   p' <- getStringIgnoreContext p   getFlakeFromFlakeRef evalState p' -traverseWithKey_ :: Applicative f => (k -> a -> f ()) -> Map k a -> f ()+traverseWithKey_ :: (Applicative f) => (k -> a -> f ()) -> Map k a -> f () traverseWithKey_ f = M.foldrWithKey (\k a more -> f k a *> more) (pure ())  class ToRawValue a where   toRawValue :: Ptr EvalState -> a -> IO RawValue-  default toRawValue :: ToValue a => Ptr EvalState -> a -> IO RawValue+  default toRawValue :: (ToValue a) => Ptr EvalState -> a -> IO RawValue   toRawValue evalState a = rtValue <$> toValue evalState a -class ToRawValue a => ToValue a where+class (ToRawValue a) => ToValue a where   type NixTypeFor a :: Type   toValue :: Ptr EvalState -> a -> IO (Value (NixTypeFor a)) @@ -660,10 +735,10 @@   toValue _ b =     coerce       <$> [C.block| Value *{-      Value *r = new (NoGC) Value();-      r->mkBool($(bool b));-      return r;-    }|]+        Value *r = new (NoGC) Value();+        r->mkBool($(bool b));+        return r;+      }|]  instance ToRawValue Bool @@ -681,10 +756,10 @@   toValue _ i =     coerce       <$> [C.block| Value *{-    Value *r = new (NoGC) Value();-    r->mkInt($(int64_t i));-    return r;-  }|]+        Value *r = new (NoGC) Value();+        r->mkInt($(int64_t i));+        return r;+      }|]  instance ToRawValue Int @@ -699,10 +774,10 @@   toValue _ f =     coerce       <$> [C.block| Value *{-        Value *r = new (NoGC) Value();-        r->mkFloat($(double f));-        return r;-      }|]+          Value *r = new (NoGC) Value();+          r->mkFloat($(double f));+          return r;+        }|]  instance ToRawValue Double @@ -710,24 +785,36 @@   type NixTypeFor Double = NixFloat   toValue es f = toValue es (fromRational (toRational f) :: C.CDouble) +{- ORMOLU_DISABLE -} -- | Nix String instance ToValue ByteString where   type NixTypeFor ByteString = NixString-  toValue _ s =+  toValue evalState s =     -- TODO simplify when r->mkString(string_view) is safe in all supported Nix versions     coerce       <$> [C.block| Value *{-    Value *r = new (NoGC) Value();-    std::string_view s($bs-ptr:s, $bs-len:s);-    // If empty, the pointer may be invalid; don't use it.-    if (s.size() == 0) {-      r->mkString("");-    }-    else {-      r->mkString(GC_STRNDUP(s.data(), s.size()));-    }-    return r;-  }|]+        Value *r = new (NoGC) Value();+        std::string_view s($bs-ptr:s, $bs-len:s);+#if NIX_IS_AT_LEAST(2, 33, 0)+        EvalState &evalState = *$(EvalState *evalState);+        if (s.size() == 0) {+          r->mkString(std::string_view(""), evalState.mem);+        }+        else {+          r->mkString(std::string_view(GC_STRNDUP(s.data(), s.size()), s.size()), evalState.mem);+        }+#else+        // If empty, the pointer may be invalid; don't use it.+        if (s.size() == 0) {+          r->mkString("");+        }+        else {+          r->mkString(GC_STRNDUP(s.data(), s.size()));+        }+#endif+        return r;+      }|]+{- ORMOLU_ENABLE -}  -- | Nix String instance ToRawValue ByteString@@ -740,47 +827,53 @@   type NixTypeFor Text = NixString   toValue es s = toValue es (encodeUtf8 s) -instance ToRawValue a => ToRawValue (Map ByteString a)+instance (ToRawValue a) => ToRawValue (Map ByteString a) -withBindingsBuilder :: Integral n => Ptr EvalState -> n -> (Ptr BindingsBuilder' -> IO ()) -> IO (Value NixAttrs)+withBindingsBuilder :: (Integral n) => Ptr EvalState -> n -> (Ptr BindingsBuilder' -> IO ()) -> IO (Value NixAttrs) withBindingsBuilder evalState n f = do   withBindingsBuilder' evalState n \bb -> do     f bb-    v <- [C.block| Value* {-      auto v = new (NoGC) Value();-      v->mkAttrs(*$(BindingsBuilder *bb));-      return v;-    }|]+    v <-+      [C.block| Value* {+        auto v = new (NoGC) Value();+        v->mkAttrs(*$(BindingsBuilder *bb));+        return v;+      }|]     Value <$> mkRawValue v -withBindingsBuilder' :: Integral n => Ptr EvalState -> n -> (Ptr BindingsBuilder' -> IO a) -> IO a+{- ORMOLU_DISABLE -}+withBindingsBuilder' :: (Integral n) => Ptr EvalState -> n -> (Ptr BindingsBuilder' -> IO a) -> IO a withBindingsBuilder' evalState n =   let l :: C.CInt       l = fromIntegral n-  in-    bracket-      [C.block| BindingsBuilder* {-        auto &evalState = *$(EvalState *evalState);-        return new BindingsBuilder(evalState, evalState.allocBindings($(int l)));-      }|]-      \bb -> [C.block| void { delete $(BindingsBuilder *bb); }|]+   in bracket+        [C.block| BindingsBuilder* {+          auto &evalState = *$(EvalState *evalState);+#if NIX_IS_AT_LEAST(2, 32, 0)+          return new BindingsBuilder(evalState.buildBindings($(int l)));+#else+          return new BindingsBuilder(evalState, evalState.allocBindings($(int l)));+#endif+        }|]+        \bb -> [C.block| void { delete $(BindingsBuilder *bb); }|]+{- ORMOLU_ENABLE -} -instance ToRawValue a => ToValue (Map ByteString a) where+instance (ToRawValue a) => ToValue (Map ByteString a) where   type NixTypeFor (Map ByteString a) = NixAttrs    toValue evalState attrs = withBindingsBuilder evalState (length attrs) \bb -> do     attrs & traverseWithKey_ \k a -> do       RawValue aRaw <- toRawValue evalState a       [C.block| void {-          EvalState &evalState = *$(EvalState *evalState);-          std::string k($bs-ptr:k, $bs-len:k);-          Value &a = *$(Value *aRaw);-          $(BindingsBuilder *bb)->alloc(evalState.symbols.create(k)) = a;-        }|]+        EvalState &evalState = *$(EvalState *evalState);+        std::string k($bs-ptr:k, $bs-len:k);+        Value &a = *$(Value *aRaw);+        $(BindingsBuilder *bb)->alloc(evalState.symbols.create(k)) = a;+      }|] -instance ToRawValue a => ToRawValue (Map Text a)+instance (ToRawValue a) => ToRawValue (Map Text a) -instance ToRawValue a => ToValue (Map Text a) where+instance (ToRawValue a) => ToValue (Map Text a) where   type NixTypeFor (Map Text a) = NixAttrs   toValue evalState attrs = toValue evalState (M.mapKeys encodeUtf8 attrs) @@ -806,15 +899,15 @@ newtype ViaJSON a = ViaJSON {fromViaJSON :: a}   deriving newtype (Eq, Ord, Read, Show) -instance A.ToJSON a => ToRawValue (ViaJSON a) where+instance (A.ToJSON a) => ToRawValue (ViaJSON a) where   toRawValue es (ViaJSON a) = toRawValue es (A.toJSON a) -hmTraverseWithKey_ :: Applicative f => (k -> a -> f ()) -> H.HashMap k a -> f ()+hmTraverseWithKey_ :: (Applicative f) => (k -> a -> f ()) -> H.HashMap k a -> f () hmTraverseWithKey_ f = H.foldrWithKey (\k a more -> f k a *> more) (pure ()) -instance ToRawValue a => ToRawValue (H.HashMap Text a)+instance (ToRawValue a) => ToRawValue (H.HashMap Text a) -instance ToRawValue a => ToValue (H.HashMap Text a) where+instance (ToRawValue a) => ToValue (H.HashMap Text a) where   type NixTypeFor (H.HashMap Text a) = NixAttrs    toValue evalState attrs = withBindingsBuilder evalState (length attrs) \bb -> do@@ -822,15 +915,16 @@       RawValue aRaw <- toRawValue evalState a       let k = encodeUtf8 k'       [C.block| void {-          EvalState &evalState = *$(EvalState *evalState);-          std::string k($bs-ptr:k, $bs-len:k);-          Value &a = *$(Value *aRaw);-          $(BindingsBuilder *bb)->alloc(evalState.symbols.create(k)) = a;-        }|]+        EvalState &evalState = *$(EvalState *evalState);+        std::string k($bs-ptr:k, $bs-len:k);+        Value &a = *$(Value *aRaw);+        $(BindingsBuilder *bb)->alloc(evalState.symbols.create(k)) = a;+      }|] -instance ToRawValue a => ToRawValue (Vector a)+instance (ToRawValue a) => ToRawValue (Vector a) -instance ToRawValue a => ToValue (Vector a) where+{- ORMOLU_DISABLE -}+instance (ToRawValue a) => ToValue (Vector a) where   type NixTypeFor (Vector a) = NixList   toValue evalState vec =     coerce <$> do@@ -838,8 +932,15 @@           l = fromIntegral (length vec)       b <-         [C.block| ListBuilder* {+#if NIX_IS_AT_LEAST(2, 33, 0)           EvalState &evalState = *$(EvalState *evalState);+          return new (NoGC) ListBuilder(evalState.mem, $(int l));+#elif NIX_IS_AT_LEAST(2, 32, 0)+          return new (NoGC) ListBuilder($(int l));+#else+          EvalState &evalState = *$(EvalState *evalState);           return new (NoGC) ListBuilder(evalState, $(int l));+#endif         }|]       vec & V.imapM_ \i a -> do         RawValue aRaw <- toRawValue evalState a@@ -855,9 +956,10 @@           return v;         }|]       Value <$> mkRawValue v+{- ORMOLU_ENABLE -} -instance ToRawValue a => ToRawValue [a]+instance (ToRawValue a) => ToRawValue [a] -instance ToRawValue a => ToValue [a] where+instance (ToRawValue a) => ToValue [a] where   type NixTypeFor [a] = NixList   toValue es l = toValue es (V.fromList l)
src/Hercules/CNix/Expr/Context.hs view
@@ -33,6 +33,8 @@  data ListBuilder' +data ListViewType'+ context :: C.Context context =   C.cppCtx@@ -57,4 +59,6 @@           =: [t|BindingsBuilder'|]           <> C.TypeName "ListBuilder"           =: [t|ListBuilder'|]+          <> C.TypeName "ListViewType"+          =: [t|ListViewType'|]     }
src/Hercules/CNix/Expr/Typed.hs view
@@ -1,7 +1,7 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE CPP #-}  module Hercules.CNix.Expr.Typed   ( Value (..),@@ -137,8 +137,8 @@  getBool :: Value Bool -> IO Bool getBool (Value (RawValue v)) =-  (0 /=) <$>-    [C.exp| int { $(Value *v)->boolean() ? 1 : 0 }|]+  (0 /=)+    <$> [C.exp| int { $(Value *v)->boolean() ? 1 : 0 }|]  getInt :: Value NixInt -> IO Int64 getInt (Value (RawValue v)) =@@ -154,8 +154,8 @@  hasContext :: Value NixString -> IO Bool hasContext (Value (RawValue v)) =-  (0 /=) <$>-    [C.exp| int { $(Value *v)->context() ? 1 : 0 }|]+  (0 /=)+    <$> [C.exp| int { $(Value *v)->context() ? 1 : 0 }|]  class CheckType a where   checkType :: Ptr EvalState -> RawValue -> IO (Maybe (Value a))