userver: userver/dynamic_config/storage_mock.hpp Source File
Loading...
Searching...
No Matches
storage_mock.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/dynamic_config/storage_mock.hpp
4/// @brief @copybrief dynamic_config::StorageMock
5
6#include <initializer_list>
7#include <memory>
8#include <vector>
9
10#include <userver/dynamic_config/snapshot.hpp>
11#include <userver/dynamic_config/source.hpp>
12#include <userver/dynamic_config/value.hpp>
13#include <userver/formats/json/value.hpp>
14
15USERVER_NAMESPACE_BEGIN
16
17namespace dynamic_config {
18namespace impl {
19
20template <typename T>
21using IsJson = std::enable_if_t<std::is_same_v<T, formats::json::Value>>;
22
23} // namespace impl
24
25/// A type-erased config key-value pair
26class KeyValue final {
27public:
28 /// Uses the provided value directly. It can also be constructed in-place:
29 /// @code
30 /// {kMyConfig, {"foo", 42}}
31 /// @endcode
32 ///
33 /// When passed a formats::json::Value, parses the value from it:
34 /// @code
35 /// {kMyConfig, formats::json::FromString(R"({"foo": "what", "bar": 42})")}
36 /// @endcode
37 template <typename VariableType, typename Value = VariableType>
38 KeyValue(const Key<VariableType>& key, Value&& value)
39 : id_(impl::ConfigIdGetter::Get(key)), value_(Convert<VariableType>(std::forward<Value>(value))) {}
40
41 /// For internal use only
42 impl::ConfigId GetId() const { return id_; }
43
44 /// For internal use only
45 std::any GetValue() const { return value_; }
46
47private:
48 template <typename VariableType, typename Value>
49 static VariableType Convert(Value&& value) {
50 if constexpr (std::is_same_v<std::decay_t<Value>, formats::json::Value>) {
51 return value.template As<VariableType>();
52 } else {
53 return static_cast<VariableType>(std::forward<Value>(value));
54 }
55 }
56
57 impl::ConfigId id_;
58 std::any value_;
59};
60
61/// @brief Backing storage for `dynamic_config::Source` in tests and benchmarks
62/// @warning Make sure that `StorageMock` outlives all the acquired pointers!
63/// @snippet core/src/dynamic_config/config_test.cpp Sample StorageMock usage
64/// @snippet core/src/dynamic_config/config_test.cpp StorageMock from JSON
65/// @see dynamic_config::GetDefaultSource
66/// @see dynamic_config::MakeDefaultStorage
67class StorageMock final {
68public:
69 /// Create an empty `StorageMock`
71
72 /// Only store `config_variables` in the `Config`.
73 /// Use as: `StorageMock{{kVariableKey1, value1}, {kVariableKey2, value2}}`
74 StorageMock(std::initializer_list<KeyValue> config_variables);
75
76 /// Only store `config_variables` in the `Config`
77 explicit StorageMock(const std::vector<KeyValue>& config_variables);
78
79 /// @brief Store `overrides` in the `Config`, then parse all the remaining
80 /// variables from `defaults`
81 /// @see dynamic_config::MakeDefaultStorage
82 StorageMock(const DocsMap& defaults, const std::vector<KeyValue>& overrides);
83
84 StorageMock(StorageMock&&) noexcept;
85 StorageMock& operator=(StorageMock&&) noexcept;
86 ~StorageMock();
87
88 /// Update some config variables
89 void Extend(const std::vector<KeyValue>& overrides);
90
91 Source GetSource() const&;
92 Snapshot GetSnapshot() const&;
93
94 // Store the StorageMock in a variable before using
95 Snapshot GetSource() && = delete;
96 Snapshot GetSnapshot() && = delete;
97
98private:
99 std::unique_ptr<impl::StorageData> storage_;
100};
101
102} // namespace dynamic_config
103
104USERVER_NAMESPACE_END