boost_redis 1.4.2
A redis client library
response_traits.hpp
1/* Copyright (c) 2018-2022 Marcelo Zimbres Silva (mzimbres@gmail.com)
2 *
3 * Distributed under the Boost Software License, Version 1.0. (See
4 * accompanying file LICENSE.txt)
5 */
6
7#ifndef BOOST_REDIS_ADAPTER_DETAIL_RESPONSE_TRAITS_HPP
8#define BOOST_REDIS_ADAPTER_DETAIL_RESPONSE_TRAITS_HPP
9
10#include <boost/redis/resp3/node.hpp>
11#include <boost/redis/response.hpp>
12#include <boost/redis/adapter/detail/result_traits.hpp>
13#include <boost/mp11.hpp>
14#include <boost/system.hpp>
15
16#include <tuple>
17#include <limits>
18#include <string_view>
19#include <variant>
20
21namespace boost::redis::adapter::detail
22{
23
24class ignore_adapter {
25public:
26 void
27 operator()(std::size_t, resp3::basic_node<std::string_view> const& nd, system::error_code& ec)
28 {
29 switch (nd.data_type) {
33 default:;
34 }
35 }
36
37 [[nodiscard]]
38 auto get_supported_response_size() const noexcept
39 { return static_cast<std::size_t>(-1);}
40};
41
42template <class Response>
43class static_adapter {
44private:
45 static constexpr auto size = std::tuple_size<Response>::value;
46 using adapter_tuple = mp11::mp_transform<adapter_t, Response>;
47 using variant_type = mp11::mp_rename<adapter_tuple, std::variant>;
48 using adapters_array_type = std::array<variant_type, size>;
49
50 adapters_array_type adapters_;
51
52public:
53 explicit static_adapter(Response& r)
54 {
55 assigner<size - 1>::assign(adapters_, r);
56 }
57
58 [[nodiscard]]
59 auto get_supported_response_size() const noexcept
60 { return size;}
61
62 void
63 operator()(
64 std::size_t i,
65 resp3::basic_node<std::string_view> const& nd,
66 system::error_code& ec)
67 {
68 using std::visit;
69 // I am usure whether this should be an error or an assertion.
70 BOOST_ASSERT(i < adapters_.size());
71 visit([&](auto& arg){arg(nd, ec);}, adapters_.at(i));
72 }
73};
74
75template <class Vector>
76class vector_adapter {
77private:
78 using adapter_type = typename result_traits<Vector>::adapter_type;
79 adapter_type adapter_;
80
81public:
82 explicit vector_adapter(Vector& v)
83 : adapter_{internal_adapt(v)}
84 { }
85
86 [[nodiscard]]
87 auto
88 get_supported_response_size() const noexcept
89 { return static_cast<std::size_t>(-1);}
90
91 void
92 operator()(
93 std::size_t,
94 resp3::basic_node<std::string_view> const& nd,
95 system::error_code& ec)
96 {
97 adapter_(nd, ec);
98 }
99};
100
101template <class>
102struct response_traits;
103
104template <>
105struct response_traits<ignore_t> {
106 using response_type = ignore_t;
107 using adapter_type = detail::ignore_adapter;
108
109 static auto adapt(response_type&) noexcept
110 { return detail::ignore_adapter{}; }
111};
112
113template <>
114struct response_traits<result<ignore_t>> {
115 using response_type = result<ignore_t>;
116 using adapter_type = detail::ignore_adapter;
117
118 static auto adapt(response_type&) noexcept
119 { return detail::ignore_adapter{}; }
120};
121
122template <class String, class Allocator>
123struct response_traits<result<std::vector<resp3::basic_node<String>, Allocator>>> {
124 using response_type = result<std::vector<resp3::basic_node<String>, Allocator>>;
125 using adapter_type = vector_adapter<response_type>;
126
127 static auto adapt(response_type& v) noexcept
128 { return adapter_type{v}; }
129};
130
131template <class ...Ts>
132struct response_traits<response<Ts...>> {
133 using response_type = response<Ts...>;
134 using adapter_type = static_adapter<response_type>;
135
136 static auto adapt(response_type& r) noexcept
137 { return adapter_type{r}; }
138};
139
140template <class Adapter>
141class wrapper {
142public:
143 explicit wrapper(Adapter adapter) : adapter_{adapter} {}
144
145 void operator()(resp3::basic_node<std::string_view> const& nd, system::error_code& ec)
146 { return adapter_(0, nd, ec); }
147
148 [[nodiscard]]
149 auto get_supported_response_size() const noexcept
150 { return adapter_.get_supported_response_size();}
151
152private:
153 Adapter adapter_;
154};
155
156template <class Adapter>
157auto make_adapter_wrapper(Adapter adapter)
158{
159 return wrapper{adapter};
160}
161
162} // boost::redis::adapter::detail
163
164#endif // BOOST_REDIS_ADAPTER_DETAIL_RESPONSE_TRAITS_HPP
system::result< Value, error > result
Stores response to individual Redis commands.
Definition: result.hpp:56
std::decay_t< decltype(std::ignore)> ignore_t
Type used to ignore responses.
Definition: ignore.hpp:31
std::tuple< adapter::result< Ts >... > response
Response with compile-time size.
Definition: response.hpp:23
@ resp3_blob_error
Got RESP3 blob_error.
@ resp3_null
Got RESP3 null.
@ resp3_simple_error
Got RESP3 simple error.