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::vector<std::optional<
Point>>
70ParseReplyDataArray(ReplyData&& array_data,
const std::string& request_description,
To<std::vector<std::optional<
Point>>>);
72std::string Parse(ReplyData&& reply_data,
const std::string& request_description,
To<std::string>);
74double Parse(ReplyData&& reply_data,
const std::string& request_description,
To<
double>);
76size_t Parse(ReplyData&& reply_data,
const std::string& request_description,
To<size_t>);
78bool Parse(ReplyData&& reply_data,
const std::string& request_description,
To<size_t,
bool>);
80int64_t Parse(ReplyData&& reply_data,
const std::string& request_description,
To<int64_t>);
82std::chrono::system_clock::time_point
83Parse(ReplyData&& reply_data,
const std::string& request_description,
To<std::chrono::system_clock::time_point>);
85HsetReply Parse(ReplyData&& reply_data,
const std::string& request_description,
To<HsetReply>);
87PersistReply Parse(ReplyData&& reply_data,
const std::string& request_description,
To<PersistReply>);
89KeyType Parse(ReplyData&& reply_data,
const std::string& request_description,
To<
KeyType>);
91void Parse(ReplyData&& reply_data,
const std::string& request_description,
To<StatusOk,
void>);
93bool Parse(ReplyData&& reply_data,
const std::string& request_description,
To<std::optional<StatusOk>,
bool>);
95void Parse(ReplyData&& reply_data,
const std::string& request_description,
To<StatusPong,
void>);
97Point Parse(ReplyData&& reply_data,
const std::string& request_description,
To<
Point>);
99SetReply Parse(ReplyData&& reply_data,
const std::string& request_description,
To<SetReply>);
101std::unordered_set<std::string>
102Parse(ReplyData&& reply_data,
const std::string& request_description,
To<std::unordered_set<std::string>>);
104std::unordered_map<std::string, std::string>
105Parse(ReplyData&& reply_data,
const std::string& request_description,
To<std::unordered_map<std::string, std::string>>);
107ReplyData Parse(ReplyData&& reply_data,
const std::string& request_description,
To<ReplyData>);
109template <
typename Result,
typename ReplyType = Result>
110std::enable_if_t<impl::HasParseFunctionFromRedisReply<Result, ReplyType>::value, ReplyType>
111Parse(ReplyData&& reply_data,
const std::string& request_description,
To<Result, ReplyType>) {
112 return Result::Parse(std::move(reply_data), request_description);
116std::vector<T> Parse(ReplyData&& reply_data,
const std::string& request_description,
To<std::vector<T>>) {
117 impl::ExpectArray(reply_data, request_description);
118 return ParseReplyDataArray(std::move(reply_data), request_description,
To<std::vector<T>>{});
122std::optional<T> Parse(ReplyData&& reply_data,
const std::string& request_description,
To<std::optional<T>>) {
123 if (impl::IsNil(reply_data))
return std::nullopt;
124 return Parse(std::move(reply_data), request_description,
To<T>{});
129template <
typename Result,
typename ReplyType = Result>
130ReplyType ParseReply(ReplyPtr reply,
const std::string& request_description = {}) {
131 const auto& description = impl::RequestDescription(reply, request_description);
132 impl::ExpectIsOk(reply, description);
133 return Parse(impl::ExtractData(reply), description,
To<Result, ReplyType>{});