aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/json-utils.hh
diff options
context:
space:
mode:
authoreldritch horrors <pennae@lix.systems>2024-03-04 06:08:39 +0100
committereldritch horrors <pennae@lix.systems>2024-03-04 07:11:25 +0100
commitc208e918e55c423203692343b56d893dc7435095 (patch)
treef9fb10c1bb69d058f1d2071fdf35e88a0981eeb3 /src/libutil/json-utils.hh
parentb7c61d337b1b5c129f053b0ede906d1b871d3bde (diff)
fix: `nlohmann::adl_serializer` for `std::optional` (#9147)
This allows templates such as `NLOHMANN_DEFINE_TYPE_*` templates and other generators with things like `std::vector<std::optional<T>>`. Co-authored-by: John Ericson <John.Ericson@Obsidian.Systems> (cherry picked from commit 02bd821f2e71372d31bbe6700bd68086cc2ee70a) Change-Id: I8b0ebcf2af4226610dadd565962f2d2327415a03
Diffstat (limited to 'src/libutil/json-utils.hh')
-rw-r--r--src/libutil/json-utils.hh19
1 files changed, 14 insertions, 5 deletions
diff --git a/src/libutil/json-utils.hh b/src/libutil/json-utils.hh
index 77c63595c..06dd80cf7 100644
--- a/src/libutil/json-utils.hh
+++ b/src/libutil/json-utils.hh
@@ -78,20 +78,29 @@ namespace nlohmann {
*/
template<typename T>
struct adl_serializer<std::optional<T>> {
- static std::optional<T> from_json(const json & json) {
+ /**
+ * @brief Convert a JSON type to an `optional<T>` treating
+ * `null` as `std::nullopt`.
+ */
+ static void from_json(const json & json, std::optional<T> & t) {
static_assert(
nix::json_avoids_null<T>::value,
"null is already in use for underlying type's JSON");
- return json.is_null()
+ t = json.is_null()
? std::nullopt
- : std::optional { adl_serializer<T>::from_json(json) };
+ : std::make_optional(json.template get<T>());
}
- static void to_json(json & json, std::optional<T> t) {
+
+ /**
+ * @brief Convert an optional type to a JSON type treating `std::nullopt`
+ * as `null`.
+ */
+ static void to_json(json & json, const std::optional<T> & t) {
static_assert(
nix::json_avoids_null<T>::value,
"null is already in use for underlying type's JSON");
if (t)
- adl_serializer<T>::to_json(json, *t);
+ json = *t;
else
json = nullptr;
}