Skip to content

Add parse event init, node and done. #286

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 51 additions & 11 deletions include/boost/redis/adapter/any_adapter.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023 Marcelo Zimbres Silva ([email protected])
/* Copyright (c) 2018-2025 Marcelo Zimbres Silva ([email protected])
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
Expand Down Expand Up @@ -34,24 +34,41 @@ namespace boost::redis {
*/
class any_adapter {
public:
using fn_type = std::function<void(std::size_t, resp3::node_view const&, system::error_code&)>;
/** @brief Parse events that an adapter must support.
*/
enum class parse_event
{
/// Called before the parser starts processing data
init,
/// Called for each and every node of RESP3 data
node,
/// Called when done processing a complete RESP3 message
done
};

struct impl_t {
fn_type adapt_fn;
std::size_t supported_response_size;
} impl_;
/// The type erased implementation type.
using impl_t = std::function<void(parse_event, resp3::node_view const&, system::error_code&)>;

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};
return [adapter2 = boost_redis_adapt(resp)](
any_adapter::parse_event ev,
resp3::node_view const& nd,
system::error_code& ec) mutable {
switch (ev) {
case parse_event::init: adapter2.on_init(); break;
case parse_event::node: adapter2.on_node(nd, ec); break;
case parse_event::done: adapter2.on_done(); break;
}
};
}

template <class Executor>
friend class basic_connection;
/// Contructs from a type erased adaper
any_adapter(impl_t fn = [](parse_event, resp3::node_view const&, system::error_code&) { })
: impl_{std::move(fn)}
{ }

/**
* @brief Constructor.
Expand All @@ -67,6 +84,29 @@ class any_adapter {
explicit any_adapter(T& resp)
: impl_(create_impl(resp))
{ }

/// Calls the implementation with the arguments `impl_(parse_event::init, ...);`
void on_init()
{
system::error_code ec;
impl_(parse_event::init, {}, ec);
};

/// Calls the implementation with the arguments `impl_(parse_event::done, ...);`
void on_done()
{
system::error_code ec;
impl_(parse_event::done, {}, ec);
};

/// Calls the implementation with the arguments `impl_(parse_event::node, ...);`
void on_node(resp3::node_view const& nd, system::error_code& ec)
{
impl_(parse_event::node, nd, ec);
};

private:
impl_t impl_;
};

} // namespace boost::redis
Expand Down
55 changes: 43 additions & 12 deletions include/boost/redis/adapter/detail/adapters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,12 @@ class general_aggregate {
explicit general_aggregate(Result* c = nullptr)
: result_(c)
{ }

void on_init() { }
void on_done() { }

template <class String>
void operator()(resp3::basic_node<String> const& nd, system::error_code&)
void on_node(resp3::basic_node<String> const& nd, system::error_code&)
{
BOOST_ASSERT_MSG(!!result_, "Unexpected null pointer");
switch (nd.data_type) {
Expand Down Expand Up @@ -180,8 +184,11 @@ class general_simple {
: result_(t)
{ }

void on_init() { }
void on_done() { }

template <class String>
void operator()(resp3::basic_node<String> const& nd, system::error_code&)
void on_node(resp3::basic_node<String> const& nd, system::error_code&)
{
BOOST_ASSERT_MSG(!!result_, "Unexpected null pointer");
switch (nd.data_type) {
Expand All @@ -206,8 +213,11 @@ class simple_impl {
public:
void on_value_available(Result&) { }

void on_init() { }
void on_done() { }

template <class String>
void operator()(Result& result, resp3::basic_node<String> const& node, system::error_code& ec)
void on_node(Result& result, resp3::basic_node<String> const& node, system::error_code& ec)
{
if (is_aggregate(node.data_type)) {
ec = redis::error::expects_resp3_simple_type;
Expand All @@ -226,8 +236,11 @@ class set_impl {
public:
void on_value_available(Result& result) { hint_ = std::end(result); }

void on_init() { }
void on_done() { }

template <class String>
void operator()(Result& result, resp3::basic_node<String> const& nd, system::error_code& ec)
void on_node(Result& result, resp3::basic_node<String> const& nd, system::error_code& ec)
{
if (is_aggregate(nd.data_type)) {
if (nd.data_type != resp3::type::set)
Expand Down Expand Up @@ -257,8 +270,11 @@ class map_impl {
public:
void on_value_available(Result& result) { current_ = std::end(result); }

void on_init() { }
void on_done() { }

template <class String>
void operator()(Result& result, resp3::basic_node<String> const& nd, system::error_code& ec)
void on_node(Result& result, resp3::basic_node<String> const& nd, system::error_code& ec)
{
if (is_aggregate(nd.data_type)) {
if (element_multiplicity(nd.data_type) != 2)
Expand Down Expand Up @@ -292,8 +308,11 @@ class vector_impl {
public:
void on_value_available(Result&) { }

void on_init() { }
void on_done() { }

template <class String>
void operator()(Result& result, resp3::basic_node<String> const& nd, system::error_code& ec)
void on_node(Result& result, resp3::basic_node<String> const& nd, system::error_code& ec)
{
if (is_aggregate(nd.data_type)) {
auto const m = element_multiplicity(nd.data_type);
Expand All @@ -313,8 +332,11 @@ class array_impl {
public:
void on_value_available(Result&) { }

void on_init() { }
void on_done() { }

template <class String>
void operator()(Result& result, resp3::basic_node<String> const& nd, system::error_code& ec)
void on_node(Result& result, resp3::basic_node<String> const& nd, system::error_code& ec)
{
if (is_aggregate(nd.data_type)) {
if (i_ != -1) {
Expand Down Expand Up @@ -344,8 +366,11 @@ template <class Result>
struct list_impl {
void on_value_available(Result&) { }

void on_init() { }
void on_done() { }

template <class String>
void operator()(Result& result, resp3::basic_node<String> const& nd, system::error_code& ec)
void on_node(Result& result, resp3::basic_node<String> const& nd, system::error_code& ec)
{
if (!is_aggregate(nd.data_type)) {
BOOST_ASSERT(nd.aggregate_size == 1);
Expand Down Expand Up @@ -468,8 +493,11 @@ class wrapper<result<T>> {
}
}

void on_init() { impl_.on_init(); }
void on_done() { impl_.on_done(); }

template <class String>
void operator()(resp3::basic_node<String> const& nd, system::error_code& ec)
void on_node(resp3::basic_node<String> const& nd, system::error_code& ec)
{
BOOST_ASSERT_MSG(!!result_, "Unexpected null pointer");

Expand All @@ -480,7 +508,7 @@ class wrapper<result<T>> {
return;

BOOST_ASSERT(result_);
impl_(result_->value(), nd, ec);
impl_.on_node(result_->value(), nd, ec);
}
};

Expand Down Expand Up @@ -514,8 +542,11 @@ class wrapper<result<std::optional<T>>> {
: result_(o)
{ }

void on_init() { impl_.on_init(); }
void on_done() { impl_.on_done(); }

template <class String>
void operator()(resp3::basic_node<String> const& nd, system::error_code& ec)
void on_node(resp3::basic_node<String> const& nd, system::error_code& ec)
{
BOOST_ASSERT_MSG(!!result_, "Unexpected null pointer");

Expand All @@ -533,7 +564,7 @@ class wrapper<result<std::optional<T>>> {
impl_.on_value_available(result_->value().value());
}

impl_(result_->value().value(), nd, ec);
impl_.on_node(result_->value().value(), nd, ec);
}
};

Expand Down
Loading