From 5ccacafdb14fc0a7d7cc16e3611a2a2f372895e2 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Tue, 20 Apr 2021 13:53:35 -0300 Subject: [PATCH] Add support for std::optional send arguments If the optional is set it gets applied as if you specified the `T` in the send(...), if unset it works as if you didn't specify the argument at all. --- oxenmq/oxenmq.h | 11 ++++++++++- tests/test_commands.cpp | 10 +++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/oxenmq/oxenmq.h b/oxenmq/oxenmq.h index 3b122a0..1bde562 100644 --- a/oxenmq/oxenmq.h +++ b/oxenmq/oxenmq.h @@ -1094,7 +1094,9 @@ public: * call connect() first). * @param cmd - the first data frame value which is almost always the remote "category.command" name * @param opts - any number of std::string (or string_views) and send options. Each send option - * affects how the send works; each string becomes a message part. + * affects how the send works; each string becomes a message part. May also + * contain std::optional values: the value will be applied as a string or send + * option if set and skipped if null. * * Example: * @@ -1462,6 +1464,13 @@ inline void apply_send_option(bt_list& parts, bt_dict&, std::string_view arg) { parts.emplace_back(arg); } +/// std::optional: if the optional is set, we unwrap it and apply as a send_option, otherwise we +/// ignore it. +template +inline void apply_send_option(bt_list& parts, bt_dict& control_data, const std::optional& opt) { + if (opt) apply_send_option(parts, control_data, *opt); +} + /// `data_parts` specialization: appends a range of serialized data parts to the parts to send template void apply_send_option(bt_list& parts, bt_dict&, const send_option::data_parts_impl data) { diff --git a/tests/test_commands.cpp b/tests/test_commands.cpp index f750ecc..b0c4e24 100644 --- a/tests/test_commands.cpp +++ b/tests/test_commands.cpp @@ -415,13 +415,19 @@ TEST_CASE("data parts", "[send][data_parts]") { r.clear(); } + std::optional opt1, opt2; + std::optional opt3, opt4; + opt1 = "o1"sv; + opt4 = "o4"s; std::vector some_data2{{"a"sv, "b"sv, "\0"sv}}; client.send(c, "public.hello", "hi", oxenmq::send_option::data_parts(some_data2.begin(), some_data2.end()), "another", "string"sv, - oxenmq::send_option::data_parts(some_data.begin(), some_data.end())); + oxenmq::send_option::data_parts(some_data.begin(), some_data.end()), + opt1, opt2, opt3, opt4 + ); std::vector expected; expected.push_back("hi"); @@ -429,6 +435,8 @@ TEST_CASE("data parts", "[send][data_parts]") { expected.push_back("another"); expected.push_back("string"); expected.insert(expected.end(), some_data.begin(), some_data.end()); + expected.push_back("o1"); + expected.push_back("o4"); reply_sleep(); {