Commit 637d08e8 authored by Dominik Charousset's avatar Dominik Charousset

Support storing custom types in settings

parent 4e9faecb
......@@ -227,15 +227,24 @@ public:
}
template <class T>
error assign(const T& x) {
if constexpr (detail::is_config_value_type_v<T>) {
data_ = x;
error assign(T&& x) {
using val_t = std::decay_t<T>;
if constexpr (std::is_convertible_v<val_t, const char*>) {
data_ = std::string{x};
return {};
} else if constexpr (std::is_same_v<val_t, config_value>) {
if constexpr (std::is_rvalue_reference_v<T&&>)
data_ = std::move(x.data_);
else
data_ = x.data_;
return {};
} else if constexpr (detail::is_config_value_type_v<val_t>) {
data_ = std::forward<T>(x);
return {};
} else {
config_value_writer writer{this};
if (writer.apply(x))
return {};
else
return {writer.move_error()};
}
}
......
......@@ -93,13 +93,15 @@ CAF_CORE_EXPORT config_value& put_impl(settings& dict, std::string_view name,
config_value& value);
/// Converts `value` to a `config_value` and assigns it to `key`.
/// @param dict Dictionary of key-value pairs.
/// @param xs Dictionary of key-value pairs.
/// @param key Human-readable nested keys in the form `category.key`.
/// @param value New value for given `key`.
template <class T>
config_value& put(settings& dict, std::string_view key, T&& value) {
config_value tmp{std::forward<T>(value)};
return put_impl(dict, key, tmp);
config_value& put(settings& xs, std::string_view key, T&& value) {
config_value tmp;
if (auto err = tmp.assign(std::forward<T>(value)); err)
tmp = none;
return put_impl(xs, key, tmp);
}
/// Converts `value` to a `config_value` and assigns it to `key` unless `xs`
......@@ -111,7 +113,8 @@ template <class T>
void put_missing(settings& xs, std::string_view key, T&& value) {
if (get_if(&xs, key) != nullptr)
return;
config_value tmp{std::forward<T>(value)};
config_value tmp;
if (auto err = tmp.assign(std::forward<T>(value)); !err)
put_impl(xs, key, tmp);
}
......
......@@ -80,7 +80,7 @@ BEGIN_FIXTURE_SCOPE(fixture)
CAF_TEST(put) {
put(x, "foo", "bar");
put(x, "logger.console", "none");
put(x, "logger.console", config_value{"none"});
put(x, "one.two.three", "four");
CHECK_EQ(x.size(), 3u);
CHECK(x.contains("foo"));
......@@ -194,4 +194,15 @@ SCENARIO("put_missing normalizes 'global' suffixes") {
}
}
TEST_CASE("put and put_missing decomposes user-defined types") {
settings uut;
put(uut, "dummy", dummy_struct{42, "foo"});
CHECK_EQ(get_as<int>(uut, "dummy.a"), 42);
CHECK_EQ(get_as<std::string>(uut, "dummy.b"), "foo"s);
uut.clear();
put_missing(uut, "dummy", dummy_struct{23, "bar"});
CHECK_EQ(get_as<int>(uut, "dummy.a"), 23);
CHECK_EQ(get_as<std::string>(uut, "dummy.b"), "bar"s);
}
END_FIXTURE_SCOPE()
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