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
109PersistReply Parse(ReplyData&& reply_data, const std::string& request_description, To<PersistReply>);
110
111HexpireReply Parse(ReplyData&& reply_data, const std::string& request_description, To<HexpireReply>);
112
113HpersistReply Parse(ReplyData&& reply_data, const std::string& request_description, To<HpersistReply>);
114
115KeyType Parse(ReplyData&& reply_data, const std::string& request_description, To<KeyType>);
116
117void Parse(ReplyData&& reply_data, const std::string& request_description, To<StatusOk, void>);
118
119bool Parse(ReplyData&& reply_data, const std::string& request_description, To<std::optional<StatusOk>, bool>);
120
121void Parse(ReplyData&& reply_data, const std::string& request_description, To<StatusPong, void>);
122
123Point Parse(ReplyData&& reply_data, const std::string& request_description, To<Point>);
124
125SetReply Parse(ReplyData&& reply_data, const std::string& request_description, To<SetReply>);
126
127std::unordered_set<std::string>
128Parse(ReplyData&& reply_data, const std::string& request_description, To<std::unordered_set<std::string>>);
129
130std::unordered_map<std::string, std::string>
131Parse(ReplyData&& reply_data, const std::string& request_description, To<std::unordered_map<std::string, std::string>>);
132
133ReplyData Parse(ReplyData&& reply_data, const std::string& request_description, To<ReplyData>);
134
135formats::json::Value Parse(ReplyData&& reply_data, const std::string& request_description, To<formats::json::Value>);
136
137std::vector<std::optional<formats::json::Value>>
138ParseReplyDataArray(ReplyData&& array_data, const std::string& request_description, To<std::vector<std::optional<formats::json::Value>>>);
139
140template <typename Result, typename ReplyType = Result>
141requires impl::HasParseFunctionFromRedisReply<Result, ReplyType>
142ReplyType Parse(ReplyData&& reply_data, const std::string& request_description, To<Result, ReplyType>) {
143 return Result::Parse(std::move(reply_data), request_description);
144}
145
146template <typename T>
147std::vector<T> Parse(ReplyData&& reply_data, const std::string& request_description, To<std::vector<T>>) {
148 impl::ExpectArray(reply_data, request_description);
149 return ParseReplyDataArray(std::move(reply_data), request_description, To<std::vector<T>>{});
150}
151
152template <typename T>
153std::optional<T> Parse(ReplyData&& reply_data, const std::string& request_description, To<std::optional<T>>) {
154 if (impl::IsNil(reply_data)) {
155 return std::nullopt;
156 }
157 return Parse(std::move(reply_data), request_description, To<T>{});
158}
159
160namespace impl {
161
162template <typename Result, typename ReplyType = Result>
163ReplyType ParseReply(ReplyPtr reply, const std::string& request_description = {}) {
164 const auto& description = impl::RequestDescription(reply, request_description);
165 impl::ExpectIsOk(reply, description);
166 return Parse(impl::ExtractData(reply), description, To<Result, ReplyType>{}); // Customization point
167}
168
169} // namespace impl
170
171} // namespace storages::redis
172
173USERVER_NAMESPACE_END