1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-21 01:39:36 +01:00

Clean up JSON utils in a few ways

In particular

- Remove `get`, it is redundant with `valueAt` and the `get` in
  `util.hh`.

- Remove `nullableValueAt`. It is morally just the function composition
  `getNullable . valueAt`, not an orthogonal combinator like the others.

- `optionalValueAt` return a pointer, not `std::optional`. This also
  expresses optionality, but without creating a needless copy. This
  brings it in line with the other combinators which also return
  references.

- Delete `valueAt` and `optionalValueAt` taking the map by value, as we
  did for `get` in 408c09a120, which
  prevents bugs / unnecessary copies.

`adl_serializer<DerivationOptions::OutputChecks>::from_json` was the one
use of `getNullable`. I give it a little static function for the
ultimate creation of a `std::optional` it does need to do (after
switching it to using `getNullable . valueAt`. That could go in
`json-utils.hh` eventually, but I didn't bother for now since only one
things needs it.

Co-authored-by: Sergei Zimmerman <sergei@zimmerman.foo>
This commit is contained in:
John Ericson 2025-10-24 18:00:05 -04:00
parent f0b95b6d5b
commit 0f0d9255c6
6 changed files with 99 additions and 92 deletions

View file

@ -70,7 +70,7 @@ TEST(valueAt, simpleObject)
auto nested = R"({ "hello": { "world": "" } })"_json;
ASSERT_EQ(valueAt(valueAt(getObject(nested), "hello"), "world"), "");
ASSERT_EQ(valueAt(getObject(valueAt(getObject(nested), "hello")), "world"), "");
}
TEST(valueAt, missingKey)
@ -119,10 +119,12 @@ TEST(getArray, wrongAssertions)
{
auto json = R"({ "object": {}, "array": [], "string": "", "int": 0, "boolean": false })"_json;
ASSERT_THROW(getArray(valueAt(json, "object")), Error);
ASSERT_THROW(getArray(valueAt(json, "string")), Error);
ASSERT_THROW(getArray(valueAt(json, "int")), Error);
ASSERT_THROW(getArray(valueAt(json, "boolean")), Error);
auto & obj = getObject(json);
ASSERT_THROW(getArray(valueAt(obj, "object")), Error);
ASSERT_THROW(getArray(valueAt(obj, "string")), Error);
ASSERT_THROW(getArray(valueAt(obj, "int")), Error);
ASSERT_THROW(getArray(valueAt(obj, "boolean")), Error);
}
TEST(getString, rightAssertions)
@ -136,10 +138,12 @@ TEST(getString, wrongAssertions)
{
auto json = R"({ "object": {}, "array": [], "string": "", "int": 0, "boolean": false })"_json;
ASSERT_THROW(getString(valueAt(json, "object")), Error);
ASSERT_THROW(getString(valueAt(json, "array")), Error);
ASSERT_THROW(getString(valueAt(json, "int")), Error);
ASSERT_THROW(getString(valueAt(json, "boolean")), Error);
auto & obj = getObject(json);
ASSERT_THROW(getString(valueAt(obj, "object")), Error);
ASSERT_THROW(getString(valueAt(obj, "array")), Error);
ASSERT_THROW(getString(valueAt(obj, "int")), Error);
ASSERT_THROW(getString(valueAt(obj, "boolean")), Error);
}
TEST(getIntegralNumber, rightAssertions)
@ -156,18 +160,20 @@ TEST(getIntegralNumber, wrongAssertions)
auto json =
R"({ "object": {}, "array": [], "string": "", "int": 0, "signed": -256, "large": 128, "boolean": false })"_json;
ASSERT_THROW(getUnsigned(valueAt(json, "object")), Error);
ASSERT_THROW(getUnsigned(valueAt(json, "array")), Error);
ASSERT_THROW(getUnsigned(valueAt(json, "string")), Error);
ASSERT_THROW(getUnsigned(valueAt(json, "boolean")), Error);
ASSERT_THROW(getUnsigned(valueAt(json, "signed")), Error);
auto & obj = getObject(json);
ASSERT_THROW(getInteger<int8_t>(valueAt(json, "object")), Error);
ASSERT_THROW(getInteger<int8_t>(valueAt(json, "array")), Error);
ASSERT_THROW(getInteger<int8_t>(valueAt(json, "string")), Error);
ASSERT_THROW(getInteger<int8_t>(valueAt(json, "boolean")), Error);
ASSERT_THROW(getInteger<int8_t>(valueAt(json, "large")), Error);
ASSERT_THROW(getInteger<int8_t>(valueAt(json, "signed")), Error);
ASSERT_THROW(getUnsigned(valueAt(obj, "object")), Error);
ASSERT_THROW(getUnsigned(valueAt(obj, "array")), Error);
ASSERT_THROW(getUnsigned(valueAt(obj, "string")), Error);
ASSERT_THROW(getUnsigned(valueAt(obj, "boolean")), Error);
ASSERT_THROW(getUnsigned(valueAt(obj, "signed")), Error);
ASSERT_THROW(getInteger<int8_t>(valueAt(obj, "object")), Error);
ASSERT_THROW(getInteger<int8_t>(valueAt(obj, "array")), Error);
ASSERT_THROW(getInteger<int8_t>(valueAt(obj, "string")), Error);
ASSERT_THROW(getInteger<int8_t>(valueAt(obj, "boolean")), Error);
ASSERT_THROW(getInteger<int8_t>(valueAt(obj, "large")), Error);
ASSERT_THROW(getInteger<int8_t>(valueAt(obj, "signed")), Error);
}
TEST(getBoolean, rightAssertions)
@ -181,24 +187,28 @@ TEST(getBoolean, wrongAssertions)
{
auto json = R"({ "object": {}, "array": [], "string": "", "int": 0, "boolean": false })"_json;
ASSERT_THROW(getBoolean(valueAt(json, "object")), Error);
ASSERT_THROW(getBoolean(valueAt(json, "array")), Error);
ASSERT_THROW(getBoolean(valueAt(json, "string")), Error);
ASSERT_THROW(getBoolean(valueAt(json, "int")), Error);
auto & obj = getObject(json);
ASSERT_THROW(getBoolean(valueAt(obj, "object")), Error);
ASSERT_THROW(getBoolean(valueAt(obj, "array")), Error);
ASSERT_THROW(getBoolean(valueAt(obj, "string")), Error);
ASSERT_THROW(getBoolean(valueAt(obj, "int")), Error);
}
TEST(optionalValueAt, existing)
{
auto json = R"({ "string": "ssh-rsa" })"_json;
ASSERT_EQ(optionalValueAt(json, "string"), std::optional{"ssh-rsa"});
auto * ptr = optionalValueAt(getObject(json), "string");
ASSERT_TRUE(ptr);
ASSERT_EQ(*ptr, R"("ssh-rsa")"_json);
}
TEST(optionalValueAt, empty)
{
auto json = R"({})"_json;
ASSERT_EQ(optionalValueAt(json, "string"), std::nullopt);
ASSERT_EQ(optionalValueAt(getObject(json), "string"), nullptr);
}
TEST(getNullable, null)