Loading...
Searching...
No Matches
response_traits.hpp
1/* Copyright (c) 2018-2024 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 template <class String>
27 void operator()(std::size_t, resp3::basic_node<String> 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 template <class String>
63 void operator()(std::size_t i, resp3::basic_node<String> const& nd, system::error_code& ec)
64 {
65 using std::visit;
66 // I am usure whether this should be an error or an assertion.
67 BOOST_ASSERT(i < adapters_.size());
68 visit([&](auto& arg){arg(nd, ec);}, adapters_.at(i));
69 }
70};
71
72template <class Vector>
73class vector_adapter {
74private:
75 using adapter_type = typename result_traits<Vector>::adapter_type;
76 adapter_type adapter_;
77
78public:
79 explicit vector_adapter(Vector& v)
80 : adapter_{internal_adapt(v)}
81 { }
82
83 [[nodiscard]]
84 auto
85 get_supported_response_size() const noexcept
86 { return static_cast<std::size_t>(-1);}
87
88 template <class String>
89 void operator()(std::size_t, resp3::basic_node<String> const& nd, system::error_code& ec)
90 {
91 adapter_(nd, ec);
92 }
93};
94
95template <class>
96struct response_traits;
97
98template <>
99struct response_traits<ignore_t> {
100 using response_type = ignore_t;
101 using adapter_type = detail::ignore_adapter;
102
103 static auto adapt(response_type&) noexcept
104 { return detail::ignore_adapter{}; }
105};
106
107template <>
108struct response_traits<result<ignore_t>> {
109 using response_type = result<ignore_t>;
110 using adapter_type = detail::ignore_adapter;
111
112 static auto adapt(response_type&) noexcept
113 { return detail::ignore_adapter{}; }
114};
115
116template <class String, class Allocator>
117struct response_traits<result<std::vector<resp3::basic_node<String>, Allocator>>> {
118 using response_type = result<std::vector<resp3::basic_node<String>, Allocator>>;
119 using adapter_type = vector_adapter<response_type>;
120
121 static auto adapt(response_type& v) noexcept
122 { return adapter_type{v}; }
123};
124
125template <class ...Ts>
126struct response_traits<response<Ts...>> {
127 using response_type = response<Ts...>;
128 using adapter_type = static_adapter<response_type>;
129
130 static auto adapt(response_type& r) noexcept
131 { return adapter_type{r}; }
132};
133
134template <class Adapter>
135class wrapper {
136public:
137 explicit wrapper(Adapter adapter) : adapter_{adapter} {}
138
139 template <class String>
140 void operator()(resp3::basic_node<String> const& nd, system::error_code& ec)
141 { return adapter_(0, nd, ec); }
142
143 [[nodiscard]]
144 auto get_supported_response_size() const noexcept
145 { return adapter_.get_supported_response_size();}
146
147private:
148 Adapter adapter_;
149};
150
151template <class Adapter>
152auto make_adapter_wrapper(Adapter adapter)
153{
154 return wrapper{adapter};
155}
156
157} // boost::redis::adapter::detail
158
159#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:25
@ resp3_blob_error
Got RESP3 blob_error.
@ resp3_null
Got RESP3 null.
@ resp3_simple_error
Got RESP3 simple error.