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, std::size_t path_size) {
28 UINVARIANT(path_size != 0,
"attempt to get a ValueBuilder element on an empty path");
30 return parent[std::move(path[0])];
32 std::optional<ValueBuilder> current_element;
34 current_element.emplace(TransferTag(), parent[std::move(path[0])]);
35 for (std::size_t i = 1; i < path_size - 1; i++) {
36 current_element.emplace(TransferTag(), (*current_element)[std::move(path[i])]);
38 return (*current_element)[std::move(path[path_size - 1])];
47template <
typename Value>
49 auto current_value = std::move(parent);
50 for (
const auto& current_key : path) {
51 current_value = current_value[current_key];
60template <
typename ValueBuilder>
63 return impl::GetAtPath(parent, std::move(path), path.size());
70template <
typename Value>
71void SetAtPath(
typename Value::Builder& parent, std::vector<std::string>&& path, Value new_value) {
73 parent = std::move(new_value);
75 GetAtPath(parent, std::move(path)) = std::move(new_value);
84template <
typename ValueBuilder>
85void RemoveAtPath(ValueBuilder& parent, std::vector<std::string>&& path) {
87 parent = ValueBuilder();
88 }
else if (path.size() == 1) {
89 parent.Remove(path[0]);
91 auto& key = path[path.size() - 1];
92 impl::GetAtPath(parent, std::move(path), path.size() - 1).Remove(key);