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:
committed by
Marcelo Zimbres
parent
c9375a44eb
commit
ccb17f89cd
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user