5#include <unordered_map> 
    6#include <unordered_set> 
    9#include <userver/storages/redis/impl/types.hpp> 
   10#include <userver/utils/void_t.hpp> 
   12#include <userver/storages/redis/reply_types.hpp> 
   14USERVER_NAMESPACE_BEGIN
 
   19ReplyData&& ExtractData(ReplyPtr& reply);
 
   21template <
typename Result, 
typename ReplyType, 
typename = utils::void_t<>>
 
   22struct HasParseFunctionFromRedisReply {
 
   23  static constexpr bool value = 
false;
 
   26template <
typename Result, 
typename ReplyType>
 
   27struct HasParseFunctionFromRedisReply<
 
   29    utils::void_t<
decltype(Result::Parse(
 
   30        std::declval<ReplyData>(), std::declval<
const std::string&>()))>> {
 
   31  static constexpr bool value =
 
   32      std::is_same<
decltype(Result::Parse(std::declval<ReplyData>(),
 
   33                                          std::declval<
const std::string&>())),
 
   37bool IsNil(
const ReplyData& reply_data);
 
   39void ExpectIsOk(
const ReplyPtr& reply, 
const std::string& request_description);
 
   41void ExpectArray(
const ReplyData& reply_data,
 
   42                 const std::string& request_description);
 
   44const std::string& RequestDescription(
const ReplyPtr& reply,
 
   45                                      const std::string& request_description);
 
   51template <
typename Result, 
typename ReplyType = Result>
 
   54std::vector<std::string> ParseReplyDataArray(
 
   55    ReplyData&& array_data, 
const std::string& request_description,
 
   56    To<std::vector<std::string>>);
 
   58std::vector<std::optional<std::string>> ParseReplyDataArray(
 
   59    ReplyData&& array_data, 
const std::string& request_description,
 
   60    To<std::vector<std::optional<std::string>>>);
 
   62std::vector<std::pair<std::string, std::string>> ParseReplyDataArray(
 
   63    ReplyData&& array_data, 
const std::string& request_description,
 
   64    To<std::vector<std::pair<std::string, std::string>>>);
 
   66std::vector<MemberScore> ParseReplyDataArray(
 
   67    ReplyData&& array_data, 
const std::string& request_description,
 
   68    To<std::vector<MemberScore>>);
 
   70std::vector<GeoPoint> ParseReplyDataArray(
 
   71    ReplyData&& array_data, 
const std::string& request_description,
 
   72    To<std::vector<GeoPoint>>);
 
   74std::string Parse(ReplyData&& reply_data,
 
   75                  const std::string& request_description, To<std::string>);
 
   77double Parse(ReplyData&& reply_data, 
const std::string& request_description,
 
   80size_t Parse(ReplyData&& reply_data, 
const std::string& request_description,
 
   83bool Parse(ReplyData&& reply_data, 
const std::string& request_description,
 
   86int64_t Parse(ReplyData&& reply_data, 
const std::string& request_description,
 
   89std::chrono::system_clock::time_point Parse(
 
   90    ReplyData&& reply_data, 
const std::string& request_description,
 
   91    To<std::chrono::system_clock::time_point>);
 
   93HsetReply Parse(ReplyData&& reply_data, 
const std::string& request_description,
 
   96PersistReply Parse(ReplyData&& reply_data,
 
   97                   const std::string& request_description, To<PersistReply>);
 
   99KeyType Parse(ReplyData&& reply_data, 
const std::string& request_description,
 
  102void Parse(ReplyData&& reply_data, 
const std::string& request_description,
 
  105bool Parse(ReplyData&& reply_data, 
const std::string& request_description,
 
  106           To<std::optional<StatusOk>, 
bool>);
 
  108void Parse(ReplyData&& reply_data, 
const std::string& request_description,
 
  109           To<StatusPong, 
void>);
 
  111SetReply Parse(ReplyData&& reply_data, 
const std::string& request_description,
 
  114std::unordered_set<std::string> Parse(ReplyData&& reply_data,
 
  115                                      const std::string& request_description,
 
  116                                      To<std::unordered_set<std::string>>);
 
  118std::unordered_map<std::string, std::string> Parse(
 
  119    ReplyData&& reply_data, 
const std::string& request_description,
 
  120    To<std::unordered_map<std::string, std::string>>);
 
  122ReplyData Parse(ReplyData&& reply_data, 
const std::string& request_description,
 
  125template <
typename Result, 
typename ReplyType = Result>
 
  126std::enable_if_t<impl::HasParseFunctionFromRedisReply<Result, ReplyType>::value,
 
  128Parse(ReplyData&& reply_data, 
const std::string& request_description,
 
  129      To<Result, ReplyType>) {
 
  130  return Result::Parse(std::move(reply_data), request_description);
 
  134std::vector<T> Parse(ReplyData&& reply_data,
 
  135                     const std::string& request_description,
 
  136                     To<std::vector<T>>) {
 
  137  impl::ExpectArray(reply_data, request_description);
 
  138  return ParseReplyDataArray(std::move(reply_data), request_description,
 
  139                             To<std::vector<T>>{});
 
  143std::optional<T> Parse(ReplyData&& reply_data,
 
  144                       const std::string& request_description,
 
  145                       To<std::optional<T>>) {
 
  146  if (impl::IsNil(reply_data)) 
return std::nullopt;
 
  147  return Parse(std::move(reply_data), request_description, To<T>{});
 
  150template <
typename Result, 
typename ReplyType = Result>
 
  151ReplyType ParseReply(ReplyPtr reply,
 
  152                     const std::string& request_description = {}) {
 
  153  const auto& description =
 
  154      impl::RequestDescription(reply, request_description);
 
  155  impl::ExpectIsOk(reply, description);
 
  156  return Parse(impl::ExtractData(reply), description, To<Result, ReplyType>{});