2
0
mirror of https://github.com/boostorg/redis.git synced 2026-01-19 16:52:08 +00:00

Draft version without consume_one implementation

This commit is contained in:
Nikolai Vladimirov
2025-06-27 19:37:37 +00:00
committed by Marcelo Zimbres
parent c9375a44eb
commit ccb17f89cd
5 changed files with 128 additions and 0 deletions

View File

@@ -12,6 +12,7 @@
#include <boost/redis/resp3/node.hpp>
#include <boost/redis/resp3/serialization.hpp>
#include <boost/redis/resp3/type.hpp>
#include <boost/redis/response.hpp>
#include <boost/assert.hpp>
@@ -176,6 +177,33 @@ public:
}
};
template <>
class general_aggregate<result<flat_response_impl>> {
private:
result<flat_response_impl>* result_;
public:
explicit general_aggregate(result<flat_response_impl>* c = nullptr)
: result_(c)
{ }
template <class String>
void operator()(resp3::basic_node<String> const& nd, system::error_code&)
{
BOOST_ASSERT_MSG(!!result_, "Unexpected null pointer");
switch (nd.data_type) {
case resp3::type::blob_error:
case resp3::type::simple_error:
*result_ = error{
nd.data_type,
std::string{std::cbegin(nd.value), std::cend(nd.value)}
};
break;
default:
result_->value().push_back(nd);
}
}
};
template <class Node>
class general_simple {
private:

View File

@@ -107,6 +107,13 @@ struct response_traits<response<Ts...>> {
static auto adapt(response_type& r) noexcept { return adapter_type{r}; }
};
template <>
struct response_traits<generic_flat_response> {
using response_type = generic_flat_response;
using adapter_type = vector_adapter<response_type>;
static auto adapt(response_type& v) noexcept { return adapter_type{v}; }
};
} // namespace boost::redis::adapter::detail
#endif // BOOST_REDIS_ADAPTER_DETAIL_RESPONSE_TRAITS_HPP

View File

@@ -13,6 +13,7 @@
#include <boost/redis/error.hpp>
#include <boost/redis/ignore.hpp>
#include <boost/redis/resp3/type.hpp>
#include <boost/redis/response.hpp>
#include <boost/mp11.hpp>
@@ -62,6 +63,13 @@ struct result_traits<result<std::vector<resp3::basic_node<String>, Allocator>>>
static auto adapt(response_type& v) noexcept { return adapter_type{&v}; }
};
template <>
struct result_traits<generic_flat_response> {
using response_type = generic_flat_response;
using adapter_type = adapter::detail::general_aggregate<response_type>;
static auto adapt(response_type& v) noexcept { return adapter_type{&v}; }
};
template <class T>
using adapter_t = typename result_traits<std::decay_t<T>>::adapter_type;

View File

@@ -59,6 +59,14 @@ using node = basic_node<std::string>;
/// A node in the response tree that does not own its data.
using node_view = basic_node<std::string_view>;
/**
* TODO: documentation
*/
struct offset_node : node_view {
std::size_t offset{};
std::size_t size{};
};
} // namespace boost::redis::resp3
#endif // BOOST_REDIS_RESP3_NODE_HPP

View File

@@ -31,6 +31,83 @@ using response = std::tuple<adapter::result<Ts>...>;
*/
using generic_response = adapter::result<std::vector<resp3::node>>;
struct flat_response_impl {
private:
class iterator {
public:
using value_type = resp3::node_view;
using difference_type = std::ptrdiff_t;
using pointer = void;
using reference = value_type;
using iterator_category = std::forward_iterator_tag;
explicit iterator(flat_response_impl* owner, std::size_t i) noexcept
: owner_(owner)
, index_(i)
{ }
value_type operator*() const { return owner_->operator[](index_); }
iterator& operator++()
{
++index_;
return *this;
}
bool operator==(const iterator& other) const { return index_ == other.index_; }
bool operator!=(const iterator& other) const { return !(*this == other); }
private:
flat_response_impl* owner_;
std::size_t index_;
};
public:
resp3::node_view at(std::size_t index) { return make_node_view(view_.at(index)); }
std::size_t size() { return view_.size(); }
resp3::node_view operator[](std::size_t index) { return make_node_view(view_[index]); }
iterator begin() { return iterator{this, 0}; }
iterator end() { return iterator{this, view_.size()}; }
template <typename String>
void push_back(const resp3::basic_node<String>& nd)
{
resp3::offset_node new_node;
new_node.data_type = nd.data_type;
new_node.aggregate_size = nd.aggregate_size;
new_node.depth = nd.depth;
new_node.offset = data_.size();
new_node.size = nd.value.size();
data_ += std::string{std::cbegin(nd.value), std::cend(nd.value)};
view_.push_back(std::move(new_node));
}
private:
resp3::node_view make_node_view(const resp3::offset_node& n)
{
return resp3::node_view{
.data_type = n.data_type,
.aggregate_size = n.aggregate_size,
.depth = n.depth,
.value = std::string_view{data_.data() + n.offset, n.size}
};
}
std::string data_;
std::vector<resp3::offset_node> view_;
};
/**
* TODO: documentation
*/
using generic_flat_response = adapter::result<flat_response_impl>;
/** @brief Consume on response from a generic response
*
* This function rotates the elements so that the start of the next