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;
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);
80 template <std::size_t N>
81 Key(DocsMapParser parser,
const ConfigDefault (&default_json_map)[N]);
84 Key(ConstantConfig, VariableType value);
87 Key(impl::InternalTag, std::string_view name);
89 Key(impl::InternalTag, DocsMapParser parser);
92 Key(
const Key&)
noexcept =
delete;
93 Key& operator=(
const Key&)
noexcept =
delete;
96 std::string_view
GetName()
const noexcept;
102 VariableType
Parse(
const DocsMap& docs_map)
const;
105 friend struct impl::ConfigIdGetter;
107 const impl::ConfigId id_;
128class Snapshot
final {
130 Snapshot(
const Snapshot&);
131 Snapshot& operator=(
const Snapshot&);
133 Snapshot(Snapshot&&)
noexcept;
134 Snapshot& operator=(Snapshot&&)
noexcept;
139 template <
typename VariableType>
140 const VariableType&
operator[](
const Key<VariableType>& key)
const&;
143 template <
typename VariableType>
144 const VariableType&
operator[](
const Key<VariableType>&) &&;
148 template <
typename T>
149 const T& Get()
const&;
152 template <
typename T>
159 friend class impl::StorageData;
161 explicit Snapshot(
const impl::StorageData& storage);
163 const impl::SnapshotData& GetData()
const;
166 utils::FastPimpl<Impl, 16, 8> impl_;
171constexpr DefaultAsJsonString::DefaultAsJsonString(std::string_view json_string)
172 : json_string(json_string)
176ConfigDefault::ConfigDefault(std::string_view name,
const T& value)
178 default_json(impl::ToJsonString(value))
181template <
typename Variable>
182Key<Variable>::
Key(std::string_view name,
const VariableType& default_value)
183 : id_(impl::Register(
185 [name = std::string{name}](
const auto& docs_map) -> std::any {
186 return impl::DocsMapGet(docs_map, name).
template As<VariableType>();
188 impl::ValueToDocsMapString(name, default_value)
192template <
typename Variable>
193Key<Variable>::
Key(std::string_view name, DefaultAsJsonString default_json)
194 : id_(impl::Register(
196 [name = std::string{name}](
const auto& docs_map) -> std::any {
197 return impl::DocsMapGet(docs_map, name).
template As<VariableType>();
199 impl::SingleToDocsMapString(name, default_json.json_string)
203template <
typename Variable>
204Key<Variable>::
Key(std::string_view name, JsonParser parser, DefaultAsJsonString default_json)
205 : id_(impl::Register(
207 [name = std::string{name}, parser](
const auto& docs_map) -> std::any {
208 return parser(impl::DocsMapGet(docs_map, name));
210 impl::SingleToDocsMapString(name, default_json.json_string)
214template <
typename Variable>
215template <std::size_t N>
216Key<Variable>::
Key(DocsMapParser parser,
const ConfigDefault (&default_json_map)[N])
217 : id_(impl::Register(
219 [parser](
const DocsMap& docs_map) -> std::any {
return parser(docs_map); },
220 impl::MultipleToDocsMapString(default_json_map, N)
224template <
typename Variable>
225Key<Variable>::
Key(ConstantConfig , VariableType value)
226 : id_(impl::Register(std::string{}, [value = std::move(value)](
const DocsMap& ) {
return value; },
"{}"))
229template <
typename Variable>
230Key<Variable>::Key(impl::InternalTag, std::string_view name)
231 : id_(impl::Register(
233 [name = std::string{name}](
const auto& docs_map) -> std::any {
234 return impl::DocsMapGet(docs_map, name).
template As<VariableType>();
240template <
typename Variable>
241Key<Variable>::Key(impl::InternalTag, DocsMapParser parser)
242 : id_(impl::Register(
244 [parser](
const DocsMap& docs_map) -> std::any {
return parser(docs_map); },
249template <
typename VariableType>
250std::string_view Key<VariableType>::
GetName()
const noexcept {
251 return impl::GetName(id_);
254template <
typename VariableType>
255VariableType Key<VariableType>::
Parse(
const DocsMap& docs_map)
const {
256 return std::any_cast<VariableType>(impl::MakeConfig(id_, docs_map));
259template <
typename VariableType>
260const VariableType& Snapshot::
operator[](
const Key<VariableType>& key)
const& {
261 return GetData().Get<VariableType>(impl::ConfigIdGetter::Get(key));
264template <
typename VariableType>
265const VariableType& Snapshot::
operator[](
const Key<VariableType>&) && {
266 static_assert(!
sizeof(VariableType),
"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");