10#include <userver/dynamic_config/impl/snapshot.hpp>
11#include <userver/dynamic_config/impl/to_json.hpp>
12#include <userver/formats/json_fwd.hpp>
13#include <userver/utils/fast_pimpl.hpp>
15USERVER_NAMESPACE_BEGIN
17namespace dynamic_config {
20struct DefaultAsJsonString
final {
21 constexpr explicit DefaultAsJsonString(std::string_view json_string);
23 std::string_view json_string;
27struct ConfigDefault
final {
29 ConfigDefault(std::string_view name,
const T& value);
31 ConfigDefault(std::string_view name, DefaultAsJsonString default_json);
33 std::string_view name;
34 std::string default_json;
38struct ConstantConfig
final {
39 constexpr explicit ConstantConfig() =
default;
44template <
typename Variable>
48 using VariableType = Variable;
50 using JsonParser = Variable (*)(
const formats::
json::Value&);
51 using DocsMapParser = Variable (*)(
const DocsMap&);
58 Key(std::string_view name,
const VariableType& default_value);
68 Key(std::string_view name, DefaultAsJsonString default_json);
74 Key(std::string_view name, JsonParser parser, DefaultAsJsonString default_json);
83 template <std::size_t N>
84 Key(DocsMapParser parser,
const ConfigDefault (&default_json_map)[N]);
87 Key(ConstantConfig, VariableType value);
90 Key(impl::InternalTag, std::string_view name);
92 Key(impl::InternalTag, DocsMapParser parser);
95 Key(
const Key&)
noexcept =
delete;
96 Key& operator=(
const Key&)
noexcept =
delete;
105 VariableType
Parse(
const DocsMap& docs_map)
const;
108 friend struct impl::ConfigIdGetter;
110 const impl::ConfigId id_;
131class Snapshot
final {
133 Snapshot(
const Snapshot&);
134 Snapshot& operator=(
const Snapshot&);
136 Snapshot(Snapshot&&)
noexcept;
137 Snapshot& operator=(Snapshot&&)
noexcept;
142 template <
typename VariableType>
143 const VariableType&
operator[](
const Key<VariableType>& key)
const&;
146 template <
typename VariableType>
147 const VariableType&
operator[](
const Key<VariableType>&) &&;
151 template <
typename T>
152 const T& Get()
const&;
155 template <
typename T>
162 friend class impl::StorageData;
164 explicit Snapshot(
const impl::StorageData& storage);
166 const impl::SnapshotData& GetData()
const;
169 utils::FastPimpl<Impl, 16, 8> impl_;
174constexpr DefaultAsJsonString::DefaultAsJsonString(std::string_view json_string) : json_string(json_string) {}
177ConfigDefault::ConfigDefault(std::string_view name,
const T& value)
178 : name(name), default_json(impl::ToJsonString(value)) {}
180template <
typename Variable>
181Key<Variable>::
Key(std::string_view name,
const VariableType& default_value)
190template <
typename Variable>
191Key<Variable>::
Key(std::string_view name, DefaultAsJsonString default_json)
200template <
typename Variable>
201Key<Variable>::
Key(std::string_view name, JsonParser parser, DefaultAsJsonString default_json)
210template <
typename Variable>
211template <std::size_t N>
212Key<Variable>::
Key(DocsMapParser parser,
const ConfigDefault (&default_json_map)[N])
213 : id_(impl::Register(
215 [parser](
const DocsMap& docs_map) -> std::any {
return parser(docs_map); },
216 impl::MultipleToDocsMapString(default_json_map, N)
219template <
typename Variable>
220Key<Variable>::
Key(ConstantConfig , VariableType value)
221 : id_(impl::Register(
223 [value = std::move(value)](
const DocsMap& ) {
return value; },
227template <
typename Variable>
228Key<Variable>::Key(impl::InternalTag, std::string_view name)
229 : id_(impl::Register(
231 [name = std::string{name}](
const auto& docs_map) -> std::any {
232 return impl::DocsMapGet(docs_map, name).
template As<VariableType>();
237template <
typename Variable>
238Key<Variable>::Key(impl::InternalTag, DocsMapParser parser)
239 : id_(impl::Register(
241 [parser](
const DocsMap& docs_map) -> std::any {
return parser(docs_map); },
245template <
typename VariableType>
247 return impl::GetName(id_);
250template <
typename VariableType>
251VariableType Key<VariableType>::
Parse(
const DocsMap& docs_map)
const {
252 return std::any_cast<VariableType>(impl::MakeConfig(id_, docs_map));
255template <
typename VariableType>
256const VariableType& Snapshot::
operator[](
const Key<VariableType>& key)
const& {
257 return GetData().Get<VariableType>(impl::ConfigIdGetter::Get(key));
260template <
typename VariableType>
261const VariableType& Snapshot::
operator[](
const Key<VariableType>&) && {
262 static_assert(!
sizeof(VariableType),
"keep the Snapshot before using, please");
266const T& Snapshot::Get()
const& {
267 return (*
this)[T::kDeprecatedKey];
271const T& Snapshot::Get() && {
272 static_assert(!
sizeof(T),
"keep the Snapshot before using, please");