userver: userver/storages/redis/parse_reply.hpp Source File
Loading...
Searching...
No Matches
parse_reply.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file
4/// @brief Customizations for Redis response parsings
5
6#include <concepts>
7#include <optional>
8#include <string>
9#include <unordered_map>
10#include <unordered_set>
11#include <vector>
12
13#include <userver/formats/json/value.hpp>
14#include <userver/storages/redis/fwd.hpp>
15
16#include <userver/storages/redis/hexpiretime_reply.hpp>
17#include <userver/storages/redis/hpexpiretime_reply.hpp>
18#include <userver/storages/redis/pttl_reply.hpp>
19#include <userver/storages/redis/reply_types.hpp>
20#include <userver/storages/redis/ttl_reply.hpp>
21
22USERVER_NAMESPACE_BEGIN
23
24namespace storages::redis {
25namespace impl {
26
27ReplyData&& ExtractData(ReplyPtr& reply);
28
29template <typename Result, typename ReplyType = Result>
30concept HasParseFunctionFromRedisReply = requires {
31 {
32 Result::Parse(std::declval<ReplyData>(), std::declval<const std::string&>())
33 } -> std::same_as<ReplyType>;
34};
35
36bool IsNil(const ReplyData& reply_data);
37
38void ExpectIsOk(const ReplyPtr& reply, const std::string& request_description);
39
40void ExpectArray(const ReplyData& reply_data, const std::string& request_description);
41
42const std::string& RequestDescription(const ReplyPtr& reply, const std::string& request_description);
43
44} // namespace impl
45
46/// An ADL helper that allows searching for `Parse` functions in namespace
47/// `storages::redis` additionally to the namespace of `Result`.
48template <typename Result, typename ReplyType = Result>
49struct To {};
50
51std::vector<std::string>
52ParseReplyDataArray(ReplyData&& array_data, const std::string& request_description, To<std::vector<std::string>>);
53
54std::vector<int64_t>
55ParseReplyDataArray(ReplyData&& array_data, const std::string& request_description, To<std::vector<int64_t>>);
56
57std::
58 vector<std::optional<std::string>>
59 ParseReplyDataArray(ReplyData&& array_data, const std::string& request_description, To<std::vector<std::optional<std::string>>>);
60
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>>>);
63
64std::vector<MemberScore>
65ParseReplyDataArray(ReplyData&& array_data, const std::string& request_description, To<std::vector<MemberScore>>);
66
67std::vector<GeoPoint>
68ParseReplyDataArray(ReplyData&& array_data, const std::string& request_description, To<std::vector<GeoPoint>>);
69
70std::vector<HexpireReply>
71ParseReplyDataArray(ReplyData&& array_data, const std::string& request_description, To<std::vector<HexpireReply>>);
72
73std::vector<HpersistReply>
74ParseReplyDataArray(ReplyData&& array_data, const std::string& request_description, To<std::vector<HpersistReply>>);
75
76std::vector<TtlReply>
77ParseReplyDataArray(ReplyData&& array_data, const std::string& request_description, To<std::vector<TtlReply>>);
78
79std::vector<PttlReply>
80ParseReplyDataArray(ReplyData&& array_data, const std::string& request_description, To<std::vector<PttlReply>>);
81
82std::vector<HexpiretimeReply>
83ParseReplyDataArray(ReplyData&& array_data, const std::string& request_description, To<std::vector<HexpiretimeReply>>);
84
85std::vector<HpexpiretimeReply>
86ParseReplyDataArray(ReplyData&& array_data, const std::string& request_description, To<std::vector<HpexpiretimeReply>>);
87
88std::
89 vector<std::optional<Point>>
90 ParseReplyDataArray(ReplyData&& array_data, const std::string& request_description, To<std::vector<std::optional<Point>>>);
91
92std::string Parse(ReplyData&& reply_data, const std::string& request_description, To<std::string>);
93
94double Parse(ReplyData&& reply_data, const std::string& request_description, To<double>);
95
96size_t Parse(ReplyData&& reply_data, const std::string& request_description, To<size_t>);
97
98bool Parse(ReplyData&& reply_data, const std::string& request_description, To<size_t, bool>);
99
100int64_t Parse(ReplyData&& reply_data, const std::string& request_description, To<int64_t>);
101
102std::chrono::system_clock::time_point
103Parse(ReplyData&& reply_data, const std::string& request_description, To<std::chrono::system_clock::time_point>);
104
105HsetReply Parse(ReplyData&& reply_data, const std::string& request_description, To<HsetReply>);
106
107HsetexReply Parse(ReplyData&& reply_data, const std::string& request_description, To<HsetexReply>);
108
109MsetexReply Parse(ReplyData&& reply_data, const std::string& request_description, To<MsetexReply>);
110
111PersistReply Parse(ReplyData&& reply_data, const std::string& request_description, To<PersistReply>);
112
113HexpireReply Parse(ReplyData&& reply_data, const std::string& request_description, To<HexpireReply>);
114
115HpersistReply Parse(ReplyData&& reply_data, const std::string& request_description, To<HpersistReply>);
116
117KeyType Parse(ReplyData&& reply_data, const std::string& request_description, To<KeyType>);
118
119void Parse(ReplyData&& reply_data, const std::string& request_description, To<StatusOk, void>);
120
121bool Parse(ReplyData&& reply_data, const std::string& request_description, To<std::optional<StatusOk>, bool>);
122
123void Parse(ReplyData&& reply_data, const std::string& request_description, To<StatusPong, void>);
124
125Point Parse(ReplyData&& reply_data, const std::string& request_description, To<Point>);
126
127SetReply Parse(ReplyData&& reply_data, const std::string& request_description, To<SetReply>);
128
129std::unordered_set<std::string>
130Parse(ReplyData&& reply_data, const std::string& request_description, To<std::unordered_set<std::string>>);
131
132std::unordered_map<std::string, std::string>
133Parse(ReplyData&& reply_data, const std::string& request_description, To<std::unordered_map<std::string, std::string>>);
134
135ReplyData Parse(ReplyData&& reply_data, const std::string& request_description, To<ReplyData>);
136
137formats::json::Value Parse(ReplyData&& reply_data, const std::string& request_description, To<formats::json::Value>);
138
139std::vector<std::optional<formats::json::Value>>
140ParseReplyDataArray(ReplyData&& array_data, const std::string& request_description, To<std::vector<std::optional<formats::json::Value>>>);
141
142template <typename Result, typename ReplyType = Result>
143requires impl::HasParseFunctionFromRedisReply<Result, ReplyType>
144ReplyType Parse(ReplyData&& reply_data, const std::string& request_description, To<Result, ReplyType>) {
145 return Result::Parse(std::move(reply_data), request_description);
146}
147
148template <typename T>
149std::vector<T> Parse(ReplyData&& reply_data, const std::string& request_description, To<std::vector<T>>) {
150 impl::ExpectArray(reply_data, request_description);
151 return ParseReplyDataArray(std::move(reply_data), request_description, To<std::vector<T>>{});
152}
153
154template <typename T>
155std::optional<T> Parse(ReplyData&& reply_data, const std::string& request_description, To<std::optional<T>>) {
156 if (impl::IsNil(reply_data)) {
157 return std::nullopt;
158 }
159 return Parse(std::move(reply_data), request_description, To<T>{});
160}
161
162namespace impl {
163
164template <typename Result, typename ReplyType = Result>
165ReplyType ParseReply(ReplyPtr reply, const std::string& request_description = {}) {
166 const auto& description = impl::RequestDescription(reply, request_description);
167 impl::ExpectIsOk(reply, description);
168 return Parse(impl::ExtractData(reply), description, To<Result, ReplyType>{}); // Customization point
169}
170
171} // namespace impl
172
173} // namespace storages::redis
174
175USERVER_NAMESPACE_END