1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-15 23:12:44 +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

@ -2,7 +2,6 @@
///@file
#include <nlohmann/json.hpp>
#include <list>
#include "nix/util/error.hh"
#include "nix/util/types.hh"
@ -12,20 +11,25 @@ namespace nix {
enum struct ExperimentalFeature;
const nlohmann::json * get(const nlohmann::json & map, const std::string & key);
nlohmann::json * get(nlohmann::json & map, const std::string & key);
/**
* Get the value of a json object at a key safely, failing with a nice
* error if the key does not exist.
*
* Use instead of nlohmann::json::at() to avoid ugly exceptions.
*/
const nlohmann::json & valueAt(const nlohmann::json::object_t & map, const std::string & key);
const nlohmann::json & valueAt(const nlohmann::json::object_t & map, std::string_view key);
std::optional<nlohmann::json> optionalValueAt(const nlohmann::json::object_t & value, const std::string & key);
std::optional<nlohmann::json> nullableValueAt(const nlohmann::json::object_t & value, const std::string & key);
/**
* @return A pointer to the value assiocated with `key` if `value`
* contains `key`, otherwise return `nullptr` (not JSON `null`!).
*/
const nlohmann::json * optionalValueAt(const nlohmann::json::object_t & value, std::string_view key);
/**
* Prevents bugs; see `get` for the same trick.
*/
const nlohmann::json & valueAt(nlohmann::json::object_t && map, std::string_view key) = delete;
const nlohmann::json * optionalValueAt(nlohmann::json::object_t && value, std::string_view key) = delete;
/**
* Downcast the json object, failing with a nice error if the conversion fails.

View file

@ -1,52 +1,21 @@
#include "nix/util/json-utils.hh"
#include "nix/util/error.hh"
#include "nix/util/types.hh"
#include <nlohmann/json_fwd.hpp>
#include <iostream>
#include <optional>
#include "nix/util/util.hh"
namespace nix {
const nlohmann::json * get(const nlohmann::json & map, const std::string & key)
const nlohmann::json & valueAt(const nlohmann::json::object_t & map, std::string_view key)
{
auto i = map.find(key);
if (i == map.end())
return nullptr;
return &*i;
}
nlohmann::json * get(nlohmann::json & map, const std::string & key)
{
auto i = map.find(key);
if (i == map.end())
return nullptr;
return &*i;
}
const nlohmann::json & valueAt(const nlohmann::json::object_t & map, const std::string & key)
{
if (!map.contains(key))
if (auto * p = optionalValueAt(map, key))
return *p;
else
throw Error("Expected JSON object to contain key '%s' but it doesn't: %s", key, nlohmann::json(map).dump());
return map.at(key);
}
std::optional<nlohmann::json> optionalValueAt(const nlohmann::json::object_t & map, const std::string & key)
const nlohmann::json * optionalValueAt(const nlohmann::json::object_t & map, std::string_view key)
{
if (!map.contains(key))
return std::nullopt;
return std::optional{map.at(key)};
}
std::optional<nlohmann::json> nullableValueAt(const nlohmann::json::object_t & map, const std::string & key)
{
auto value = valueAt(map, key);
if (value.is_null())
return std::nullopt;
return std::optional{std::move(value)};
return get(map, key);
}
const nlohmann::json * getNullable(const nlohmann::json & value)