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");