Skip to content

Commit 876d90f

Browse files
author
rsak112358
committed
fix: compatibility with the new yaml-cpp version
На MacOS падает рантайм из-за обновления yaml-cpp (коммит <jbeder/yaml-cpp@96f5c887>). Ошибка: `Error at path'additionalProperties': Wrong type. Expected YAML type'objectValue', but found 'scalarValue' When parsing manager-controller config schema GetManagerConfigSchema() ` Связанный issue: <#990> commit_hash:73fffdba35aaec0cb83ed5faaf585702148229d0
1 parent 6b5bd57 commit 876d90f

File tree

3 files changed

+36
-53
lines changed

3 files changed

+36
-53
lines changed

universal/src/formats/yaml/value.cpp

Lines changed: 5 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -11,52 +11,6 @@
1111
#include "exttypes.hpp"
1212
#include "string_view_support.hpp"
1313

14-
namespace {
15-
16-
// Helper structure for YAML conversions. YAML has built in conversion logic and
17-
// an `T Node::as<T>(U default_value)` function that uses it. We provide
18-
// `IsConvertibleChecker<T>{}` as a `default_value`, and if the
19-
// `IsConvertibleChecker` was converted to T (an implicit conversion operator
20-
// was called), then the conversion failed.
21-
template <class T>
22-
struct IsConvertibleChecker {
23-
bool& convertible;
24-
25-
operator T() const {
26-
convertible = false;
27-
return {};
28-
}
29-
};
30-
31-
} // anonymous namespace
32-
33-
namespace YAML {
34-
35-
// Reverting harm done by https://github.com/jbeder/yaml-cpp/commit/96f5c887f373ac483844c51cfc9a3621002314f0
36-
// to detect if the conversion is successful without throwing an exception
37-
template <typename T>
38-
requires std::integral<T> || std::floating_point<T>
39-
struct as_if<T, IsConvertibleChecker<T> > {
40-
explicit as_if(const Node& node_in)
41-
: node(node_in)
42-
{}
43-
const Node& node;
44-
45-
T operator()(const IsConvertibleChecker<T>& fallback) const {
46-
if (!node.m_pNode) {
47-
return fallback;
48-
}
49-
50-
T t;
51-
if (convert<T>::decode(node, t)) {
52-
return t;
53-
}
54-
return fallback;
55-
}
56-
};
57-
58-
} // namespace YAML
59-
6014
USERVER_NAMESPACE_BEGIN
6115

6216
namespace formats::yaml {
@@ -182,21 +136,19 @@ bool Value::IsConvertibleToArithmetic() const {
182136
return false;
183137
}
184138

185-
bool ok = true;
186-
value_pimpl_->as<T>(IsConvertibleChecker<T>{ok});
187-
return ok && !IsExplicitlyTypedString(*value_pimpl_);
139+
T t{};
140+
return YAML::convert<T>::decode(*value_pimpl_, t) && !IsExplicitlyTypedString(*value_pimpl_);
188141
}
189142

190143
template <class T>
191144
T Value::ValueAsArithmetic() const {
192145
CheckNotMissing();
193146

194-
bool ok = true;
195-
auto res = value_pimpl_->as<T>(IsConvertibleChecker<T>{ok});
196-
if (!ok || IsExplicitlyTypedString(*value_pimpl_)) {
147+
T t{};
148+
if (!YAML::convert<T>::decode(*value_pimpl_, t) || IsExplicitlyTypedString(*value_pimpl_)) {
197149
throw TypeMismatchException(*value_pimpl_, compiler::GetTypeName<T>(), path_.ToStringView());
198150
}
199-
return res;
151+
return t;
200152
}
201153

202154
bool Value::IsNull() const noexcept {

universal/src/formats/yaml/value_test.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,4 +146,23 @@ TEST(FormatsYaml, NodesTags) {
146146
EXPECT_EQ(yaml["field_tag_prefix"].GetTag(), "tag:example,2024:foo");
147147
}
148148

149+
TEST(FormatsYaml, IsBoolFromParsedScalar) {
150+
auto f = formats::yaml::FromString("false");
151+
auto t = formats::yaml::FromString("true");
152+
153+
EXPECT_TRUE(f.IsBool());
154+
EXPECT_TRUE(t.IsBool());
155+
EXPECT_FALSE(f.As<bool>());
156+
EXPECT_TRUE(t.As<bool>());
157+
158+
EXPECT_FALSE(formats::yaml::FromString("\"false\"").IsBool());
159+
EXPECT_FALSE(formats::yaml::FromString("hello").IsBool());
160+
}
161+
162+
TEST(FormatsYaml, IsIntFromParsedScalar) {
163+
auto v = formats::yaml::FromString("42");
164+
EXPECT_TRUE(v.IsInt());
165+
EXPECT_EQ(v.As<int>(), 42);
166+
}
167+
149168
USERVER_NAMESPACE_END

universal/src/yaml_config/merge_schemas_test.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,4 +205,16 @@ TEST(MergeSchemas, RequiredParentOnlyNoChildRequired) {
205205
EXPECT_EQ(*schema.required, (std::unordered_set<std::string>{"parent_option"}));
206206
}
207207

208+
TEST(YamlConfigSchema, AdditionalPropertiesFalse) {
209+
auto schema = yaml_config::impl::SchemaFromString(R"(
210+
type: object
211+
description: test
212+
additionalProperties: false
213+
properties: {}
214+
)");
215+
ASSERT_TRUE(schema.additional_properties.has_value());
216+
ASSERT_TRUE(std::holds_alternative<bool>(schema.additional_properties.value()));
217+
EXPECT_FALSE(std::get<bool>(schema.additional_properties.value()));
218+
}
219+
208220
USERVER_NAMESPACE_END

0 commit comments

Comments
 (0)