Skip to content

Commit d182276

Browse files
committed
Added any_adapter
1 parent a4d2bb9 commit d182276

File tree

3 files changed

+82
-8
lines changed

3 files changed

+82
-8
lines changed

include/boost/redis/any_adapter.hpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/* Copyright (c) 2018-2023 Marcelo Zimbres Silva ([email protected])
2+
*
3+
* Distributed under the Boost Software License, Version 1.0. (See
4+
* accompanying file LICENSE.txt)
5+
*/
6+
7+
#ifndef BOOST_REDIS_ANY_ADAPTER_HPP
8+
#define BOOST_REDIS_ANY_ADAPTER_HPP
9+
10+
11+
#include <boost/redis/resp3/node.hpp>
12+
#include <boost/redis/adapter/adapt.hpp>
13+
#include <boost/system/detail/error_code.hpp>
14+
#include <cstddef>
15+
#include <functional>
16+
#include <string_view>
17+
#include <type_traits>
18+
19+
namespace boost::redis {
20+
21+
class any_adapter
22+
{
23+
using fn_type = std::function<void(std::size_t, resp3::basic_node<std::string_view> const&, system::error_code&)>;
24+
25+
struct impl_t {
26+
fn_type adapt_fn;
27+
std::size_t supported_response_size;
28+
} impl_;
29+
30+
template <class T>
31+
static auto create_impl(T& response) -> impl_t
32+
{
33+
using namespace boost::redis::adapter;
34+
auto adapter = boost_redis_adapt(response);
35+
std::size_t size = adapter.get_supported_response_size();
36+
return { std::move(adapter), size };
37+
}
38+
39+
public:
40+
template <class T, class = std::enable_if_t<!std::is_same_v<T, any_adapter>>>
41+
explicit any_adapter(T& response) : impl_(create_impl(response)) {}
42+
43+
// TODO: make this private
44+
auto get_impl() && { return std::move(impl_); }
45+
};
46+
47+
}
48+
49+
#endif

include/boost/redis/connection.hpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#ifndef BOOST_REDIS_CONNECTION_HPP
88
#define BOOST_REDIS_CONNECTION_HPP
99

10+
#include <boost/redis/any_adapter.hpp>
1011
#include <boost/redis/detail/connection_base.hpp>
1112
#include <boost/redis/logger.hpp>
1213
#include <boost/redis/config.hpp>
@@ -256,7 +257,18 @@ class basic_connection {
256257
Response& resp = ignore,
257258
CompletionToken&& token = CompletionToken{})
258259
{
259-
return impl_.async_exec(req, resp, std::forward<CompletionToken>(token));
260+
return impl_.async_exec(req, any_adapter(resp), std::forward<CompletionToken>(token));
261+
}
262+
263+
264+
template <class CompletionToken = asio::default_completion_token_t<executor_type>>
265+
auto
266+
async_exec(
267+
request const& req,
268+
any_adapter adapter,
269+
CompletionToken&& token = CompletionToken{})
270+
{
271+
return impl_.async_exec(req, std::move(adapter), std::forward<CompletionToken>(token));
260272
}
261273

262274
/** @brief Cancel operations.
@@ -394,7 +406,13 @@ class connection {
394406
template <class Response, class CompletionToken>
395407
auto async_exec(request const& req, Response& resp, CompletionToken token)
396408
{
397-
return impl_.async_exec(req, resp, std::move(token));
409+
return async_exec(req, any_adapter(resp), std::move(token));
410+
}
411+
412+
template <class CompletionToken>
413+
auto async_exec(request const& req, any_adapter adapter, CompletionToken token)
414+
{
415+
return impl_.async_exec(req, std::move(adapter), std::move(token));
398416
}
399417

400418
/// Calls `boost::redis::basic_connection::cancel`.

include/boost/redis/detail/connection_base.hpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#ifndef BOOST_REDIS_CONNECTION_BASE_HPP
88
#define BOOST_REDIS_CONNECTION_BASE_HPP
99

10+
#include <boost/redis/any_adapter.hpp>
1011
#include <boost/redis/adapter/adapt.hpp>
1112
#include <boost/redis/detail/helper.hpp>
1213
#include <boost/redis/error.hpp>
@@ -39,6 +40,7 @@
3940
#include <string_view>
4041
#include <type_traits>
4142
#include <functional>
43+
#include <utility>
4244

4345
namespace boost::redis::detail
4446
{
@@ -440,21 +442,26 @@ class connection_base {
440442
cancel_impl(op);
441443
}
442444

443-
template <class Response, class CompletionToken>
444-
auto async_exec(request const& req, Response& resp, CompletionToken token)
445+
template <class CompletionToken>
446+
auto async_exec(request const& req, any_adapter adapter, CompletionToken token)
445447
{
446-
using namespace boost::redis::adapter;
447-
auto f = boost_redis_adapt(resp);
448-
BOOST_ASSERT_MSG(req.get_expected_responses() <= f.get_supported_response_size(), "Request and response have incompatible sizes.");
448+
auto adapter_impl = std::move(adapter).get_impl();
449+
BOOST_ASSERT_MSG(req.get_expected_responses() <= adapter_impl.supported_response_size, "Request and response have incompatible sizes.");
449450

450-
auto info = std::make_shared<req_info>(req, f, get_executor());
451+
auto info = std::make_shared<req_info>(req, std::move(adapter_impl.adapt_fn), get_executor());
451452

452453
return asio::async_compose
453454
< CompletionToken
454455
, void(system::error_code, std::size_t)
455456
>(exec_op<this_type>{this, info}, token, writer_timer_);
456457
}
457458

459+
template <class Response, class CompletionToken>
460+
auto async_exec(request const& req, Response& resp, CompletionToken token)
461+
{
462+
return async_exec(req, any_adapter(resp), std::forward<CompletionToken>(token));
463+
}
464+
458465
template <class Response, class CompletionToken>
459466
[[deprecated("Set the response with set_receive_response and use the other overload.")]]
460467
auto async_receive(Response& response, CompletionToken token)

0 commit comments

Comments
 (0)