8#include <unordered_map>
9#include <unordered_set>
12#include <userver/storages/redis/fwd.hpp>
13#include <userver/utils/void_t.hpp>
15#include <userver/storages/redis/reply_types.hpp>
17USERVER_NAMESPACE_BEGIN
19namespace storages::
redis {
22ReplyData&& ExtractData(ReplyPtr& reply);
24template <
typename Result,
typename ReplyType,
typename =
utils::void_t<>>
25struct HasParseFunctionFromRedisReply {
26 static constexpr bool value =
false;
29template <
typename Result,
typename ReplyType>
30struct HasParseFunctionFromRedisReply<
33 utils::void_t<
decltype(Result::Parse(std::declval<ReplyData>(), std::declval<
const std::string&>()))>> {
34 static constexpr bool value = std::is_same<
35 decltype(Result::Parse(std::declval<ReplyData>(), std::declval<
const std::string&>())),
39bool IsNil(
const ReplyData& reply_data);
41void ExpectIsOk(
const ReplyPtr& reply,
const std::string& request_description);
43void ExpectArray(
const ReplyData& reply_data,
const std::string& request_description);
45const std::string& RequestDescription(
const ReplyPtr& reply,
const std::string& request_description);
51template <
typename Result,
typename ReplyType = Result>
54std::vector<std::string>
55ParseReplyDataArray(ReplyData&& array_data,
const std::string& request_description,
To<std::vector<std::string>>);
57std::vector<std::optional<std::string>>
58ParseReplyDataArray(ReplyData&& array_data,
const std::string& request_description,
To<std::vector<std::optional<std::string>>>);
60std::vector<std::pair<std::string, std::string>>
61ParseReplyDataArray(ReplyData&& array_data,
const std::string& request_description,
To<std::vector<std::pair<std::string, std::string>>>);
63std::vector<MemberScore>
64ParseReplyDataArray(ReplyData&& array_data,
const std::string& request_description,
To<std::vector<MemberScore>>);
67ParseReplyDataArray(ReplyData&& array_data,
const std::string& request_description,
To<std::vector<GeoPoint>>);
69std::string Parse(ReplyData&& reply_data,
const std::string& request_description,
To<std::string>);
71double Parse(ReplyData&& reply_data,
const std::string& request_description,
To<
double>);
73size_t Parse(ReplyData&& reply_data,
const std::string& request_description,
To<size_t>);
75bool Parse(ReplyData&& reply_data,
const std::string& request_description,
To<size_t,
bool>);
77int64_t Parse(ReplyData&& reply_data,
const std::string& request_description,
To<int64_t>);
79std::chrono::system_clock::time_point
80Parse(ReplyData&& reply_data,
const std::string& request_description,
To<std::chrono::system_clock::time_point>);
82HsetReply Parse(ReplyData&& reply_data,
const std::string& request_description,
To<HsetReply>);
84PersistReply Parse(ReplyData&& reply_data,
const std::string& request_description,
To<PersistReply>);
86KeyType Parse(ReplyData&& reply_data,
const std::string& request_description,
To<
KeyType>);
88void Parse(ReplyData&& reply_data,
const std::string& request_description,
To<StatusOk,
void>);
90bool Parse(ReplyData&& reply_data,
const std::string& request_description,
To<std::optional<StatusOk>,
bool>);
92void Parse(ReplyData&& reply_data,
const std::string& request_description,
To<StatusPong,
void>);
94SetReply Parse(ReplyData&& reply_data,
const std::string& request_description,
To<SetReply>);
96std::unordered_set<std::string>
97Parse(ReplyData&& reply_data,
const std::string& request_description,
To<std::unordered_set<std::string>>);
99std::unordered_map<std::string, std::string>
100Parse(ReplyData&& reply_data,
const std::string& request_description,
To<std::unordered_map<std::string, std::string>>);
102ReplyData Parse(ReplyData&& reply_data,
const std::string& request_description,
To<ReplyData>);
104template <
typename Result,
typename ReplyType = Result>
105std::enable_if_t<impl::HasParseFunctionFromRedisReply<Result, ReplyType>::value, ReplyType>
106Parse(ReplyData&& reply_data,
const std::string& request_description,
To<Result, ReplyType>) {
107 return Result::Parse(std::move(reply_data), request_description);
111std::vector<T> Parse(ReplyData&& reply_data,
const std::string& request_description,
To<std::vector<T>>) {
112 impl::ExpectArray(reply_data, request_description);
113 return ParseReplyDataArray(std::move(reply_data), request_description,
To<std::vector<T>>{});
117std::optional<T> Parse(ReplyData&& reply_data,
const std::string& request_description,
To<std::optional<T>>) {
118 if (impl::IsNil(reply_data))
return std::nullopt;
119 return Parse(std::move(reply_data), request_description,
To<T>{});
124template <
typename Result,
typename ReplyType = Result>
125ReplyType ParseReply(ReplyPtr reply,
const std::string& request_description = {}) {
126 const auto& description = impl::RequestDescription(reply, request_description);
127 impl::ExpectIsOk(reply, description);
128 return Parse(impl::ExtractData(reply), description,
To<Result, ReplyType>{});