-
-
Notifications
You must be signed in to change notification settings - Fork 51
Expand file tree
/
Copy pathresponse.cc
More file actions
105 lines (94 loc) · 3.25 KB
/
response.cc
File metadata and controls
105 lines (94 loc) · 3.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <nlohmann/json.hpp>
#include <nix/util/json-utils.hh>
#include <nix/util/util.hh> // for overloaded
#include <nlohmann/json_fwd.hpp>
#include <optional>
#include <stdexcept>
#include <string>
#include <utility>
#include <variant>
#include <vector>
#include "response.hh"
#include "drv.hh"
namespace nlohmann {
using nix::get;
using nix::getBoolean;
using nix::getObject;
using nix::getString;
using nix::overloaded;
using nix::valueAt;
void adl_serializer<Response>::to_json(json &res, const Response &response) {
res = json{
{"attr", response.attr},
{"attrPath", response.attrPath},
};
if (!response.traces.empty()) {
res["traces"] = response.traces;
}
if (!response.warnings.empty()) {
res["warnings"] = response.warnings;
}
std::visit(overloaded{
[&](const Response::Job &job) -> void {
// Merge Drv fields at the top level (flat structure)
res.update(json(job.drv));
if (job.extraValue) {
res["extraValue"] = *job.extraValue;
}
},
[&](const Response::Attrs &attrs) -> void {
res["attrs"] = attrs.attrs;
},
[&](const Response::Error &error) -> void {
res["error"] = error.error;
res["fatal"] = error.fatal;
},
},
response.payload);
}
auto adl_serializer<Response>::from_json(const json &_json) -> Response {
const auto &json = getObject(_json);
auto attr = getString(valueAt(json, "attr"));
std::vector<std::string> attrPath = valueAt(json, "attrPath");
std::vector<std::string> traces;
if (const auto *tracesJson = get(json, "traces")) {
traces = tracesJson->get<std::vector<std::string>>();
}
std::vector<std::string> warnings;
if (const auto *warningsJson = get(json, "warnings")) {
warnings = warningsJson->get<std::vector<std::string>>();
}
auto makeResponse = [&](Response::Payload payload) -> Response {
return Response{
.attr = std::move(attr),
.attrPath = std::move(attrPath),
.traces = std::move(traces),
.warnings = std::move(warnings),
.payload = std::move(payload),
};
};
if (const auto *attrs = get(json, "attrs")) {
return makeResponse(Response::Attrs{*attrs});
}
if (const auto *error = get(json, "error")) {
Response::Error err{.error = getString(*error)};
if (const auto *fatalJson = get(json, "fatal")) {
err.fatal = getBoolean(*fatalJson);
}
return makeResponse(std::move(err));
}
if (get(json, "drvPath") != nullptr) {
auto drv = adl_serializer<Drv>::from_json(_json);
std::optional<nlohmann::json> extraValue;
if (const auto *extra = get(json, "extraValue")) {
extraValue = *extra;
}
return makeResponse(Response::Job{
std::move(drv),
std::move(extraValue),
});
}
throw std::invalid_argument(
"Response JSON must contain 'attrs', 'error', or 'drvPath'");
}
} // namespace nlohmann