userver: userver/storages/redis/parse_reply.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
parse_reply.hpp
1#pragma once
2
3#include <optional>
4#include <string>
5#include <unordered_map>
6#include <unordered_set>
7#include <vector>
8
9#include <userver/storages/redis/impl/types.hpp>
10#include <userver/utils/void_t.hpp>
11
12#include <userver/storages/redis/reply_types.hpp>
13
14USERVER_NAMESPACE_BEGIN
15
16namespace storages::redis {
17namespace impl {
18
19ReplyData&& ExtractData(ReplyPtr& reply);
20
21template <typename Result, typename ReplyType, typename = utils::void_t<>>
22struct HasParseFunctionFromRedisReply {
23 static constexpr bool value = false;
24};
25
26template <typename Result, typename ReplyType>
27struct HasParseFunctionFromRedisReply<
28 Result, ReplyType,
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&>())),
34 ReplyType>::value;
35};
36
37bool IsNil(const ReplyData& reply_data);
38
39void ExpectIsOk(const ReplyPtr& reply, const std::string& request_description);
40
41void ExpectArray(const ReplyData& reply_data,
42 const std::string& request_description);
43
44const std::string& RequestDescription(const ReplyPtr& reply,
45 const std::string& request_description);
46
47} // namespace impl
48
49/// An ADL helper that allows searching for `Parse` functions in namespace
50/// `storages::redis` additionally to the namespace of `Result`.
51template <typename Result, typename ReplyType = Result>
52struct To {};
53
54std::vector<std::string> ParseReplyDataArray(
55 ReplyData&& array_data, const std::string& request_description,
56 To<std::vector<std::string>>);
57
58std::vector<std::optional<std::string>> ParseReplyDataArray(
59 ReplyData&& array_data, const std::string& request_description,
60 To<std::vector<std::optional<std::string>>>);
61
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>>>);
65
66std::vector<MemberScore> ParseReplyDataArray(
67 ReplyData&& array_data, const std::string& request_description,
68 To<std::vector<MemberScore>>);
69
70std::vector<GeoPoint> ParseReplyDataArray(
71 ReplyData&& array_data, const std::string& request_description,
72 To<std::vector<GeoPoint>>);
73
74std::string Parse(ReplyData&& reply_data,
75 const std::string& request_description, To<std::string>);
76
77double Parse(ReplyData&& reply_data, const std::string& request_description,
78 To<double>);
79
80size_t Parse(ReplyData&& reply_data, const std::string& request_description,
81 To<size_t>);
82
83bool Parse(ReplyData&& reply_data, const std::string& request_description,
84 To<size_t, bool>);
85
86int64_t Parse(ReplyData&& reply_data, const std::string& request_description,
87 To<int64_t>);
88
89std::chrono::system_clock::time_point Parse(
90 ReplyData&& reply_data, const std::string& request_description,
91 To<std::chrono::system_clock::time_point>);
92
93HsetReply Parse(ReplyData&& reply_data, const std::string& request_description,
94 To<HsetReply>);
95
96PersistReply Parse(ReplyData&& reply_data,
97 const std::string& request_description, To<PersistReply>);
98
99KeyType Parse(ReplyData&& reply_data, const std::string& request_description,
100 To<KeyType>);
101
102void Parse(ReplyData&& reply_data, const std::string& request_description,
103 To<StatusOk, void>);
104
105bool Parse(ReplyData&& reply_data, const std::string& request_description,
106 To<std::optional<StatusOk>, bool>);
107
108void Parse(ReplyData&& reply_data, const std::string& request_description,
109 To<StatusPong, void>);
110
111SetReply Parse(ReplyData&& reply_data, const std::string& request_description,
112 To<SetReply>);
113
114std::unordered_set<std::string> Parse(ReplyData&& reply_data,
115 const std::string& request_description,
116 To<std::unordered_set<std::string>>);
117
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>>);
121
122ReplyData Parse(ReplyData&& reply_data, const std::string& request_description,
123 To<ReplyData>);
124
125template <typename Result, typename ReplyType = Result>
126std::enable_if_t<impl::HasParseFunctionFromRedisReply<Result, ReplyType>::value,
127 ReplyType>
128Parse(ReplyData&& reply_data, const std::string& request_description,
129 To<Result, ReplyType>) {
130 return Result::Parse(std::move(reply_data), request_description);
131}
132
133template <typename T>
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>>{});
140}
141
142template <typename 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>{});
148}
149
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>{});
157}
158
159} // namespace storages::redis
160
161USERVER_NAMESPACE_END