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