15#include <userver/formats/common/meta.hpp> 
   16#include <userver/formats/common/transfer_tag.hpp> 
   17#include <userver/formats/common/type.hpp> 
   18#include <userver/utils/assert.hpp> 
   20USERVER_NAMESPACE_BEGIN
 
   26template <
typename ValueBuilder>
 
   27ValueBuilder GetAtPath(ValueBuilder& parent, std::vector<std::string>&& path,
 
   28                       std::size_t path_size) {
 
   30             "attempt to get a ValueBuilder element on an empty path");
 
   32    return parent[std::move(path[0])];
 
   34  std::optional<ValueBuilder> current_element;
 
   36  current_element.emplace(TransferTag(), parent[std::move(path[0])]);
 
   37  for (std::size_t i = 1; i < path_size - 1; i++) {
 
   38    current_element.emplace(TransferTag(),
 
   39                            (*current_element)[std::move(path[i])]);
 
   41  return (*current_element)[std::move(path[path_size - 1])];
 
   50template <
typename Value>
 
   53  auto current_value = std::move(parent);
 
   54  for (
const auto& current_key : path) {
 
   55    current_value = current_value[current_key];
 
   64template <
typename ValueBuilder>
 
   67  return impl::GetAtPath(parent, std::move(path), path.size());
 
   74template <
typename Value>
 
   75void SetAtPath(
typename Value::Builder& parent, std::vector<std::string>&& path,
 
   78    parent = std::move(new_value);
 
   80    GetAtPath(parent, std::move(path)) = std::move(new_value);
 
   89template <
typename ValueBuilder>
 
   90void RemoveAtPath(ValueBuilder& parent, std::vector<std::string>&& path) {
 
   92    parent = ValueBuilder();
 
   93  } 
else if (path.size() == 1) {
 
   94    parent.Remove(path[0]);
 
   96    auto& key = path[path.size() - 1];
 
   97    impl::GetAtPath(parent, std::move(path), path.size() - 1).Remove(key);