-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #201 from anarthal/feature/type-erased-response
Adds a type-erased response adapter to the public API
- Loading branch information
Showing
10 changed files
with
218 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/* Copyright (c) 2018-2023 Marcelo Zimbres Silva ([email protected]) | ||
* | ||
* Distributed under the Boost Software License, Version 1.0. (See | ||
* accompanying file LICENSE.txt) | ||
*/ | ||
|
||
#ifndef BOOST_REDIS_ANY_ADAPTER_HPP | ||
#define BOOST_REDIS_ANY_ADAPTER_HPP | ||
|
||
|
||
#include <boost/redis/resp3/node.hpp> | ||
#include <boost/redis/adapter/adapt.hpp> | ||
#include <boost/system/error_code.hpp> | ||
#include <cstddef> | ||
#include <functional> | ||
#include <string_view> | ||
#include <type_traits> | ||
|
||
namespace boost::redis { | ||
|
||
namespace detail { | ||
|
||
// Forward decl | ||
template <class Executor> | ||
class connection_base; | ||
|
||
} | ||
|
||
/** @brief A type-erased reference to a response. | ||
* @ingroup high-level-api | ||
* | ||
* A type-erased response adapter. It can be executed using @ref connection::async_exec. | ||
* Using this type instead of raw response references enables separate compilation. | ||
* | ||
* Given a response object `resp` that can be passed to `async_exec`, the following two | ||
* statements have the same effect: | ||
* ``` | ||
* co_await conn.async_exec(req, resp); | ||
* co_await conn.async_exec(req, any_response(resp)); | ||
* ``` | ||
*/ | ||
class any_adapter | ||
{ | ||
using fn_type = std::function<void(std::size_t, resp3::basic_node<std::string_view> const&, system::error_code&)>; | ||
|
||
struct impl_t { | ||
fn_type adapt_fn; | ||
std::size_t supported_response_size; | ||
} impl_; | ||
|
||
template <class T> | ||
static auto create_impl(T& resp) -> impl_t | ||
{ | ||
using namespace boost::redis::adapter; | ||
auto adapter = boost_redis_adapt(resp); | ||
std::size_t size = adapter.get_supported_response_size(); | ||
return { std::move(adapter), size }; | ||
} | ||
|
||
template <class Executor> | ||
friend class detail::connection_base; | ||
|
||
public: | ||
/** | ||
* @brief Constructor. | ||
* | ||
* Creates a type-erased response adapter from `resp` by calling | ||
* `boost_redis_adapt`. `T` must be a valid Redis response type. | ||
* Any type passed to @ref connection::async_exec qualifies. | ||
* | ||
* This object stores a reference to `resp`, which must be kept alive | ||
* while `*this` is being used. | ||
*/ | ||
template <class T, class = std::enable_if_t<!std::is_same_v<T, any_adapter>>> | ||
explicit any_adapter(T& resp) : impl_(create_impl(resp)) {} | ||
}; | ||
|
||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,6 +51,7 @@ local tests = | |
test_low_level | ||
test_request | ||
test_run | ||
test_any_adapter | ||
; | ||
|
||
# Build and run the tests | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* Copyright (c) 2018-2022 Marcelo Zimbres Silva ([email protected]) | ||
* | ||
* Distributed under the Boost Software License, Version 1.0. (See | ||
* accompanying file LICENSE.txt) | ||
*/ | ||
|
||
#include <boost/redis/ignore.hpp> | ||
#include <boost/redis/response.hpp> | ||
#include <boost/redis/adapter/any_adapter.hpp> | ||
#include <string> | ||
#define BOOST_TEST_MODULE any_adapter | ||
#include <boost/test/included/unit_test.hpp> | ||
|
||
using boost::redis::generic_response; | ||
using boost::redis::response; | ||
using boost::redis::ignore; | ||
using boost::redis::any_adapter; | ||
|
||
BOOST_AUTO_TEST_CASE(any_adapter_response_types) | ||
{ | ||
// any_adapter can be used with any supported responses | ||
response<int> r1; | ||
response<int, std::string> r2; | ||
generic_response r3; | ||
|
||
BOOST_CHECK_NO_THROW(any_adapter{r1}); | ||
BOOST_CHECK_NO_THROW(any_adapter{r2}); | ||
BOOST_CHECK_NO_THROW(any_adapter{r3}); | ||
BOOST_CHECK_NO_THROW(any_adapter{ignore}); | ||
} | ||
|
||
BOOST_AUTO_TEST_CASE(any_adapter_copy_move) | ||
{ | ||
// any_adapter can be copied/moved | ||
response<int, std::string> r; | ||
any_adapter ad1 {r}; | ||
|
||
// copy constructor | ||
any_adapter ad2 {ad1}; | ||
|
||
// move constructor | ||
any_adapter ad3 {std::move(ad2)}; | ||
|
||
// copy assignment | ||
BOOST_CHECK_NO_THROW(ad2 = ad1); | ||
|
||
// move assignment | ||
BOOST_CHECK_NO_THROW(ad2 = std::move(ad1)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters