Specialize ConfigOption for bool to accept "truthy" / "falsy" values

This commit is contained in:
Stephen Shelton 2020-04-29 12:32:07 -06:00
parent 331770b348
commit 320564d792
No known key found for this signature in database
GPG Key ID: EE4BADACCE8B631C
3 changed files with 41 additions and 5 deletions

View File

@ -16,6 +16,18 @@ namespace llarp
{
}
template <>
bool
OptionDefinition<bool>::fromString(const std::string& input)
{
if (input == "false" || input == "off" || input == "0" || input == "no")
return false;
else if (input == "true" || input == "on" || input == "1" || input == "yes")
return true;
else
throw std::invalid_argument(stringify(input, " is not a valid bool"));
}
ConfigDefinition&
ConfigDefinition::defineOption(OptionDefinition_ptr def)
{

View File

@ -168,17 +168,19 @@ namespace llarp
stringify("duplicate value for ", name, ", previous value: ", parsedValues[0]));
}
parsedValues.emplace_back(fromString(input));
}
T
fromString(const std::string& input)
{
std::istringstream iss(input);
T t;
iss >> t;
if (iss.fail())
{
throw std::invalid_argument(stringify(input, " is not a valid ", typeid(T).name()));
}
else
{
parsedValues.emplace_back(std::move(t));
}
return t;
}
std::string
@ -239,6 +241,12 @@ namespace llarp
std::function<void(T)> acceptor;
};
/// Specialization for bool types. We don't want to use stringstream parsing in this
/// case because we want to accept "truthy" and "falsy" string values (e.g. "off" == false)
template <>
bool
OptionDefinition<bool>::fromString(const std::string& input);
using UndeclaredValueHandler =
std::function<void(string_view section, string_view name, string_view value)>;

View File

@ -387,3 +387,19 @@ TEST_CASE("ConfigDefinition [bind]iface regression", "[config regression]")
CHECK(undeclaredName == "enp35s0");
CHECK(undeclaredValue == "1091");
}
TEST_CASE("ConfigDefinition truthy bool values", "[config]")
{
llarp::OptionDefinition<bool> def("foo", "bar", false, true);
// defaults to true
auto maybe = def.getValue();
CHECK(maybe.has_value());
CHECK(maybe.value() == true);
// "off" should result in false
CHECK_NOTHROW(def.parseValue("off"));
maybe = def.getValue();
CHECK(maybe.has_value());
CHECK(maybe.value() == false);
}