/* Copyright (c) 2018-2023 Marcelo Zimbres Silva (mzimbres@gmail.com) * * Distributed under the Boost Software License, Version 1.0. (See * accompanying file LICENSE.txt) */ #ifndef BOOST_REDIS_ADAPTER_DETAIL_RESPONSE_TRAITS_HPP #define BOOST_REDIS_ADAPTER_DETAIL_RESPONSE_TRAITS_HPP #include #include #include #include #include #include #include #include #include namespace boost::redis::adapter::detail { class ignore_adapter { public: template void operator()(std::size_t, resp3::basic_node const& nd, system::error_code& ec) { switch (nd.data_type) { case resp3::type::simple_error: ec = redis::error::resp3_simple_error; break; case resp3::type::blob_error: ec = redis::error::resp3_blob_error; break; case resp3::type::null: ec = redis::error::resp3_null; break; default:; } } [[nodiscard]] auto get_supported_response_size() const noexcept { return static_cast(-1);} }; template class static_adapter { private: static constexpr auto size = std::tuple_size::value; using adapter_tuple = mp11::mp_transform; using variant_type = mp11::mp_rename; using adapters_array_type = std::array; adapters_array_type adapters_; public: explicit static_adapter(Response& r) { assigner::assign(adapters_, r); } [[nodiscard]] auto get_supported_response_size() const noexcept { return size;} template void operator()(std::size_t i, resp3::basic_node const& nd, system::error_code& ec) { using std::visit; // I am usure whether this should be an error or an assertion. BOOST_ASSERT(i < adapters_.size()); visit([&](auto& arg){arg(nd, ec);}, adapters_.at(i)); } }; template class vector_adapter { private: using adapter_type = typename result_traits::adapter_type; adapter_type adapter_; public: explicit vector_adapter(Vector& v) : adapter_{internal_adapt(v)} { } [[nodiscard]] auto get_supported_response_size() const noexcept { return static_cast(-1);} template void operator()(std::size_t, resp3::basic_node const& nd, system::error_code& ec) { adapter_(nd, ec); } }; template struct response_traits; template <> struct response_traits { using response_type = ignore_t; using adapter_type = detail::ignore_adapter; static auto adapt(response_type&) noexcept { return detail::ignore_adapter{}; } }; template <> struct response_traits> { using response_type = result; using adapter_type = detail::ignore_adapter; static auto adapt(response_type&) noexcept { return detail::ignore_adapter{}; } }; template struct response_traits, Allocator>>> { using response_type = result, Allocator>>; using adapter_type = vector_adapter; static auto adapt(response_type& v) noexcept { return adapter_type{v}; } }; template struct response_traits> { using response_type = response; using adapter_type = static_adapter; static auto adapt(response_type& r) noexcept { return adapter_type{r}; } }; template class wrapper { public: explicit wrapper(Adapter adapter) : adapter_{adapter} {} template void operator()(resp3::basic_node const& nd, system::error_code& ec) { return adapter_(0, nd, ec); } [[nodiscard]] auto get_supported_response_size() const noexcept { return adapter_.get_supported_response_size();} private: Adapter adapter_; }; template auto make_adapter_wrapper(Adapter adapter) { return wrapper{adapter}; } } // boost::redis::adapter::detail #endif // BOOST_REDIS_ADAPTER_DETAIL_RESPONSE_TRAITS_HPP