7#ifndef BOOST_REDIS_ADAPTER_RESPONSE_TRAITS_HPP
8#define BOOST_REDIS_ADAPTER_RESPONSE_TRAITS_HPP
10#include <boost/redis/error.hpp>
11#include <boost/redis/resp3/type.hpp>
12#include <boost/redis/ignore.hpp>
13#include <boost/redis/adapter/detail/adapters.hpp>
14#include <boost/redis/adapter/result.hpp>
15#include <boost/redis/adapter/ignore.hpp>
16#include <boost/mp11.hpp>
23namespace boost::redis::adapter::detail
31template <
class Result>
34 static auto adapt(Result& r)
noexcept {
return adapter_type{&r}; }
39 using response_type = result<ignore_t>;
40 using adapter_type =
ignore;
41 static auto adapt(response_type)
noexcept {
return adapter_type{}; }
47 using adapter_type =
ignore;
48 static auto adapt(response_type)
noexcept {
return adapter_type{}; }
52struct result_traits<
result<resp3::basic_node<T>>> {
53 using response_type = result<resp3::basic_node<T>>;
54 using adapter_type = adapter::detail::general_simple<response_type>;
55 static auto adapt(response_type& v)
noexcept {
return adapter_type{&v}; }
58template <
class String,
class Allocator>
59struct result_traits<
result<std::vector<resp3::basic_node<String>, Allocator>>> {
60 using response_type = result<std::vector<resp3::basic_node<String>, Allocator>>;
61 using adapter_type = adapter::detail::general_aggregate<response_type>;
62 static auto adapt(response_type& v)
noexcept {
return adapter_type{&v}; }
66using adapter_t =
typename result_traits<std::decay_t<T>>::adapter_type;
69auto internal_adapt(T& t)
noexcept
70 {
return result_traits<std::decay_t<T>>::adapt(t); }
72template <std::
size_t N>
74 template <
class T1,
class T2>
75 static void assign(T1& dest, T2& from)
77 dest[N].template emplace<N>(internal_adapt(std::get<N>(from)));
78 assigner<N - 1>::assign(dest, from);
84 template <
class T1,
class T2>
85 static void assign(T1& dest, T2& from)
87 dest[0].template emplace<0>(internal_adapt(std::get<0>(from)));
92class static_aggregate_adapter;
95class static_aggregate_adapter<
result<Tuple>> {
97 using adapters_array_type =
103 std::tuple_size<Tuple>::value>;
106 std::size_t aggregate_size_ = 0;
107 adapters_array_type adapters_;
108 result<Tuple>* res_ =
nullptr;
111 explicit static_aggregate_adapter(result<Tuple>* r =
nullptr)
115 detail::assigner<std::tuple_size<Tuple>::value - 1>::assign(adapters_, r->value());
119 void count(resp3::basic_node<std::string_view>
const& nd)
122 if (is_aggregate(nd.data_type))
123 aggregate_size_ = element_multiplicity(nd.data_type) * nd.aggregate_size;
130 if (--aggregate_size_ == 0)
134 void operator()(resp3::basic_node<std::string_view>
const& nd, system::error_code& ec)
139 auto const real_aggr_size = nd.aggregate_size * element_multiplicity(nd.data_type);
140 if (real_aggr_size != std::tuple_size<Tuple>::value)
146 visit([&](
auto& arg){arg(nd, ec);}, adapters_[i_]);
151template <
class... Ts>
152struct result_traits<
result<std::tuple<Ts...>>>
154 using response_type =
result<std::tuple<Ts...>>;
155 using adapter_type = static_aggregate_adapter<response_type>;
156 static auto adapt(response_type& r)
noexcept {
return adapter_type{&r}; }
system::result< Value, error > result
Stores response to individual Redis commands.
ignore_t ignore
Global ignore object.
std::decay_t< decltype(std::ignore)> ignore_t
Type used to ignore responses.
@ incompatible_size
Aggregate container has incompatible size.