3#include <ydb-cpp-sdk/client/value/value.h>
9#if __cpp_lib_ranges >= 201911L
13#include <userver/utils/assert.hpp>
14#include <userver/utils/meta.hpp>
16#include <userver/ydb/io/traits.hpp>
18USERVER_NAMESPACE_BEGIN
25class ParseItemsIterator final {
27 using difference_type = std::ptrdiff_t;
30 using iterator_category = std::input_iterator_tag;
32 ParseItemsIterator() =
default;
34 ParseItemsIterator(NYdb::TValueParser& parser,
const ParseContext& context)
35 : parser_(&parser), context_(&context) {
40 ParseItemsIterator(
const ParseItemsIterator&) =
default;
41 ParseItemsIterator& operator=(
const ParseItemsIterator&) =
default;
45 return ydb::Parse<T>(*parser_, *context_);
48 ParseItemsIterator& operator++() {
50 if (!parser_->TryNextListItem()) {
56 bool operator==(
const ParseItemsIterator& other)
const noexcept {
57 UASSERT(parser_ ==
nullptr || other.parser_ ==
nullptr);
58 return parser_ == other.parser_;
62 NYdb::TValueParser* parser_{
nullptr};
63 const ParseContext* context_{
nullptr};
70using InsertRow = std::vector<InsertColumn>;
74struct ValueTraits<T, std::enable_if_t<meta::kIsRange<T> && !meta::kIsMap<T>>> {
75 using ValueType = meta::RangeValueType<T>;
77 static T Parse(NYdb::TValueParser& parser,
const ParseContext& context) {
79#if __cpp_lib_ranges_to_container >= 202202L
81 std::ranges::subrange{
82 impl::ParseItemsIterator<ValueType>{parser, context},
83 impl::ParseItemsIterator<ValueType>{},
87 T result(impl::ParseItemsIterator<ValueType>{parser, context},
88 impl::ParseItemsIterator<ValueType>{});
94 template <
typename Builder,
typename U =
const T&>
95 static void Write(NYdb::TValueBuilderBase<Builder>& builder, U&& value) {
96 bool list_opened =
false;
97 for (
auto&& item : value) {
102 builder.AddListItem();
103 ydb::Write(builder, item);
107 }
else if constexpr (std::is_same_v<ValueType, InsertRow>) {
112 builder.EmptyList(ValueTraits<ValueType>::MakeType());
116 static NYdb::TType MakeType() {
117 NYdb::TTypeBuilder builder;
118 builder.List(ValueTraits<ValueType>::MakeType());
119 return builder.Build();