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

@ -116,27 +116,29 @@ DerivationOptions::fromStructuredAttrs(const StringMap & env, const StructuredAt
DerivationOptions defaults = {};
if (shouldWarn && parsed) {
if (get(parsed->structuredAttrs, "allowedReferences")) {
auto & structuredAttrs = getObject(parsed->structuredAttrs);
if (get(structuredAttrs, "allowedReferences")) {
warn(
"'structuredAttrs' disables the effect of the top-level attribute 'allowedReferences'; use 'outputChecks' instead");
}
if (get(parsed->structuredAttrs, "allowedRequisites")) {
if (get(structuredAttrs, "allowedRequisites")) {
warn(
"'structuredAttrs' disables the effect of the top-level attribute 'allowedRequisites'; use 'outputChecks' instead");
}
if (get(parsed->structuredAttrs, "disallowedRequisites")) {
if (get(structuredAttrs, "disallowedRequisites")) {
warn(
"'structuredAttrs' disables the effect of the top-level attribute 'disallowedRequisites'; use 'outputChecks' instead");
}
if (get(parsed->structuredAttrs, "disallowedReferences")) {
if (get(structuredAttrs, "disallowedReferences")) {
warn(
"'structuredAttrs' disables the effect of the top-level attribute 'disallowedReferences'; use 'outputChecks' instead");
}
if (get(parsed->structuredAttrs, "maxSize")) {
if (get(structuredAttrs, "maxSize")) {
warn(
"'structuredAttrs' disables the effect of the top-level attribute 'maxSize'; use 'outputChecks' instead");
}
if (get(parsed->structuredAttrs, "maxClosureSize")) {
if (get(structuredAttrs, "maxClosureSize")) {
warn(
"'structuredAttrs' disables the effect of the top-level attribute 'maxClosureSize'; use 'outputChecks' instead");
}
@ -145,11 +147,15 @@ DerivationOptions::fromStructuredAttrs(const StringMap & env, const StructuredAt
return {
.outputChecks = [&]() -> OutputChecksVariant {
if (parsed) {
auto & structuredAttrs = getObject(parsed->structuredAttrs);
std::map<std::string, OutputChecks> res;
if (auto outputChecks = get(parsed->structuredAttrs, "outputChecks")) {
for (auto & [outputName, output] : getObject(*outputChecks)) {
if (auto * outputChecks = get(structuredAttrs, "outputChecks")) {
for (auto & [outputName, output_] : getObject(*outputChecks)) {
OutputChecks checks;
auto & output = getObject(output_);
if (auto maxSize = get(output, "maxSize"))
checks.maxSize = maxSize->get<uint64_t>();
@ -195,7 +201,9 @@ DerivationOptions::fromStructuredAttrs(const StringMap & env, const StructuredAt
std::map<std::string, bool> res;
if (parsed) {
if (auto udr = get(parsed->structuredAttrs, "unsafeDiscardReferences")) {
auto & structuredAttrs = getObject(parsed->structuredAttrs);
if (auto * udr = get(structuredAttrs, "unsafeDiscardReferences")) {
for (auto & [outputName, output] : getObject(*udr)) {
if (!output.is_boolean())
throw Error("attribute 'unsafeDiscardReferences.\"%s\"' must be a Boolean", outputName);
@ -226,7 +234,7 @@ DerivationOptions::fromStructuredAttrs(const StringMap & env, const StructuredAt
std::map<std::string, StringSet> ret;
if (parsed) {
auto e = optionalValueAt(parsed->structuredAttrs, "exportReferencesGraph");
auto e = optionalValueAt(getObject(parsed->structuredAttrs), "exportReferencesGraph");
if (!e || !e->is_object())
return ret;
for (auto & [key, value] : getObject(*e)) {
@ -333,8 +341,10 @@ namespace nlohmann {
using namespace nix;
DerivationOptions adl_serializer<DerivationOptions>::from_json(const json & json)
DerivationOptions adl_serializer<DerivationOptions>::from_json(const json & json_)
{
auto & json = getObject(json_);
return {
.outputChecks = [&]() -> OutputChecksVariant {
auto outputChecks = getObject(valueAt(json, "outputChecks"));
@ -397,13 +407,24 @@ void adl_serializer<DerivationOptions>::to_json(json & json, const DerivationOpt
json["allowSubstitutes"] = o.allowSubstitutes;
}
DerivationOptions::OutputChecks adl_serializer<DerivationOptions::OutputChecks>::from_json(const json & json)
template<typename T>
static inline std::optional<T> ptrToOwned(const json * ptr)
{
if (ptr)
return std::optional{*ptr};
else
return std::nullopt;
}
DerivationOptions::OutputChecks adl_serializer<DerivationOptions::OutputChecks>::from_json(const json & json_)
{
auto & json = getObject(json_);
return {
.ignoreSelfRefs = getBoolean(valueAt(json, "ignoreSelfRefs")),
.allowedReferences = nullableValueAt(json, "allowedReferences"),
.allowedReferences = ptrToOwned<StringSet>(getNullable(valueAt(json, "allowedReferences"))),
.disallowedReferences = getStringSet(valueAt(json, "disallowedReferences")),
.allowedRequisites = nullableValueAt(json, "allowedRequisites"),
.allowedRequisites = ptrToOwned<StringSet>(getNullable(valueAt(json, "allowedRequisites"))),
.disallowedRequisites = getStringSet(valueAt(json, "disallowedRequisites")),
};
}

View file

@ -159,17 +159,19 @@ NarInfo NarInfo::fromJSON(const StoreDirConfig & store, const StorePath & path,
UnkeyedValidPathInfo::fromJSON(store, json),
}};
auto & obj = getObject(json);
if (json.contains("url"))
res.url = getString(valueAt(json, "url"));
res.url = getString(valueAt(obj, "url"));
if (json.contains("compression"))
res.compression = getString(valueAt(json, "compression"));
res.compression = getString(valueAt(obj, "compression"));
if (json.contains("downloadHash"))
res.fileHash = Hash::parseAny(getString(valueAt(json, "downloadHash")), std::nullopt);
res.fileHash = Hash::parseAny(getString(valueAt(obj, "downloadHash")), std::nullopt);
if (json.contains("downloadSize"))
res.fileSize = getUnsigned(valueAt(json, "downloadSize"));
res.fileSize = getUnsigned(valueAt(obj, "downloadSize"));
return res;
}