gnss-sim/3rdparty/boost/redis/resp3/serialization.hpp

145 lines
3.5 KiB
C++
Raw Normal View History

2024-12-24 16:15:51 +00:00
/* 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_RESP3_SERIALIZATION_HPP
#define BOOST_REDIS_RESP3_SERIALIZATION_HPP
#include <boost/redis/resp3/type.hpp>
#include <boost/system/system_error.hpp>
#include <boost/throw_exception.hpp>
#include <boost/redis/resp3/parser.hpp>
#include <string>
#include <tuple>
// NOTE: Consider detecting tuples in the type in the parameter pack
// to calculate the header size correctly.
namespace boost::redis::resp3 {
/** @brief Adds a bulk to the request.
* @relates boost::redis::request
*
* This function is useful in serialization of your own data
* structures in a request. For example
*
* @code
* void boost_redis_to_bulk(std::string& payload, mystruct const& obj)
* {
* auto const str = // Convert obj to a string.
* boost_redis_to_bulk(payload, str);
* }
* @endcode
*
* @param payload Storage on which data will be copied into.
* @param data Data that will be serialized and stored in `payload`.
*
* See more in @ref serialization.
*/
void boost_redis_to_bulk(std::string& payload, std::string_view data);
template <class T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
void boost_redis_to_bulk(std::string& payload, T n)
{
auto const s = std::to_string(n);
boost::redis::resp3::boost_redis_to_bulk(payload, std::string_view{s});
}
template <class T>
struct add_bulk_impl {
static void add(std::string& payload, T const& from)
{
using namespace boost::redis::resp3;
boost_redis_to_bulk(payload, from);
}
};
template <class ...Ts>
struct add_bulk_impl<std::tuple<Ts...>> {
static void add(std::string& payload, std::tuple<Ts...> const& t)
{
auto f = [&](auto const&... vs)
{
using namespace boost::redis::resp3;
(boost_redis_to_bulk(payload, vs), ...);
};
std::apply(f, t);
}
};
template <class U, class V>
struct add_bulk_impl<std::pair<U, V>> {
static void add(std::string& payload, std::pair<U, V> const& from)
{
using namespace boost::redis::resp3;
boost_redis_to_bulk(payload, from.first);
boost_redis_to_bulk(payload, from.second);
}
};
void add_header(std::string& payload, type t, std::size_t size);
template <class T>
void add_bulk(std::string& payload, T const& data)
{
add_bulk_impl<T>::add(payload, data);
}
template <class>
struct bulk_counter;
template <class>
struct bulk_counter {
static constexpr auto size = 1U;
};
template <class T, class U>
struct bulk_counter<std::pair<T, U>> {
static constexpr auto size = 2U;
};
void add_blob(std::string& payload, std::string_view blob);
void add_separator(std::string& payload);
namespace detail
{
template <class Adapter>
void deserialize(std::string_view const& data, Adapter adapter, system::error_code& ec)
{
parser parser;
while (!parser.done()) {
auto const res = parser.consume(data, ec);
if (ec)
return;
BOOST_ASSERT(res.has_value());
adapter(res.value(), ec);
if (ec)
return;
}
BOOST_ASSERT(parser.get_consumed() == std::size(data));
}
template <class Adapter>
void deserialize(std::string_view const& data, Adapter adapter)
{
system::error_code ec;
deserialize(data, adapter, ec);
if (ec)
BOOST_THROW_EXCEPTION(system::system_error{ec});
}
}
} // boost::redis::resp3
#endif // BOOST_REDIS_RESP3_SERIALIZATION_HPP