Commit 99972912 authored by Dominik Charousset's avatar Dominik Charousset

Improve parsing of booleans from config values

parent 70af2bb9
...@@ -220,7 +220,7 @@ expected<bool> config_value::to_boolean() const { ...@@ -220,7 +220,7 @@ expected<bool> config_value::to_boolean() const {
using result_type = expected<bool>; using result_type = expected<bool>;
auto f = detail::make_overload( auto f = detail::make_overload(
no_conversions<bool, none_t, integer, real, timespan, uri, no_conversions<bool, none_t, integer, real, timespan, uri,
config_value::list, config_value::dictionary>(), config_value::list>(),
[](boolean x) { return result_type{x}; }, [](boolean x) { return result_type{x}; },
[](const std::string& x) { [](const std::string& x) {
if (x == "true") { if (x == "true") {
...@@ -233,6 +233,31 @@ expected<bool> config_value::to_boolean() const { ...@@ -233,6 +233,31 @@ expected<bool> config_value::to_boolean() const {
msg += " to a boolean"; msg += " to a boolean";
return result_type{make_error(sec::conversion_failed, std::move(msg))}; return result_type{make_error(sec::conversion_failed, std::move(msg))};
} }
},
[](const dictionary& x) {
if (auto i = x.find("@type");
i != x.end() && holds_alternative<std::string>(i->second)) {
const auto& tn = get<std::string>(i->second);
if (tn == type_name_v<bool>) {
if (auto j = x.find("value"); j != x.end()) {
return j->second.to_boolean();
} else {
std::string msg = "missing value for object of type ";
msg += tn;
return result_type{
make_error(sec::conversion_failed, std::move(msg))};
}
} else {
std::string msg = "cannot convert ";
msg += tn;
msg += " to a boolean";
return result_type{
make_error(sec::conversion_failed, std::move(msg))};
}
} else {
std::string msg = "cannot convert a dictionary to a boolean";
return result_type{make_error(sec::conversion_failed, std::move(msg))};
}
}); });
return visit(f, data_); return visit(f, data_);
} }
......
...@@ -97,6 +97,16 @@ SCENARIO("get_as can convert config values to boolean") { ...@@ -97,6 +97,16 @@ SCENARIO("get_as can convert config values to boolean") {
} }
} }
} }
GIVEN("a config value with type annotation 'bool' and the value \"true\"") {
config_value x;
x.as_dictionary().emplace("@type", "bool");
x.as_dictionary().emplace("value", "true");
WHEN("using get_as with bool") {
THEN("conversion succeeds") {
CHECK_EQ(get_as<bool>(x), true);
}
}
}
GIVEN("non-boolean config_values") { GIVEN("non-boolean config_values") {
WHEN("using get_as with bool") { WHEN("using get_as with bool") {
THEN("conversion fails") { THEN("conversion fails") {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment