File indexing completed on 2025-01-18 09:51:19
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_REDIS_ADAPTER_DETAIL_RESPONSE_TRAITS_HPP
0008 #define BOOST_REDIS_ADAPTER_DETAIL_RESPONSE_TRAITS_HPP
0009
0010 #include <boost/redis/resp3/node.hpp>
0011 #include <boost/redis/response.hpp>
0012 #include <boost/redis/adapter/detail/result_traits.hpp>
0013 #include <boost/mp11.hpp>
0014 #include <boost/system.hpp>
0015
0016 #include <tuple>
0017 #include <limits>
0018 #include <string_view>
0019 #include <variant>
0020
0021 namespace boost::redis::adapter::detail
0022 {
0023
0024 class ignore_adapter {
0025 public:
0026 template <class String>
0027 void operator()(std::size_t, resp3::basic_node<String> const& nd, system::error_code& ec)
0028 {
0029 switch (nd.data_type) {
0030 case resp3::type::simple_error: ec = redis::error::resp3_simple_error; break;
0031 case resp3::type::blob_error: ec = redis::error::resp3_blob_error; break;
0032 case resp3::type::null: ec = redis::error::resp3_null; break;
0033 default:;
0034 }
0035 }
0036
0037 [[nodiscard]]
0038 auto get_supported_response_size() const noexcept
0039 { return static_cast<std::size_t>(-1);}
0040 };
0041
0042 template <class Response>
0043 class static_adapter {
0044 private:
0045 static constexpr auto size = std::tuple_size<Response>::value;
0046 using adapter_tuple = mp11::mp_transform<adapter_t, Response>;
0047 using variant_type = mp11::mp_rename<adapter_tuple, std::variant>;
0048 using adapters_array_type = std::array<variant_type, size>;
0049
0050 adapters_array_type adapters_;
0051
0052 public:
0053 explicit static_adapter(Response& r)
0054 {
0055 assigner<size - 1>::assign(adapters_, r);
0056 }
0057
0058 [[nodiscard]]
0059 auto get_supported_response_size() const noexcept
0060 { return size;}
0061
0062 template <class String>
0063 void operator()(std::size_t i, resp3::basic_node<String> const& nd, system::error_code& ec)
0064 {
0065 using std::visit;
0066
0067 BOOST_ASSERT(i < adapters_.size());
0068 visit([&](auto& arg){arg(nd, ec);}, adapters_.at(i));
0069 }
0070 };
0071
0072 template <class Vector>
0073 class vector_adapter {
0074 private:
0075 using adapter_type = typename result_traits<Vector>::adapter_type;
0076 adapter_type adapter_;
0077
0078 public:
0079 explicit vector_adapter(Vector& v)
0080 : adapter_{internal_adapt(v)}
0081 { }
0082
0083 [[nodiscard]]
0084 auto
0085 get_supported_response_size() const noexcept
0086 { return static_cast<std::size_t>(-1);}
0087
0088 template <class String>
0089 void operator()(std::size_t, resp3::basic_node<String> const& nd, system::error_code& ec)
0090 {
0091 adapter_(nd, ec);
0092 }
0093 };
0094
0095 template <class>
0096 struct response_traits;
0097
0098 template <>
0099 struct response_traits<ignore_t> {
0100 using response_type = ignore_t;
0101 using adapter_type = detail::ignore_adapter;
0102
0103 static auto adapt(response_type&) noexcept
0104 { return detail::ignore_adapter{}; }
0105 };
0106
0107 template <>
0108 struct response_traits<result<ignore_t>> {
0109 using response_type = result<ignore_t>;
0110 using adapter_type = detail::ignore_adapter;
0111
0112 static auto adapt(response_type&) noexcept
0113 { return detail::ignore_adapter{}; }
0114 };
0115
0116 template <class String, class Allocator>
0117 struct response_traits<result<std::vector<resp3::basic_node<String>, Allocator>>> {
0118 using response_type = result<std::vector<resp3::basic_node<String>, Allocator>>;
0119 using adapter_type = vector_adapter<response_type>;
0120
0121 static auto adapt(response_type& v) noexcept
0122 { return adapter_type{v}; }
0123 };
0124
0125 template <class ...Ts>
0126 struct response_traits<response<Ts...>> {
0127 using response_type = response<Ts...>;
0128 using adapter_type = static_adapter<response_type>;
0129
0130 static auto adapt(response_type& r) noexcept
0131 { return adapter_type{r}; }
0132 };
0133
0134 template <class Adapter>
0135 class wrapper {
0136 public:
0137 explicit wrapper(Adapter adapter) : adapter_{adapter} {}
0138
0139 template <class String>
0140 void operator()(resp3::basic_node<String> const& nd, system::error_code& ec)
0141 { return adapter_(0, nd, ec); }
0142
0143 [[nodiscard]]
0144 auto get_supported_response_size() const noexcept
0145 { return adapter_.get_supported_response_size();}
0146
0147 private:
0148 Adapter adapter_;
0149 };
0150
0151 template <class Adapter>
0152 auto make_adapter_wrapper(Adapter adapter)
0153 {
0154 return wrapper{adapter};
0155 }
0156
0157 }
0158
0159 #endif