Loading...
Searching...
No Matches
serialization.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_RESP3_SERIALIZATION_HPP
8#define BOOST_REDIS_RESP3_SERIALIZATION_HPP
9
10#include <boost/redis/resp3/parser.hpp>
11#include <boost/redis/resp3/type.hpp>
12
13#include <boost/system/system_error.hpp>
14#include <boost/throw_exception.hpp>
15
16#include <string>
17#include <tuple>
18
19// NOTE: Consider detecting tuples in the type in the parameter pack
20// to calculate the header size correctly.
21
22namespace boost::redis::resp3 {
23
43void boost_redis_to_bulk(std::string& payload, std::string_view data);
44
45template <class T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
46void boost_redis_to_bulk(std::string& payload, T n)
47{
48 auto const s = std::to_string(n);
49 boost::redis::resp3::boost_redis_to_bulk(payload, std::string_view{s});
50}
51
52template <class T>
53struct add_bulk_impl {
54 static void add(std::string& payload, T const& from)
55 {
56 using namespace boost::redis::resp3;
57 boost_redis_to_bulk(payload, from);
58 }
59};
60
61template <class... Ts>
62struct add_bulk_impl<std::tuple<Ts...>> {
63 static void add(std::string& payload, std::tuple<Ts...> const& t)
64 {
65 auto f = [&](auto const&... vs) {
66 using namespace boost::redis::resp3;
67 (boost_redis_to_bulk(payload, vs), ...);
68 };
69
70 std::apply(f, t);
71 }
72};
73
74template <class U, class V>
75struct add_bulk_impl<std::pair<U, V>> {
76 static void add(std::string& payload, std::pair<U, V> const& from)
77 {
78 using namespace boost::redis::resp3;
79 boost_redis_to_bulk(payload, from.first);
80 boost_redis_to_bulk(payload, from.second);
81 }
82};
83
84void add_header(std::string& payload, type t, std::size_t size);
85
86template <class T>
87void add_bulk(std::string& payload, T const& data)
88{
89 add_bulk_impl<T>::add(payload, data);
90}
91
92template <class>
93struct bulk_counter;
94
95template <class>
96struct bulk_counter {
97 static constexpr auto size = 1U;
98};
99
100template <class T, class U>
101struct bulk_counter<std::pair<T, U>> {
102 static constexpr auto size = 2U;
103};
104
105void add_blob(std::string& payload, std::string_view blob);
106void add_separator(std::string& payload);
107
108namespace detail {
109
110template <class Adapter>
111void deserialize(std::string_view const& data, Adapter adapter, system::error_code& ec)
112{
113 parser parser;
114 while (!parser.done()) {
115 auto const res = parser.consume(data, ec);
116 if (ec)
117 return;
118
119 BOOST_ASSERT(res.has_value());
120
121 adapter(res.value(), ec);
122 if (ec)
123 return;
124 }
125
126 BOOST_ASSERT(parser.get_consumed() == std::size(data));
127}
128
129template <class Adapter>
130void deserialize(std::string_view const& data, Adapter adapter)
131{
132 system::error_code ec;
133 deserialize(data, adapter, ec);
134
135 if (ec)
136 BOOST_THROW_EXCEPTION(system::system_error{ec});
137}
138
139} // namespace detail
140
141} // namespace boost::redis::resp3
142
143#endif // BOOST_REDIS_RESP3_SERIALIZATION_HPP
void boost_redis_to_bulk(std::string &payload, std::string_view data)
Adds a bulk to the request.
type
RESP3 data types.
Definition type.hpp:24