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>>);
58 vector<std::optional<std::string>>
59 ParseReplyDataArray(ReplyData&& array_data,
const std::string& request_description,
To<std::vector<std::optional<std::string>>>);
61std::vector<std::pair<std::string, std::string>>
62ParseReplyDataArray(ReplyData&& array_data,
const std::string& request_description,
To<std::vector<std::pair<std::string, std::string>>>);
64std::vector<MemberScore>
65ParseReplyDataArray(ReplyData&& array_data,
const std::string& request_description,
To<std::vector<MemberScore>>);
68ParseReplyDataArray(ReplyData&& array_data,
const std::string& request_description,
To<std::vector<GeoPoint>>);
71 vector<std::optional<
Point>>
72 ParseReplyDataArray(ReplyData&& array_data,
const std::string& request_description,
To<std::vector<std::optional<
Point>>>);
74std::string Parse(ReplyData&& reply_data,
const std::string& request_description,
To<std::string>);
76double Parse(ReplyData&& reply_data,
const std::string& request_description,
To<
double>);
78size_t Parse(ReplyData&& reply_data,
const std::string& request_description,
To<size_t>);
80bool Parse(ReplyData&& reply_data,
const std::string& request_description,
To<size_t,
bool>);
82int64_t Parse(ReplyData&& reply_data,
const std::string& request_description,
To<int64_t>);
84std::chrono::system_clock::time_point
85Parse(ReplyData&& reply_data,
const std::string& request_description,
To<std::chrono::system_clock::time_point>);
87HsetReply Parse(ReplyData&& reply_data,
const std::string& request_description,
To<HsetReply>);
89PersistReply Parse(ReplyData&& reply_data,
const std::string& request_description,
To<PersistReply>);
91KeyType Parse(ReplyData&& reply_data,
const std::string& request_description,
To<
KeyType>);
93void Parse(ReplyData&& reply_data,
const std::string& request_description,
To<StatusOk,
void>);
95bool Parse(ReplyData&& reply_data,
const std::string& request_description,
To<std::optional<StatusOk>,
bool>);
97void Parse(ReplyData&& reply_data,
const std::string& request_description,
To<StatusPong,
void>);
99Point Parse(ReplyData&& reply_data,
const std::string& request_description,
To<
Point>);
101SetReply Parse(ReplyData&& reply_data,
const std::string& request_description,
To<SetReply>);
103std::unordered_set<std::string>
104Parse(ReplyData&& reply_data,
const std::string& request_description,
To<std::unordered_set<std::string>>);
106std::unordered_map<std::string, std::string>
107Parse(ReplyData&& reply_data,
const std::string& request_description,
To<std::unordered_map<std::string, std::string>>);
109ReplyData Parse(ReplyData&& reply_data,
const std::string& request_description,
To<ReplyData>);
111template <
typename Result,
typename ReplyType = Result>
112std::enable_if_t<impl::HasParseFunctionFromRedisReply<Result, ReplyType>::value, ReplyType>
113Parse(ReplyData&& reply_data,
const std::string& request_description,
To<Result, ReplyType>) {
114 return Result::Parse(std::move(reply_data), request_description);
118std::vector<T> Parse(ReplyData&& reply_data,
const std::string& request_description,
To<std::vector<T>>) {
119 impl::ExpectArray(reply_data, request_description);
120 return ParseReplyDataArray(std::move(reply_data), request_description,
To<std::vector<T>>{});
124std::optional<T> Parse(ReplyData&& reply_data,
const std::string& request_description,
To<std::optional<T>>) {
125 if (impl::IsNil(reply_data)) {
128 return Parse(std::move(reply_data), request_description,
To<T>{});
133template <
typename Result,
typename ReplyType = Result>
134ReplyType ParseReply(ReplyPtr reply,
const std::string& request_description = {}) {
135 const auto& description = impl::RequestDescription(reply, request_description);
136 impl::ExpectIsOk(reply, description);
137 return Parse(impl::ExtractData(reply), description,
To<Result, ReplyType>{});