Skip to content

Commit 1c02dd5

Browse files
committed
Allow for standard nlohmann JSON serializers to take separate XP features
I realized that we can actually do this thing, even though it is not what nlohmann expects at all, because the extra parameter has a default argument so nlohmann doesn't need to care. Sneaky!
1 parent d87a06a commit 1c02dd5

File tree

5 files changed

+35
-32
lines changed

5 files changed

+35
-32
lines changed

src/libstore-tests/derivation.cc

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -66,23 +66,17 @@ TEST_F(DynDerivationTest, BadATerm_oldVersionDynDeps)
6666
FormatError);
6767
}
6868

69-
#define MAKE_OUTPUT_JSON_TEST_P(FIXTURE) \
70-
TEST_P(FIXTURE, from_json) \
71-
{ \
72-
const auto & [name, expected] = GetParam(); \
73-
/* Don't use readJsonTest because we want to check experimental \
74-
features. */ \
75-
readTest(Path{"output-"} + name + ".json", [&](const auto & encoded_) { \
76-
json j = json::parse(encoded_); \
77-
DerivationOutput got = DerivationOutput::fromJSON(j, mockXpSettings); \
78-
ASSERT_EQ(got, expected); \
79-
}); \
80-
} \
81-
\
82-
TEST_P(FIXTURE, to_json) \
83-
{ \
84-
const auto & [name, value] = GetParam(); \
85-
writeJsonTest("output-" + name, value); \
69+
#define MAKE_OUTPUT_JSON_TEST_P(FIXTURE) \
70+
TEST_P(FIXTURE, from_json) \
71+
{ \
72+
const auto & [name, expected] = GetParam(); \
73+
readJsonTest(Path{"output-"} + name, expected, mockXpSettings); \
74+
} \
75+
\
76+
TEST_P(FIXTURE, to_json) \
77+
{ \
78+
const auto & [name, value] = GetParam(); \
79+
writeJsonTest("output-" + name, value); \
8680
}
8781

8882
struct DerivationOutputJsonTest : DerivationTest,
@@ -193,13 +187,7 @@ INSTANTIATE_TEST_SUITE_P(
193187
TEST_P(FIXTURE, from_json) \
194188
{ \
195189
const auto & drv = GetParam(); \
196-
/* Don't use readJsonTest because we want to check experimental \
197-
features. */ \
198-
readTest(drv.name + ".json", [&](const auto & encoded_) { \
199-
auto encoded = json::parse(encoded_); \
200-
Derivation got = Derivation::fromJSON(encoded, mockXpSettings); \
201-
ASSERT_EQ(got, drv); \
202-
}); \
190+
readJsonTest(drv.name, drv, mockXpSettings); \
203191
} \
204192
\
205193
TEST_P(FIXTURE, to_json) \

src/libstore/derivations.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1496,19 +1496,20 @@ namespace nlohmann {
14961496

14971497
using namespace nix;
14981498

1499-
DerivationOutput adl_serializer<DerivationOutput>::from_json(const json & json)
1499+
DerivationOutput
1500+
adl_serializer<DerivationOutput>::from_json(const json & json, const ExperimentalFeatureSettings & xpSettings)
15001501
{
1501-
return DerivationOutput::fromJSON(json);
1502+
return DerivationOutput::fromJSON(json, xpSettings);
15021503
}
15031504

15041505
void adl_serializer<DerivationOutput>::to_json(json & json, const DerivationOutput & c)
15051506
{
15061507
json = c.toJSON();
15071508
}
15081509

1509-
Derivation adl_serializer<Derivation>::from_json(const json & json)
1510+
Derivation adl_serializer<Derivation>::from_json(const json & json, const ExperimentalFeatureSettings & xpSettings)
15101511
{
1511-
return Derivation::fromJSON(json);
1512+
return Derivation::fromJSON(json, xpSettings);
15121513
}
15131514

15141515
void adl_serializer<Derivation>::to_json(json & json, const Derivation & c)

src/libstore/include/nix/store/derivations.hh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -537,5 +537,5 @@ std::string hashPlaceholder(const OutputNameView outputName);
537537

538538
} // namespace nix
539539

540-
JSON_IMPL(nix::DerivationOutput)
541-
JSON_IMPL(nix::Derivation)
540+
JSON_IMPL_WITH_XP_FEATURES(nix::DerivationOutput)
541+
JSON_IMPL_WITH_XP_FEATURES(nix::Derivation)

src/libutil-test-support/include/nix/util/tests/json-characterization.hh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ struct JsonCharacterizationTest : virtual CharacterizationTest
2424
* @param test hook that takes the contents of the file and does the
2525
* actual work
2626
*/
27-
void readJsonTest(PathView testStem, const T & expected)
27+
void readJsonTest(PathView testStem, const T & expected, auto... args)
2828
{
2929
using namespace nlohmann;
3030
readTest(Path{testStem} + ".json", [&](const auto & encodedRaw) {
3131
auto encoded = json::parse(encodedRaw);
32-
T decoded = adl_serializer<T>::from_json(encoded);
32+
T decoded = adl_serializer<T>::from_json(encoded, args...);
3333
ASSERT_EQ(decoded, expected);
3434
});
3535
}

src/libutil/include/nix/util/json-impls.hh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#include <nlohmann/json_fwd.hpp>
55

6+
#include "nix/util/experimental-features.hh"
7+
68
// Following https://github.com/nlohmann/json#how-can-i-use-get-for-non-default-constructiblenon-copyable-types
79
#define JSON_IMPL(TYPE) \
810
namespace nlohmann { \
@@ -14,3 +16,15 @@
1416
static void to_json(json & json, const TYPE & t); \
1517
}; \
1618
}
19+
20+
#define JSON_IMPL_WITH_XP_FEATURES(TYPE) \
21+
namespace nlohmann { \
22+
using namespace nix; \
23+
template<> \
24+
struct adl_serializer<TYPE> \
25+
{ \
26+
static TYPE \
27+
from_json(const json & json, const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings); \
28+
static void to_json(json & json, const TYPE & t); \
29+
}; \
30+
}

0 commit comments

Comments
 (0)