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