userver: userver/cache/mongo_cache_type_traits.hpp Source File
Loading...
Searching...
No Matches
mongo_cache_type_traits.hpp
1#pragma once
2
3#include <chrono>
4#include <type_traits>
5
6#include <userver/cache/update_type.hpp>
7#include <userver/utils/meta.hpp>
8#include <userver/utils/void_t.hpp>
9
10USERVER_NAMESPACE_BEGIN
11
12namespace formats::bson {
13class Document;
14}
15
16namespace storages::mongo::operations {
17class Find;
18}
19
20namespace mongo_cache::impl {
21
22template <typename T>
23concept HasCollectionsField = requires { T::kMongoCollectionsField; };
24
25template <typename T>
26concept HasUpdateFieldName = requires { T::kMongoUpdateFieldName; };
27
28template <typename T>
29concept HasKeyField = requires { T::kKeyField; };
30
31template <typename T>
32concept HasValidDataType = meta::kIsMap<typename T::DataType>;
33
34template <typename T>
35concept HasSecondaryPreferred = requires { T::kIsSecondaryPreferred; };
36
37template <typename T>
38concept HasDeserializeObject = requires { T::DeserializeObject; };
39
40template <typename T>
41concept HasCorrectDeserializeObject = requires(const T& t, const formats::bson::Document& doc) {
42 {
43 t.DeserializeObject(doc)
44 } -> std::same_as<typename T::ObjectType>;
45};
46
47template <typename T>
48concept HasDefaultDeserializeObject = requires { T::kUseDefaultDeserializeObject; };
49
50template <typename T>
51concept HasFindOperation = requires { T::GetFindOperation; };
52
53template <typename T>
54concept HasCorrectFindOperation = requires(
55 const T& t,
56 cache::UpdateType update_type,
57 const std::chrono::system_clock::time_point& last_update,
58 const std::chrono::system_clock::time_point& now,
59 const std::chrono::system_clock::duration& correction
60) {
61 // NOLINTNEXTLINE(readability-static-accessed-through-instance)
62 {
63 t.GetFindOperation(update_type, last_update, now, correction)
64 } -> std::same_as<storages::mongo::operations::Find>;
65};
66
67template <typename T>
68concept HasDefaultFindOperation = requires { T::kUseDefaultFindOperation; };
69
70template <typename T>
71concept HasInvalidDocumentsSkipped = requires { T::kAreInvalidDocumentsSkipped; };
72
73template <typename>
74struct ClassByMemberPointer {};
75template <typename T, typename C>
76struct ClassByMemberPointer<T C::*> {
77 using type = C;
78};
79template <typename CollectionPtr>
80using CollectionsType = typename ClassByMemberPointer<std::remove_cv_t<CollectionPtr>>::type;
81
82template <typename MongoCacheTraits>
83struct CheckTraits {
84 CheckTraits() {
85 if constexpr (HasDefaultDeserializeObject<MongoCacheTraits>) {
86 static_assert(
87 std::is_same_v<std::decay_t<decltype(MongoCacheTraits::kUseDefaultDeserializeObject)>, bool>,
88 "Mongo cache traits must specify kUseDefaultDeserializeObject as "
89 "bool"
90 );
91 }
92 if constexpr (HasDefaultFindOperation<MongoCacheTraits>) {
93 static_assert(
94 std::is_same_v<std::decay_t<decltype(MongoCacheTraits::kUseDefaultFindOperation)>, bool>,
95 "Mongo cache traits must specify kUseDefaultFindOperation as bool"
96 );
97 }
98 }
99
100 static_assert(HasCollectionsField<MongoCacheTraits>, "Mongo cache traits must specify collections field");
101 static_assert(HasKeyField<MongoCacheTraits>, "Mongo cache traits must specify key field");
102 static_assert(HasValidDataType<MongoCacheTraits>, "Mongo cache traits must specify mapping data type");
103
104 static_assert(HasSecondaryPreferred<MongoCacheTraits>, "Mongo cache traits must specify read preference");
105 static_assert(
106 std::is_same_v<std::decay_t<decltype(MongoCacheTraits::kIsSecondaryPreferred)>, bool>,
107 "Mongo cache traits must specify read preference of a bool type"
108 );
109
110 static_assert(HasInvalidDocumentsSkipped<MongoCacheTraits>, "Mongo cache traits must specify validation policy");
111 static_assert(
112 std::is_same_v<std::decay_t<decltype(MongoCacheTraits::kAreInvalidDocumentsSkipped)>, bool>,
113 "Mongo cache traits must specify validation policy of a bool type"
114 );
115
116 static_assert(
117 HasFindOperation<MongoCacheTraits> || HasDefaultFindOperation<MongoCacheTraits>,
118 "Mongo cache traits must specify find operation"
119 );
120 static_assert(
121 !HasFindOperation<MongoCacheTraits> || HasCorrectFindOperation<MongoCacheTraits>,
122 "Mongo cache traits must specify find operation with correct "
123 "signature and return value type: "
124 "static storages::mongo::operations::Find GetFindOperation("
125 "cache::UpdateType type, "
126 "const std::chrono::system_clock::time_point& last_update, "
127 "const std::chrono::system_clock::time_point& now, "
128 "const std::chrono::system_clock::duration& correction)"
129 );
130
131 static_assert(
132 HasDeserializeObject<MongoCacheTraits> || HasDefaultDeserializeObject<MongoCacheTraits>,
133 "Mongo cache traits must specify deserialize object"
134 );
135 static_assert(
136 !HasDeserializeObject<MongoCacheTraits> || HasCorrectDeserializeObject<MongoCacheTraits>,
137 "Mongo cache traits must specify deserialize object with correct "
138 "signature and return value type: "
139 "static ObjectType DeserializeObject(const formats::bson::Document& "
140 "doc)"
141 );
142};
143
144} // namespace mongo_cache::impl
145
146USERVER_NAMESPACE_END