Skip to content

Commit f5390e7

Browse files
committed
Make ValidPathInfo, NarInfo JSON instances, but don't yet use in the CLI
Make instances for them that share code with `nix path-info`, but do a slightly different format without store paths containing store dirs (matching the other latest JSON formats). Progress on #13570. If we depend on the store dir, our JSON serializers/deserializers take extra arguements, and that interfaces with the likes of various frameworks for associating these with types (e.g. nlohmann in C++, Serde in Rust, and Aeson in Haskell). For now, `nix path-info` still uses the previous format, with store dirs. We may yet decide to "rip of the band-aid", and just switch it over, but that is left as a future PR.
1 parent d00c419 commit f5390e7

File tree

7 files changed

+93
-32
lines changed

7 files changed

+93
-32
lines changed

src/libstore-tests/nar-info.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ static NarInfo makeNarInfo(const Store & store, bool includeImpureInfo)
6565
readTest(#STEM, [&](const auto & encoded_) { \
6666
auto encoded = json::parse(encoded_); \
6767
auto expected = makeNarInfo(*store, PURE); \
68-
NarInfo got = NarInfo::fromJSON(*store, expected.path, encoded); \
68+
auto got = UnkeyedNarInfo::fromJSON(&*store, encoded); \
6969
ASSERT_EQ(got, expected); \
7070
}); \
7171
} \
@@ -74,7 +74,7 @@ static NarInfo makeNarInfo(const Store & store, bool includeImpureInfo)
7474
{ \
7575
writeTest( \
7676
#STEM, \
77-
[&]() -> json { return makeNarInfo(*store, PURE).toJSON(*store, PURE); }, \
77+
[&]() -> json { return makeNarInfo(*store, PURE).toJSON(&*store, PURE); }, \
7878
[](const auto & file) { return json::parse(readFile(file)); }, \
7979
[](const auto & file, const auto & got) { return writeFile(file, got.dump(2) + "\n"); }); \
8080
}

src/libstore-tests/path-info.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ static UnkeyedValidPathInfo makeFull(const Store & store, bool includeImpureInfo
7070
{ \
7171
readTest(#STEM, [&](const auto & encoded_) { \
7272
auto encoded = json::parse(encoded_); \
73-
UnkeyedValidPathInfo got = UnkeyedValidPathInfo::fromJSON(*store, encoded); \
73+
UnkeyedValidPathInfo got = UnkeyedValidPathInfo::fromJSON(&*store, encoded); \
7474
auto expected = OBJ; \
7575
ASSERT_EQ(got, expected); \
7676
}); \
@@ -80,7 +80,7 @@ static UnkeyedValidPathInfo makeFull(const Store & store, bool includeImpureInfo
8080
{ \
8181
writeTest( \
8282
#STEM, \
83-
[&]() -> json { return OBJ.toJSON(*store, PURE); }, \
83+
[&]() -> json { return OBJ.toJSON(&*store, PURE); }, \
8484
[](const auto & file) { return json::parse(readFile(file)); }, \
8585
[](const auto & file, const auto & got) { return writeFile(file, got.dump(2) + "\n"); }); \
8686
}

src/libstore/include/nix/store/nar-info.hh

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,42 @@ namespace nix {
99

1010
struct StoreDirConfig;
1111

12-
struct NarInfo : ValidPathInfo
12+
struct UnkeyedNarInfo : virtual UnkeyedValidPathInfo
1313
{
1414
std::string url;
1515
std::string compression;
1616
std::optional<Hash> fileHash;
1717
uint64_t fileSize = 0;
1818

19+
UnkeyedNarInfo(UnkeyedValidPathInfo info)
20+
: UnkeyedValidPathInfo(std::move(info))
21+
{
22+
}
23+
24+
bool operator==(const UnkeyedNarInfo &) const = default;
25+
// TODO libc++ 16 (used by darwin) missing `std::optional::operator <=>`, can't do yet
26+
// auto operator <=>(const NarInfo &) const = default;
27+
28+
nlohmann::json toJSON(const StoreDirConfig * store, bool includeImpureInfo) const override;
29+
static UnkeyedNarInfo fromJSON(const StoreDirConfig * store, const nlohmann::json & json);
30+
};
31+
32+
/**
33+
* Key and the extra NAR fields
34+
*/
35+
struct NarInfo : ValidPathInfo, UnkeyedNarInfo
36+
{
1937
NarInfo() = delete;
2038

2139
NarInfo(ValidPathInfo info)
22-
: ValidPathInfo{std::move(info)}
40+
: UnkeyedValidPathInfo{static_cast<UnkeyedValidPathInfo &&>(info)}
41+
/* Later copies from `*this` are pointless. The argument is only
42+
there so the constructors can also call
43+
`UnkeyedValidPathInfo`, but this won't happen since the base
44+
class is virtual. Only this counstructor (assuming it is most
45+
derived) will initialize that virtual base class. */
46+
, ValidPathInfo{info.path, static_cast<const UnkeyedValidPathInfo &>(*this)}
47+
, UnkeyedNarInfo{static_cast<const UnkeyedValidPathInfo &>(*this)}
2348
{
2449
}
2550

@@ -37,13 +62,10 @@ struct NarInfo : ValidPathInfo
3762
NarInfo(const StoreDirConfig & store, const std::string & s, const std::string & whence);
3863

3964
bool operator==(const NarInfo &) const = default;
40-
// TODO libc++ 16 (used by darwin) missing `std::optional::operator <=>`, can't do yet
41-
// auto operator <=>(const NarInfo &) const = default;
4265

4366
std::string to_string(const StoreDirConfig & store) const;
44-
45-
nlohmann::json toJSON(const StoreDirConfig & store, bool includeImpureInfo) const override;
46-
static NarInfo fromJSON(const StoreDirConfig & store, const StorePath & path, const nlohmann::json & json);
4767
};
4868

4969
} // namespace nix
70+
71+
JSON_IMPL(nix::UnkeyedNarInfo)

src/libstore/include/nix/store/path-info.hh

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,11 @@ struct UnkeyedValidPathInfo
117117
* @param includeImpureInfo If true, variable elements such as the
118118
* registration time are included.
119119
*/
120-
virtual nlohmann::json toJSON(const StoreDirConfig & store, bool includeImpureInfo) const;
121-
static UnkeyedValidPathInfo fromJSON(const StoreDirConfig & store, const nlohmann::json & json);
120+
virtual nlohmann::json toJSON(const StoreDirConfig * store, bool includeImpureInfo) const;
121+
static UnkeyedValidPathInfo fromJSON(const StoreDirConfig * store, const nlohmann::json & json);
122122
};
123123

124-
struct ValidPathInfo : UnkeyedValidPathInfo
124+
struct ValidPathInfo : virtual UnkeyedValidPathInfo
125125
{
126126
StorePath path;
127127

@@ -174,10 +174,14 @@ struct ValidPathInfo : UnkeyedValidPathInfo
174174

175175
ValidPathInfo(StorePath && path, UnkeyedValidPathInfo info)
176176
: UnkeyedValidPathInfo(info)
177-
, path(std::move(path)) {};
177+
, path(std::move(path))
178+
{
179+
}
180+
178181
ValidPathInfo(const StorePath & path, UnkeyedValidPathInfo info)
179-
: UnkeyedValidPathInfo(info)
180-
, path(path) {};
182+
: ValidPathInfo(StorePath{path}, std::move(info))
183+
{
184+
}
181185

182186
static ValidPathInfo
183187
makeFromCA(const StoreDirConfig & store, std::string_view name, ContentAddressWithReferences && ca, Hash narHash);
@@ -191,3 +195,5 @@ static_assert(std::is_move_constructible_v<ValidPathInfo>);
191195
using ValidPathInfos = std::map<StorePath, ValidPathInfo>;
192196

193197
} // namespace nix
198+
199+
JSON_IMPL(nix::UnkeyedValidPathInfo)

src/libstore/nar-info.cc

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
namespace nix {
88

99
NarInfo::NarInfo(const StoreDirConfig & store, const std::string & s, const std::string & whence)
10-
: ValidPathInfo(StorePath(StorePath::dummy), Hash(Hash::dummy)) // FIXME: hack
10+
: UnkeyedValidPathInfo(Hash::dummy) // FIXME: hack
11+
, ValidPathInfo(StorePath::dummy, static_cast<const UnkeyedValidPathInfo &>(*this)) // FIXME: hack
12+
, UnkeyedNarInfo(static_cast<const UnkeyedValidPathInfo &>(*this))
1113
{
1214
unsigned line = 1;
1315

@@ -130,11 +132,11 @@ std::string NarInfo::to_string(const StoreDirConfig & store) const
130132
return res;
131133
}
132134

133-
nlohmann::json NarInfo::toJSON(const StoreDirConfig & store, bool includeImpureInfo) const
135+
nlohmann::json UnkeyedNarInfo::toJSON(const StoreDirConfig * store, bool includeImpureInfo) const
134136
{
135137
using nlohmann::json;
136138

137-
auto jsonObject = ValidPathInfo::toJSON(store, includeImpureInfo);
139+
auto jsonObject = UnkeyedValidPathInfo::toJSON(store, includeImpureInfo);
138140

139141
if (includeImpureInfo) {
140142
if (!url.empty())
@@ -150,14 +152,11 @@ nlohmann::json NarInfo::toJSON(const StoreDirConfig & store, bool includeImpureI
150152
return jsonObject;
151153
}
152154

153-
NarInfo NarInfo::fromJSON(const StoreDirConfig & store, const StorePath & path, const nlohmann::json & json)
155+
UnkeyedNarInfo UnkeyedNarInfo::fromJSON(const StoreDirConfig * store, const nlohmann::json & json)
154156
{
155157
using nlohmann::detail::value_t;
156158

157-
NarInfo res{ValidPathInfo{
158-
path,
159-
UnkeyedValidPathInfo::fromJSON(store, json),
160-
}};
159+
UnkeyedNarInfo res{UnkeyedValidPathInfo::fromJSON(store, json)};
161160

162161
auto & obj = getObject(json);
163162

@@ -177,3 +176,19 @@ NarInfo NarInfo::fromJSON(const StoreDirConfig & store, const StorePath & path,
177176
}
178177

179178
} // namespace nix
179+
180+
namespace nlohmann {
181+
182+
using namespace nix;
183+
184+
UnkeyedNarInfo adl_serializer<UnkeyedNarInfo>::from_json(const json & json)
185+
{
186+
return UnkeyedNarInfo::fromJSON(nullptr, json);
187+
}
188+
189+
void adl_serializer<UnkeyedNarInfo>::to_json(json & json, const UnkeyedNarInfo & c)
190+
{
191+
json = c.toJSON(nullptr, true);
192+
}
193+
194+
} // namespace nlohmann

src/libstore/path-info.cc

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ ValidPathInfo ValidPathInfo::makeFromCA(
149149
return res;
150150
}
151151

152-
nlohmann::json UnkeyedValidPathInfo::toJSON(const StoreDirConfig & store, bool includeImpureInfo) const
152+
nlohmann::json UnkeyedValidPathInfo::toJSON(const StoreDirConfig * store, bool includeImpureInfo) const
153153
{
154154
using nlohmann::json;
155155

@@ -163,13 +163,15 @@ nlohmann::json UnkeyedValidPathInfo::toJSON(const StoreDirConfig & store, bool i
163163
{
164164
auto & jsonRefs = jsonObject["references"] = json::array();
165165
for (auto & ref : references)
166-
jsonRefs.emplace_back(store.printStorePath(ref));
166+
jsonRefs.emplace_back(store ? static_cast<json>(store->printStorePath(ref)) : static_cast<json>(ref));
167167
}
168168

169169
jsonObject["ca"] = ca;
170170

171171
if (includeImpureInfo) {
172-
jsonObject["deriver"] = deriver ? (std::optional{store.printStorePath(*deriver)}) : std::nullopt;
172+
jsonObject["deriver"] = deriver ? (store ? static_cast<json>(std::optional{store->printStorePath(*deriver)})
173+
: static_cast<json>(std::optional{*deriver}))
174+
: static_cast<json>(std::optional<StorePath>{});
173175

174176
jsonObject["registrationTime"] = registrationTime ? (std::optional{registrationTime}) : std::nullopt;
175177

@@ -183,7 +185,7 @@ nlohmann::json UnkeyedValidPathInfo::toJSON(const StoreDirConfig & store, bool i
183185
return jsonObject;
184186
}
185187

186-
UnkeyedValidPathInfo UnkeyedValidPathInfo::fromJSON(const StoreDirConfig & store, const nlohmann::json & _json)
188+
UnkeyedValidPathInfo UnkeyedValidPathInfo::fromJSON(const StoreDirConfig * store, const nlohmann::json & _json)
187189
{
188190
UnkeyedValidPathInfo res{
189191
Hash(Hash::dummy),
@@ -203,7 +205,7 @@ UnkeyedValidPathInfo UnkeyedValidPathInfo::fromJSON(const StoreDirConfig & store
203205
try {
204206
auto references = getStringList(valueAt(json, "references"));
205207
for (auto & input : references)
206-
res.references.insert(store.parseStorePath(static_cast<const std::string &>(input)));
208+
res.references.insert(store ? store->parseStorePath(getString(input)) : static_cast<StorePath>(input));
207209
} catch (Error & e) {
208210
e.addTrace({}, "while reading key 'references'");
209211
throw;
@@ -218,7 +220,7 @@ UnkeyedValidPathInfo UnkeyedValidPathInfo::fromJSON(const StoreDirConfig & store
218220

219221
if (auto * rawDeriver0 = optionalValueAt(json, "deriver"))
220222
if (auto * rawDeriver = getNullable(*rawDeriver0))
221-
res.deriver = store.parseStorePath(getString(*rawDeriver));
223+
res.deriver = store ? store->parseStorePath(getString(*rawDeriver)) : static_cast<StorePath>(*rawDeriver);
222224

223225
if (auto * rawRegistrationTime0 = optionalValueAt(json, "registrationTime"))
224226
if (auto * rawRegistrationTime = getNullable(*rawRegistrationTime0))
@@ -234,3 +236,19 @@ UnkeyedValidPathInfo UnkeyedValidPathInfo::fromJSON(const StoreDirConfig & store
234236
}
235237

236238
} // namespace nix
239+
240+
namespace nlohmann {
241+
242+
using namespace nix;
243+
244+
UnkeyedValidPathInfo adl_serializer<UnkeyedValidPathInfo>::from_json(const json & json)
245+
{
246+
return UnkeyedValidPathInfo::fromJSON(nullptr, json);
247+
}
248+
249+
void adl_serializer<UnkeyedValidPathInfo>::to_json(json & json, const UnkeyedValidPathInfo & c)
250+
{
251+
json = c.toJSON(nullptr, true);
252+
}
253+
254+
} // namespace nlohmann

src/nix/path-info.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ static json pathInfoToJSON(Store & store, const StorePathSet & storePaths, bool
5151
// know the name yet until we've read the NAR info.
5252
printedStorePath = store.printStorePath(info->path);
5353

54-
jsonObject = info->toJSON(store, true);
54+
jsonObject = info->toJSON(&store, true);
5555

5656
if (showClosureSize) {
5757
StorePathSet closure;

0 commit comments

Comments
 (0)