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 {
27 public:
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)),
41
42 /// For internal use only
43 impl::ConfigId GetId() const { return id_; }
44
45 /// For internal use only
46 std::any GetValue() const { return value_; }
47
48 private:
49 template <typename VariableType, typename Value>
50 static VariableType Convert(Value&& value) {
51 if constexpr (std::is_same_v<std::decay_t<Value>, formats::json::Value>) {
52 return value.template As<VariableType>();
53 } else {
54 return static_cast<VariableType>(std::forward<Value>(value));
55 }
56 }
57
58 impl::ConfigId id_;
59 std::any value_;
60};
61
62/// @brief Backing storage for `dynamic_config::Source` in tests and benchmarks
63/// @warning Make sure that `StorageMock` outlives all the acquired pointers!
64/// @snippet core/src/dynamic_config/config_test.cpp Sample StorageMock usage
65/// @snippet core/src/dynamic_config/config_test.cpp StorageMock from JSON
66/// @see dynamic_config::GetDefaultSource
67/// @see dynamic_config::MakeDefaultStorage
68class StorageMock final {
69 public:
70 /// Create an empty `StorageMock`
72
73 /// Only store `config_variables` in the `Config`.
74 /// Use as: `StorageMock{{kVariableKey1, value1}, {kVariableKey2, value2}}`
75 StorageMock(std::initializer_list<KeyValue> config_variables);
76
77 /// Only store `config_variables` in the `Config`
78 explicit StorageMock(const std::vector<KeyValue>& config_variables);
79
80 /// @brief Store `overrides` in the `Config`, then parse all the remaining
81 /// variables from `defaults`
82 /// @see dynamic_config::MakeDefaultStorage
83 StorageMock(const DocsMap& defaults, const std::vector<KeyValue>& overrides);
84
85 StorageMock(StorageMock&&) noexcept;
86 StorageMock& operator=(StorageMock&&) noexcept;
87 ~StorageMock();
88
89 /// Update some config variables
90 void Extend(const std::vector<KeyValue>& overrides);
91
92 Source GetSource() const&;
93 Snapshot GetSnapshot() const&;
94
95 // Store the StorageMock in a variable before using
96 Snapshot GetSource() && = delete;
97 Snapshot GetSnapshot() && = delete;
98
99 private:
100 std::unique_ptr<impl::StorageData> storage_;
101};
102
103} // namespace dynamic_config
104
105USERVER_NAMESPACE_END