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>
23using CollectionsField = decltype(T::kMongoCollectionsField);
24template <typename T>
25inline constexpr bool kHasCollectionsField = meta::IsDetected<CollectionsField, T>;
26
27template <typename T>
28using UpdateFieldName = decltype(T::kMongoUpdateFieldName);
29template <typename T>
30inline constexpr bool kHasUpdateFieldName = meta::IsDetected<UpdateFieldName, T>;
31
32template <typename T>
33using KeyField = decltype(T::kKeyField);
34template <typename T>
35inline constexpr bool kHasKeyField = meta::IsDetected<KeyField, T>;
36
37template <typename T>
38using DataType = typename T::DataType;
39template <typename T>
40inline constexpr bool kHasValidDataType = meta::kIsMap<meta::DetectedType<DataType, T>>;
41
42template <typename T>
43using HasSecondaryPreferred = decltype(T::kIsSecondaryPreferred);
44template <typename T>
45inline constexpr bool kHasSecondaryPreferred = meta::IsDetected<HasSecondaryPreferred, T>;
46
47template <typename T>
48using HasDeserializeObject = decltype(T::DeserializeObject);
49template <typename T>
50inline constexpr bool kHasDeserializeObject = meta::IsDetected<HasDeserializeObject, T>;
51
52template <typename T>
53using HasCorrectDeserializeObject = meta::ExpectSame<
54 typename T::ObjectType,
55 decltype(std::declval<const T&>().DeserializeObject(std::declval<const formats::bson::Document&>()))>;
56template <typename T>
57inline constexpr bool kHasCorrectDeserializeObject = meta::IsDetected<HasCorrectDeserializeObject, T>;
58
59template <typename T>
60using HasDefaultDeserializeObject = decltype(T::kUseDefaultDeserializeObject);
61template <typename T>
62inline constexpr bool kHasDefaultDeserializeObject = meta::IsDetected<HasDefaultDeserializeObject, T>;
63
64template <typename T>
65using HasFindOperation = decltype(T::GetFindOperation);
66template <typename T>
67inline constexpr bool kHasFindOperation = meta::IsDetected<HasFindOperation, T>;
68
69template <typename T>
70using HasCorrectFindOperation = meta::ExpectSame<
71 storages::mongo::operations::Find,
72 // NOLINTNEXTLINE(readability-static-accessed-through-instance)
73 decltype(std::declval<const T&>().GetFindOperation(
74 std::declval<cache::UpdateType>(),
75 std::declval<const std::chrono::system_clock::time_point&>(),
76 std::declval<const std::chrono::system_clock::time_point&>(),
77 std::declval<const std::chrono::system_clock::duration&>()
78 ))>;
79
80template <typename T>
81inline constexpr bool kHasCorrectFindOperation = meta::IsDetected<HasCorrectFindOperation, T>;
82
83template <typename T>
84using HasDefaultFindOperation = decltype(T::kUseDefaultFindOperation);
85template <typename T>
86inline constexpr bool kHasDefaultFindOperation = meta::IsDetected<HasDefaultFindOperation, T>;
87
88template <typename T>
89using HasInvalidDocumentsSkipped = decltype(T::kAreInvalidDocumentsSkipped);
90template <typename T>
91inline constexpr bool kHasInvalidDocumentsSkipped = meta::IsDetected<HasInvalidDocumentsSkipped, T>;
92
93template <typename>
94struct ClassByMemberPointer {};
95template <typename T, typename C>
96struct ClassByMemberPointer<T C::*> {
97 using type = C;
98};
99template <typename CollectionPtr>
100using CollectionsType = typename ClassByMemberPointer<std::remove_cv_t<CollectionPtr>>::type;
101
102template <typename MongoCacheTraits>
103struct CheckTraits {
104 CheckTraits() {
105 if constexpr (kHasDefaultDeserializeObject<MongoCacheTraits>) {
106 static_assert(
107 std::is_same_v<std::decay_t<decltype(MongoCacheTraits::kUseDefaultDeserializeObject)>, bool>,
108 "Mongo cache traits must specify kUseDefaultDeserializeObject as "
109 "bool"
110 );
111 }
112 if constexpr (kHasDefaultFindOperation<MongoCacheTraits>) {
113 static_assert(
114 std::is_same_v<std::decay_t<decltype(MongoCacheTraits::kUseDefaultFindOperation)>, bool>,
115 "Mongo cache traits must specify kUseDefaultFindOperation as bool"
116 );
117 }
118 }
119
120 static_assert(kHasCollectionsField<MongoCacheTraits>, "Mongo cache traits must specify collections field");
121 static_assert(kHasKeyField<MongoCacheTraits>, "Mongo cache traits must specify key field");
122 static_assert(kHasValidDataType<MongoCacheTraits>, "Mongo cache traits must specify mapping data type");
123
124 static_assert(kHasSecondaryPreferred<MongoCacheTraits>, "Mongo cache traits must specify read preference");
125 static_assert(
126 std::is_same_v<std::decay_t<decltype(MongoCacheTraits::kIsSecondaryPreferred)>, bool>,
127 "Mongo cache traits must specify read preference of a bool type"
128 );
129
130 static_assert(kHasInvalidDocumentsSkipped<MongoCacheTraits>, "Mongo cache traits must specify validation policy");
131 static_assert(
132 std::is_same_v<std::decay_t<decltype(MongoCacheTraits::kAreInvalidDocumentsSkipped)>, bool>,
133 "Mongo cache traits must specify validation policy of a bool type"
134 );
135
136 static_assert(
137 kHasFindOperation<MongoCacheTraits> || kHasDefaultFindOperation<MongoCacheTraits>,
138 "Mongo cache traits must specify find operation"
139 );
140 static_assert(
141 !kHasFindOperation<MongoCacheTraits> || kHasCorrectFindOperation<MongoCacheTraits>,
142 "Mongo cache traits must specify find operation with correct "
143 "signature and return value type: "
144 "static storages::mongo::operations::Find GetFindOperation("
145 "cache::UpdateType type, "
146 "const std::chrono::system_clock::time_point& last_update, "
147 "const std::chrono::system_clock::time_point& now, "
148 "const std::chrono::system_clock::duration& correction)"
149 );
150
151 static_assert(
152 kHasDeserializeObject<MongoCacheTraits> || kHasDefaultDeserializeObject<MongoCacheTraits>,
153 "Mongo cache traits must specify deserialize object"
154 );
155 static_assert(
156 !kHasDeserializeObject<MongoCacheTraits> || kHasCorrectDeserializeObject<MongoCacheTraits>,
157 "Mongo cache traits must specify deserialize object with correct "
158 "signature and return value type: "
159 "static ObjectType DeserializeObject(const formats::bson::Document& "
160 "doc)"
161 );
162};
163
164} // namespace mongo_cache::impl
165
166USERVER_NAMESPACE_END