Skip to content

Commit d566234

Browse files
committed
Add "maybe" operations to JSON.
Extracted from microsoft#1514
1 parent ad7b71c commit d566234

File tree

10 files changed

+158
-79
lines changed

10 files changed

+158
-79
lines changed

include/vcpkg/base/json.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,23 @@ namespace vcpkg::Json
108108
int64_t integer(LineInfo li) const noexcept;
109109
double number(LineInfo li) const noexcept;
110110
StringView string(LineInfo li) const noexcept;
111+
std::string* maybe_string() noexcept;
112+
const std::string* maybe_string() const noexcept;
111113

112114
const Array& array(LineInfo li) const& noexcept;
113115
Array& array(LineInfo li) & noexcept;
114116
Array&& array(LineInfo li) && noexcept;
115117

118+
Array* maybe_array() noexcept;
119+
const Array* maybe_array() const noexcept;
120+
116121
const Object& object(LineInfo li) const& noexcept;
117122
Object& object(LineInfo li) & noexcept;
118123
Object&& object(LineInfo li) && noexcept;
119124

125+
Object* maybe_object() noexcept;
126+
const Object* maybe_object() const noexcept;
127+
120128
static Value null(std::nullptr_t) noexcept;
121129
static Value boolean(bool) noexcept;
122130
static Value integer(int64_t i) noexcept;

src/vcpkg/base/json.cpp

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,26 @@ namespace vcpkg::Json
157157
return underlying_->string;
158158
}
159159

160+
std::string* Value::maybe_string() noexcept
161+
{
162+
if (underlying_ && underlying_->tag == VK::String)
163+
{
164+
return &underlying_->string;
165+
}
166+
167+
return nullptr;
168+
}
169+
170+
const std::string* Value::maybe_string() const noexcept
171+
{
172+
if (underlying_ && underlying_->tag == VK::String)
173+
{
174+
return &underlying_->string;
175+
}
176+
177+
return nullptr;
178+
}
179+
160180
const Array& Value::array(LineInfo li) const& noexcept
161181
{
162182
vcpkg::Checks::msg_check_exit(li, is_array(), msgJsonValueNotArray);
@@ -169,6 +189,26 @@ namespace vcpkg::Json
169189
}
170190
Array&& Value::array(LineInfo li) && noexcept { return std::move(this->array(li)); }
171191

192+
Array* Value::maybe_array() noexcept
193+
{
194+
if (underlying_ && underlying_->tag == VK::Array)
195+
{
196+
return &underlying_->array;
197+
}
198+
199+
return nullptr;
200+
}
201+
202+
const Array* Value::maybe_array() const noexcept
203+
{
204+
if (underlying_ && underlying_->tag == VK::Array)
205+
{
206+
return &underlying_->array;
207+
}
208+
209+
return nullptr;
210+
}
211+
172212
const Object& Value::object(LineInfo li) const& noexcept
173213
{
174214
vcpkg::Checks::msg_check_exit(li, is_object(), msgJsonValueNotObject);
@@ -181,6 +221,26 @@ namespace vcpkg::Json
181221
}
182222
Object&& Value::object(LineInfo li) && noexcept { return std::move(this->object(li)); }
183223

224+
Object* Value::maybe_object() noexcept
225+
{
226+
if (underlying_ && underlying_->tag == VK::Object)
227+
{
228+
return &underlying_->object;
229+
}
230+
231+
return nullptr;
232+
}
233+
234+
const Object* Value::maybe_object() const noexcept
235+
{
236+
if (underlying_ && underlying_->tag == VK::Object)
237+
{
238+
return &underlying_->object;
239+
}
240+
241+
return nullptr;
242+
}
243+
184244
Value::Value() noexcept = default;
185245
Value::Value(Value&&) noexcept = default;
186246
Value& Value::operator=(Value&&) noexcept = default;
@@ -1120,9 +1180,9 @@ namespace vcpkg::Json
11201180
{
11211181
return parse(text, origin).then([&](ParsedJson&& mabeValueIsh) -> ExpectedL<Json::Object> {
11221182
auto& asValue = mabeValueIsh.value;
1123-
if (asValue.is_object())
1183+
if (auto as_object = asValue.maybe_object())
11241184
{
1125-
return std::move(asValue).object(VCPKG_LINE_INFO);
1185+
return std::move(*as_object);
11261186
}
11271187

11281188
return msg::format(msgJsonErrorMustBeAnObject, msg::path = origin);

src/vcpkg/binarycaching.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -812,10 +812,12 @@ namespace
812812
auto maybe_json = Json::parse_object(*p, m_url);
813813
if (auto json = maybe_json.get())
814814
{
815-
auto archive_location = json->get(JsonIdArchiveCapitalLocation);
816-
if (archive_location && archive_location->is_string())
815+
if (auto archive_location = json->get(JsonIdArchiveCapitalLocation))
817816
{
818-
return archive_location->string(VCPKG_LINE_INFO).to_string();
817+
if (auto archive_location_string = archive_location->maybe_string())
818+
{
819+
return *archive_location_string;
820+
}
819821
}
820822
}
821823
}

src/vcpkg/bundlesettings.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,17 @@ namespace
3232

3333
bool parse_optional_json_string(const Json::Object& doc, StringLiteral field_name, Optional<std::string>& output)
3434
{
35-
auto value = doc.get(field_name);
36-
if (!value)
35+
if (auto value = doc.get(field_name))
3736
{
38-
return true;
39-
}
37+
if (auto value_string = value->maybe_string())
38+
{
39+
output = *value_string;
40+
return true;
41+
}
4042

41-
if (!value->is_string())
42-
{
4343
return false;
4444
}
4545

46-
output = value->string(VCPKG_LINE_INFO).to_string();
4746
return true;
4847
}
4948
}

src/vcpkg/commands.set-installed.cpp

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -50,24 +50,27 @@ namespace vcpkg
5050
Optional<Json::Object> create_dependency_graph_snapshot(const VcpkgCmdArguments& args,
5151
const ActionPlan& action_plan)
5252
{
53-
if (args.github_ref.has_value() && args.github_sha.has_value() && args.github_job.has_value() &&
54-
args.github_workflow.has_value() && args.github_run_id.has_value())
53+
const auto github_ref = args.github_ref.get();
54+
const auto github_sha = args.github_sha.get();
55+
const auto github_job = args.github_job.get();
56+
const auto github_workflow = args.github_workflow.get();
57+
const auto github_run_id = args.github_run_id.get();
58+
if (github_ref && github_sha && github_job && github_workflow && github_run_id)
5559
{
5660
Json::Object detector;
5761
detector.insert(JsonIdName, Json::Value::string("vcpkg"));
5862
detector.insert(JsonIdUrl, Json::Value::string("https://github.com/microsoft/vcpkg"));
5963
detector.insert(JsonIdVersion, Json::Value::string("1.0.0"));
6064

6165
Json::Object job;
62-
job.insert(JsonIdId, Json::Value::string(*args.github_run_id.get()));
63-
job.insert(JsonIdCorrelator,
64-
Json::Value::string(*args.github_workflow.get() + "-" + *args.github_job.get()));
66+
job.insert(JsonIdId, Json::Value::string(*github_run_id));
67+
job.insert(JsonIdCorrelator, Json::Value::string(fmt::format("{}-{}", *github_workflow, *github_run_id)));
6568

6669
Json::Object snapshot;
6770
snapshot.insert(JsonIdJob, job);
6871
snapshot.insert(JsonIdVersion, Json::Value::integer(0));
69-
snapshot.insert(JsonIdSha, Json::Value::string(*args.github_sha.get()));
70-
snapshot.insert(JsonIdRef, Json::Value::string(*args.github_ref.get()));
72+
snapshot.insert(JsonIdSha, Json::Value::string(*github_sha));
73+
snapshot.insert(JsonIdRef, Json::Value::string(*github_ref));
7174
snapshot.insert(JsonIdScanned, Json::Value::string(CTime::now_string()));
7275
snapshot.insert(JsonIdDetector, detector);
7376

@@ -77,44 +80,45 @@ namespace vcpkg
7780
std::unordered_map<std::string, std::string> map;
7881
for (auto&& action : action_plan.install_actions)
7982
{
80-
if (!action.source_control_file_and_location.has_value())
83+
const auto scfl = action.source_control_file_and_location.get();
84+
if (!scfl)
8185
{
8286
return nullopt;
8387
}
84-
const auto& scf = *action.source_control_file_and_location.get();
85-
auto version = scf.to_version().to_string();
86-
auto s = action.spec.to_string();
87-
auto pkg_url = Strings::concat("pkg:github/vcpkg/", s, "@", version);
88-
map.insert({s, pkg_url});
88+
auto spec = action.spec.to_string();
89+
map.insert(
90+
{spec, fmt::format("pkg:github/vcpkg/{}@{}", spec, scfl->source_control_file->to_version())});
8991
}
9092

9193
Json::Object resolved;
9294
for (auto&& action : action_plan.install_actions)
9395
{
9496
Json::Object resolved_item;
95-
if (map.find(action.spec.to_string()) != map.end())
97+
auto spec = action.spec.to_string();
98+
const auto found = map.find(spec);
99+
if (found != map.end())
96100
{
97-
auto pkg_url = map.at(action.spec.to_string());
101+
const auto& pkg_url = found->second;
98102
resolved_item.insert(JsonIdPackageUnderscoreUrl, pkg_url);
99103
resolved_item.insert(JsonIdRelationship, Json::Value::string(JsonIdDirect));
100104
Json::Array deps_list;
101105
for (auto&& dep : action.package_dependencies)
102106
{
103-
if (map.find(dep.to_string()) != map.end())
107+
const auto found_dep = map.find(dep.to_string());
108+
if (found_dep != map.end())
104109
{
105-
auto dep_pkg_url = map.at(dep.to_string());
106-
deps_list.push_back(dep_pkg_url);
110+
deps_list.push_back(found_dep->second);
107111
}
108112
}
109113
resolved_item.insert(JsonIdDependencies, deps_list);
110114
resolved.insert(pkg_url, resolved_item);
111115
}
112116
}
117+
113118
manifest.insert(JsonIdResolved, resolved);
114119
Json::Object manifests;
115120
manifests.insert(JsonIdVcpkgDotJson, manifest);
116121
snapshot.insert(JsonIdManifests, manifests);
117-
118122
Debug::print(Json::stringify(snapshot));
119123
return snapshot;
120124
}

src/vcpkg/configuration.cpp

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -441,20 +441,20 @@ namespace
441441
continue;
442442
}
443443

444-
if (!el.second.is_object())
444+
auto maybe_demand_obj = el.second.maybe_object();
445+
if (!maybe_demand_obj)
445446
{
446447
r.add_generic_error(type_name(), msg::format(msgJsonFieldNotObject, msg::json_field = key));
447448
continue;
448449
}
449450

450-
const auto& demand_obj = el.second.object(VCPKG_LINE_INFO);
451-
if (demand_obj.contains(JsonIdDemands))
451+
if (maybe_demand_obj->contains(JsonIdDemands))
452452
{
453453
r.add_generic_error(type_name(),
454454
msg::format(msgConfigurationNestedDemands, msg::json_field = el.first));
455455
}
456456

457-
auto maybe_demand = r.visit(demand_obj, CeMetadataDeserializer::instance);
457+
auto maybe_demand = r.visit(*maybe_demand_obj, CeMetadataDeserializer::instance);
458458
if (maybe_demand.has_value())
459459
{
460460
ret.insert_or_replace(key, maybe_demand.value_or_exit(VCPKG_LINE_INFO));
@@ -602,13 +602,14 @@ namespace
602602
auto serialize_demands = [](const Json::Object& obj, Json::Object& put_into) {
603603
if (auto demands = obj.get(JsonIdDemands))
604604
{
605-
if (!demands->is_object())
605+
auto demands_obj = demands->maybe_object();
606+
if (!demands_obj)
606607
{
607608
return;
608609
}
609610

610611
Json::Object serialized_demands;
611-
for (const auto& el : demands->object(VCPKG_LINE_INFO))
612+
for (const auto& el : *demands_obj)
612613
{
613614
auto key = el.first;
614615
if (Strings::starts_with(key, "$"))
@@ -617,10 +618,10 @@ namespace
617618
continue;
618619
}
619620

620-
if (el.second.is_object())
621+
if (auto demand_obj = el.second.maybe_object())
621622
{
622623
auto& inserted = serialized_demands.insert_or_replace(key, Json::Object{});
623-
serialize_ce_metadata(el.second.object(VCPKG_LINE_INFO), inserted);
624+
serialize_ce_metadata(*demand_obj, inserted);
624625
}
625626
}
626627
put_into.insert_or_replace(JsonIdDemands, serialized_demands);
@@ -667,12 +668,13 @@ namespace
667668

668669
if (el.first == JsonIdDemands)
669670
{
670-
if (!el.second.is_object())
671+
auto maybe_demands_object = el.second.maybe_object();
672+
if (!maybe_demands_object)
671673
{
672674
continue;
673675
}
674676

675-
for (const auto& demand : el.second.object(VCPKG_LINE_INFO))
677+
for (const auto& demand : *maybe_demands_object)
676678
{
677679
if (Strings::starts_with(demand.first, "$"))
678680
{
@@ -840,13 +842,13 @@ namespace vcpkg
840842
}
841843

842844
auto conf_value = std::move(conf).value(VCPKG_LINE_INFO).value;
843-
if (!conf_value.is_object())
845+
if (auto conf_value_object = conf_value.maybe_object())
844846
{
845-
messageSink.println(msgFailedToParseNoTopLevelObj, msg::path = origin);
846-
return nullopt;
847+
return parse_configuration(std::move(*conf_value_object), origin, messageSink);
847848
}
848849

849-
return parse_configuration(std::move(conf_value).object(VCPKG_LINE_INFO), origin, messageSink);
850+
messageSink.println(msgFailedToParseNoTopLevelObj, msg::path = origin);
851+
return nullopt;
850852
}
851853

852854
Optional<Configuration> parse_configuration(const Json::Object& obj, StringView origin, MessageSink& messageSink)

src/vcpkg/configure-environment.cpp

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,30 +42,32 @@ namespace
4242
return;
4343
}
4444

45-
auto acquired_artifacts = pparsed->get(JsonIdAcquiredArtifacts);
46-
if (acquired_artifacts)
45+
if (auto acquired_artifacts = pparsed->get(JsonIdAcquiredArtifacts))
4746
{
48-
if (acquired_artifacts->is_string())
47+
if (auto maybe_acquired_string = acquired_artifacts->maybe_string())
4948
{
50-
get_global_metrics_collector().track_string(StringMetric::AcquiredArtifacts,
51-
acquired_artifacts->string(VCPKG_LINE_INFO));
49+
get_global_metrics_collector().track_string(StringMetric::AcquiredArtifacts, *maybe_acquired_string);
50+
}
51+
else
52+
{
53+
Debug::println("Acquired artifacts was not a string.");
5254
}
53-
Debug::println("Acquired artifacts was not a string.");
5455
}
5556
else
5657
{
5758
Debug::println("No artifacts acquired.");
5859
}
5960

60-
auto activated_artifacts = pparsed->get(JsonIdActivatedArtifacts);
61-
if (activated_artifacts)
61+
if (auto activated_artifacts = pparsed->get(JsonIdActivatedArtifacts))
6262
{
63-
if (activated_artifacts->is_string())
63+
if (auto maybe_activated_string = activated_artifacts->maybe_string())
64+
{
65+
get_global_metrics_collector().track_string(StringMetric::ActivatedArtifacts, *maybe_activated_string);
66+
}
67+
else
6468
{
65-
get_global_metrics_collector().track_string(StringMetric::ActivatedArtifacts,
66-
activated_artifacts->string(VCPKG_LINE_INFO));
69+
Debug::println("Activated artifacts was not a string.");
6770
}
68-
Debug::println("Activated artifacts was not a string.");
6971
}
7072
else
7173
{

src/vcpkg/sourceparagraph.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,9 +1194,9 @@ namespace vcpkg
11941194

11951195
if (auto configuration = obj.get(JsonIdVcpkgConfiguration))
11961196
{
1197-
if (configuration->is_object())
1197+
if (auto configuration_object = configuration->maybe_object())
11981198
{
1199-
spgh.vcpkg_configuration.emplace(configuration->object(VCPKG_LINE_INFO));
1199+
spgh.vcpkg_configuration.emplace(*configuration_object);
12001200
}
12011201
else
12021202
{

0 commit comments

Comments
 (0)