Add isInitialized to nix::Value

Add a method to check if a value has been initialized. This helps avoid
segfaults when calling `type()`.
Useful in the context of the new C API.

Closes #10524
This commit is contained in:
José Luis Lafuente 2024-04-18 20:05:59 +02:00
parent 6fd2f42c2d
commit 5cc4af5231
No known key found for this signature in database
GPG Key ID: 8A3455EBE455489A
2 changed files with 33 additions and 1 deletions

View File

@ -23,6 +23,7 @@ class BindingsBuilder;
typedef enum {
tUnset,
tInt = 1,
tBool,
tString,
@ -166,7 +167,7 @@ public:
struct Value
{
private:
InternalType internalType;
InternalType internalType = tUnset;
friend std::string showType(const Value & v);
@ -270,6 +271,7 @@ public:
inline ValueType type(bool invalidIsThunk = false) const
{
switch (internalType) {
case tUnset: break;
case tInt: return nInt;
case tBool: return nBool;
case tString: return nString;
@ -294,6 +296,11 @@ public:
internalType = newType;
}
inline bool isInitialized()
{
return internalType != tUnset;
}
inline void mkInt(NixInt n)
{
finishValue(tInt, { .integer = n });

View File

@ -0,0 +1,25 @@
#include "value.hh"
#include "tests/libstore.hh"
namespace nix {
class ValueTest : public LibStoreTest
{};
TEST_F(ValueTest, unsetValue)
{
Value unsetValue;
ASSERT_EQ(false, unsetValue.isInitialized());
ASSERT_EQ(nThunk, unsetValue.type(true));
ASSERT_DEATH(unsetValue.type(), "");
}
TEST_F(ValueTest, vInt)
{
Value vInt;
vInt.mkInt(42);
ASSERT_EQ(true, vInt.isInitialized());
}
} // namespace nix