Commit c7edd72b authored by Dominik Charousset's avatar Dominik Charousset

Merge issue/1298

Close #1298.
parents 4e9faecb 637d08e8
...@@ -227,15 +227,24 @@ public: ...@@ -227,15 +227,24 @@ public:
} }
template <class T> template <class T>
error assign(const T& x) { error assign(T&& x) {
if constexpr (detail::is_config_value_type_v<T>) { using val_t = std::decay_t<T>;
data_ = x; 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 {}; return {};
} else { } else {
config_value_writer writer{this}; config_value_writer writer{this};
if (writer.apply(x)) if (writer.apply(x))
return {}; return {};
else
return {writer.move_error()}; return {writer.move_error()};
} }
} }
......
...@@ -93,13 +93,15 @@ CAF_CORE_EXPORT config_value& put_impl(settings& dict, std::string_view name, ...@@ -93,13 +93,15 @@ CAF_CORE_EXPORT config_value& put_impl(settings& dict, std::string_view name,
config_value& value); config_value& value);
/// Converts `value` to a `config_value` and assigns it to `key`. /// 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 key Human-readable nested keys in the form `category.key`.
/// @param value New value for given `key`. /// @param value New value for given `key`.
template <class T> template <class T>
config_value& put(settings& dict, std::string_view key, T&& value) { config_value& put(settings& xs, std::string_view key, T&& value) {
config_value tmp{std::forward<T>(value)}; config_value tmp;
return put_impl(dict, key, 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` /// Converts `value` to a `config_value` and assigns it to `key` unless `xs`
...@@ -111,7 +113,8 @@ template <class T> ...@@ -111,7 +113,8 @@ template <class T>
void put_missing(settings& xs, std::string_view key, T&& value) { void put_missing(settings& xs, std::string_view key, T&& value) {
if (get_if(&xs, key) != nullptr) if (get_if(&xs, key) != nullptr)
return; 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); put_impl(xs, key, tmp);
} }
......
...@@ -80,7 +80,7 @@ BEGIN_FIXTURE_SCOPE(fixture) ...@@ -80,7 +80,7 @@ BEGIN_FIXTURE_SCOPE(fixture)
CAF_TEST(put) { CAF_TEST(put) {
put(x, "foo", "bar"); put(x, "foo", "bar");
put(x, "logger.console", "none"); put(x, "logger.console", config_value{"none"});
put(x, "one.two.three", "four"); put(x, "one.two.three", "four");
CHECK_EQ(x.size(), 3u); CHECK_EQ(x.size(), 3u);
CHECK(x.contains("foo")); CHECK(x.contains("foo"));
...@@ -194,4 +194,15 @@ SCENARIO("put_missing normalizes 'global' suffixes") { ...@@ -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() 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