Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
28 changes: 28 additions & 0 deletions include/boost/redis/adapter/detail/adapters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down Expand Up @@ -170,6 +171,33 @@ class general_aggregate {
}
};

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:
Expand Down
8 changes: 8 additions & 0 deletions include/boost/redis/adapter/detail/response_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,14 @@ 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}; }
};

template <class Adapter>
class wrapper {
public:
Expand Down
8 changes: 8 additions & 0 deletions include/boost/redis/adapter/detail/result_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down Expand Up @@ -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;

Expand Down
8 changes: 8 additions & 0 deletions include/boost/redis/resp3/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ using node = basic_node<std::string>;
*/
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
77 changes: 77 additions & 0 deletions include/boost/redis/response.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,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
Expand Down