6#include <ydb-cpp-sdk/client/value/value.h>
13#include <userver/utils/assert.hpp>
14#include <userver/utils/meta.hpp>
16#include <userver/ydb/io/generic_optional.hpp>
17#include <userver/ydb/io/traits.hpp>
19USERVER_NAMESPACE_BEGIN
26class ParseItemsIterator final {
28 using difference_type = std::ptrdiff_t;
31 using iterator_category = std::input_iterator_tag;
33 ParseItemsIterator() =
default;
35 ParseItemsIterator(NYdb::TValueParser& parser,
const ParseContext& context)
43 ParseItemsIterator(
const ParseItemsIterator&) =
default;
44 ParseItemsIterator& operator=(
const ParseItemsIterator&) =
default;
48 return ydb::Parse<T>(*parser_, *context_);
51 ParseItemsIterator& operator++() {
53 if (!parser_->TryNextListItem()) {
59 bool operator==(
const ParseItemsIterator& other)
const noexcept {
60 UASSERT(parser_ ==
nullptr || other.parser_ ==
nullptr);
61 return parser_ == other.parser_;
65 NYdb::TValueParser* parser_{
nullptr};
66 const ParseContext* context_{
nullptr};
77requires meta::kIsRange<T> && (!meta::kIsMap<T>)
79 using ValueType = meta::RangeValueType<T>;
81 static T Parse(NYdb::TValueParser& parser,
const ParseContext& context) {
83#if __cpp_lib_ranges_to_container >= 202202L
85 std::ranges::subrange{
86 impl::ParseItemsIterator<ValueType>{parser, context},
87 impl::ParseItemsIterator<ValueType>{},
91 T result(impl::ParseItemsIterator<ValueType>{parser, context}, impl::ParseItemsIterator<ValueType>{});
97 template <
typename Builder,
typename U =
const T&>
98 static void Write(NYdb::TValueBuilderBase<Builder>& builder, U&& value) {
99 bool list_opened =
false;
100 for (
auto&& item : value) {
105 builder.AddListItem();
110 }
else if constexpr (std::is_same_v<ValueType, InsertRow>) {
115 builder.EmptyList(
ValueTraits<ValueType>::MakeType());
119 static NYdb::TType MakeType() {
120 NYdb::TTypeBuilder builder;
122 return builder.Build();
127requires meta::kIsRange<T> && (!meta::kIsMap<T>)
128struct ValueTraits<std::optional<T>> : impl::GenericOptionalValueTraits<T> {};