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,
75 DefaultAsJsonString default_json);
84 template <std::size_t N>
85 Key(DocsMapParser parser,
const ConfigDefault (&default_json_map)[N]);
88 Key(ConstantConfig, VariableType value);
91 Key(impl::InternalTag, std::string_view name);
93 Key(impl::InternalTag, DocsMapParser parser);
96 Key(
const Key&)
noexcept =
delete;
97 Key& operator=(
const Key&)
noexcept =
delete;
106 VariableType
Parse(
const DocsMap& docs_map)
const;
109 friend struct impl::ConfigIdGetter;
111 const impl::ConfigId id_;
132class Snapshot
final {
134 Snapshot(
const Snapshot&);
135 Snapshot& operator=(
const Snapshot&);
137 Snapshot(Snapshot&&)
noexcept;
138 Snapshot& operator=(Snapshot&&)
noexcept;
143 template <
typename VariableType>
144 const VariableType&
operator[](
const Key<VariableType>& key)
const&;
147 template <
typename VariableType>
148 const VariableType&
operator[](
const Key<VariableType>&) &&;
152 template <
typename T>
153 const T& Get()
const&;
156 template <
typename T>
163 friend class impl::StorageData;
165 explicit Snapshot(
const impl::StorageData& storage);
167 const impl::SnapshotData& GetData()
const;
170 utils::FastPimpl<Impl, 16, 8> impl_;
175constexpr DefaultAsJsonString::DefaultAsJsonString(std::string_view json_string)
176 : json_string(json_string) {}
179ConfigDefault::ConfigDefault(std::string_view name,
const T& value)
180 : name(name), default_json(impl::ToJsonString(value)) {}
182template <
typename Variable>
183Key<Variable>::
Key(std::string_view name,
const VariableType& default_value)
191template <
typename Variable>
192Key<Variable>::
Key(std::string_view name, DefaultAsJsonString default_json)
200template <
typename Variable>
201Key<Variable>::
Key(std::string_view name, JsonParser parser,
202 DefaultAsJsonString default_json)
210template <
typename Variable>
211template <std::size_t N>
212Key<Variable>::
Key(DocsMapParser parser,
213 const ConfigDefault (&default_json_map)[N])
214 : id_(impl::Register(
216 [parser](
const DocsMap& docs_map) -> std::any {
217 return parser(docs_map);
219 impl::MultipleToDocsMapString(default_json_map, N))) {}
221template <
typename Variable>
222Key<Variable>::
Key(ConstantConfig , VariableType value)
223 : id_(impl::Register(
225 [value = std::move(value)](
const DocsMap& ) {
230template <
typename Variable>
231Key<Variable>::Key(impl::InternalTag, std::string_view name)
232 : id_(impl::Register(
234 [name = std::string{name}](
const auto& docs_map) -> std::any {
235 return impl::DocsMapGet(docs_map, name).
template As<VariableType>();
239template <
typename Variable>
240Key<Variable>::Key(impl::InternalTag, DocsMapParser parser)
241 : id_(impl::Register(
243 [parser](
const DocsMap& docs_map) -> std::any {
244 return parser(docs_map);
248template <
typename VariableType>
250 return impl::GetName(id_);
253template <
typename VariableType>
254VariableType Key<VariableType>::
Parse(
const DocsMap& docs_map)
const {
255 return std::any_cast<VariableType>(impl::MakeConfig(id_, docs_map));
258template <
typename VariableType>
259const VariableType& Snapshot::
operator[](
const Key<VariableType>& key)
const& {
260 return GetData().Get<VariableType>(impl::ConfigIdGetter::Get(key));
263template <
typename VariableType>
264const VariableType& Snapshot::
operator[](
const Key<VariableType>&) && {
265 static_assert(!
sizeof(VariableType),
266 "keep the Snapshot before using, please");
270const T& Snapshot::Get()
const& {
271 return (*
this)[T::kDeprecatedKey];
275const T& Snapshot::Get() && {
276 static_assert(!
sizeof(T),
"keep the Snapshot before using, please");