diff options
author | arkady-e1ppa <arkady-e1ppa@yandex-team.com> | 2024-05-08 19:50:23 +0300 |
---|---|---|
committer | arkady-e1ppa <arkady-e1ppa@yandex-team.com> | 2024-05-08 20:01:56 +0300 |
commit | b9848536fa2642fab34114a1779ab886881495c4 (patch) | |
tree | be492d31a4bd081464e936c3ac6187762731ca7c /yt | |
parent | f2d47d896f4913ff5da2f328149322516fbadde6 (diff) | |
download | ydb-b9848536fa2642fab34114a1779ab886881495c4.tar.gz |
YT-21310: Introduce CYsonStructSource to remove code duplication in TYsonStruct implementation (now with a fixed bug)
94a777c1510546c0a8a7ef3e3b327add7dfc3813
Diffstat (limited to 'yt')
-rw-r--r-- | yt/yt/core/ytree/yson_struct-inl.h | 24 | ||||
-rw-r--r-- | yt/yt/core/ytree/yson_struct.cpp | 6 | ||||
-rw-r--r-- | yt/yt/core/ytree/yson_struct.h | 31 | ||||
-rw-r--r-- | yt/yt/core/ytree/yson_struct_detail-inl.h | 440 | ||||
-rw-r--r-- | yt/yt/core/ytree/yson_struct_detail.h | 34 | ||||
-rw-r--r-- | yt/yt/core/ytree/yson_struct_enum.h | 21 | ||||
-rw-r--r-- | yt/yt/core/ytree/yson_struct_public.h | 48 |
7 files changed, 312 insertions, 292 deletions
diff --git a/yt/yt/core/ytree/yson_struct-inl.h b/yt/yt/core/ytree/yson_struct-inl.h index 75f5b1db1d..baa01de7b5 100644 --- a/yt/yt/core/ytree/yson_struct-inl.h +++ b/yt/yt/core/ytree/yson_struct-inl.h @@ -264,8 +264,7 @@ TYsonStructRegistrar<TStruct>::operator TYsonStructRegistrar<TBase>() //////////////////////////////////////////////////////////////////////////////// -template <class T> - requires CExternallySerializable<T> +template <CExternallySerializable T> void Serialize(const T& value, NYson::IYsonConsumer* consumer) { using TSerializer = typename TGetExternalizedYsonStructTraits<T>::TExternalSerializer; @@ -273,28 +272,13 @@ void Serialize(const T& value, NYson::IYsonConsumer* consumer) Serialize(serializer, consumer); } -template <class T> - requires CExternallySerializable<T> -void DeserializeExternalized(T& value, INodePtr node, bool postprocess, bool setDefaults) +template <CExternallySerializable T, CYsonStructSource TSource> +void Deserialize(T& value, TSource source, bool postprocess, bool setDefaults) { using TTraits = TGetExternalizedYsonStructTraits<T>; using TSerializer = typename TTraits::TExternalSerializer; auto serializer = TSerializer::template CreateWritable<T, TSerializer>(value, setDefaults); - serializer.Load(node, postprocess, setDefaults); -} - -template <class T> - requires CExternallySerializable<T> -void Deserialize(T& value, INodePtr node) -{ - DeserializeExternalized(value, std::move(node), /*postprocess*/ true, /*setDefaults*/ true); -} - -template <class T> - requires CExternallySerializable<T> -void Deserialize(T& value, NYson::TYsonPullParserCursor* cursor) -{ - Deserialize(value, NYson::ExtractTo<NYTree::INodePtr>(cursor)); + serializer.Load(std::move(source), postprocess, setDefaults); } template <class T> diff --git a/yt/yt/core/ytree/yson_struct.cpp b/yt/yt/core/ytree/yson_struct.cpp index b939d17b9a..fbdad0be6b 100644 --- a/yt/yt/core/ytree/yson_struct.cpp +++ b/yt/yt/core/ytree/yson_struct.cpp @@ -51,16 +51,16 @@ void TYsonStructBase::Load( INodePtr node, bool postprocess, bool setDefaults, - const TYPath& path) + const NYPath::TYPath& path) { - Meta_->LoadStruct(this, node, postprocess, setDefaults, path); + Meta_->LoadStruct(this, std::move(node), postprocess, setDefaults, path); } void TYsonStructBase::Load( TYsonPullParserCursor* cursor, bool postprocess, bool setDefaults, - const TYPath& path) + const NYPath::TYPath& path) { Meta_->LoadStruct(this, cursor, postprocess, setDefaults, path); } diff --git a/yt/yt/core/ytree/yson_struct.h b/yt/yt/core/ytree/yson_struct.h index 19300099bf..5d384840a8 100644 --- a/yt/yt/core/ytree/yson_struct.h +++ b/yt/yt/core/ytree/yson_struct.h @@ -1,13 +1,14 @@ #pragma once #include "node.h" -#include "yson_struct_enum.h" +#include "yson_struct_public.h" #include <yt/yt/core/misc/error.h> #include <yt/yt/core/misc/mpl.h> #include <yt/yt/core/misc/property.h> #include <yt/yt/core/yson/public.h> + #include <yt/yt/library/syncmap/map.h> #include <library/cpp/yt/misc/enum.h> @@ -62,7 +63,7 @@ public: virtual ~TYsonStructBase() = default; void Load( - NYTree::INodePtr node, + INodePtr node, bool postprocess = true, bool setDefaults = true, const NYPath::TYPath& path = {}); @@ -293,21 +294,6 @@ private: //////////////////////////////////////////////////////////////////////////////// template <class T> -concept CExternalizedYsonStructTraits = requires { - typename T::TExternalSerializer; -}; - -template <class T> -concept CExternallySerializable = requires (T t) { - { GetExternalizedYsonStructTraits(t) } -> CExternalizedYsonStructTraits; -}; - -template <CExternallySerializable T> -using TGetExternalizedYsonStructTraits = decltype(GetExternalizedYsonStructTraits(std::declval<T>())); - -//////////////////////////////////////////////////////////////////////////////// - -template <class T> TIntrusivePtr<T> CloneYsonStruct(const TIntrusivePtr<const T>& obj); template <class T> TIntrusivePtr<T> CloneYsonStruct(const TIntrusivePtr<T>& obj); @@ -320,15 +306,10 @@ void Serialize(const TYsonStructBase& value, NYson::IYsonConsumer* consumer); void Deserialize(TYsonStructBase& value, INodePtr node); void Deserialize(TYsonStructBase& value, NYson::TYsonPullParserCursor* cursor); -template <class T> - requires CExternallySerializable<T> +template <CExternallySerializable T> void Serialize(const T& value, NYson::IYsonConsumer* consumer); -template <class T> - requires CExternallySerializable<T> -void Deserialize(T& value, INodePtr node); -template <class T> - requires CExternallySerializable<T> -void Deserialize(T& value, NYson::TYsonPullParserCursor* cursor); +template <CExternallySerializable T, CYsonStructSource TSource> +void Deserialize(T& value, TSource source, bool postprocess = true, bool setDefaults = true); template <class T> TIntrusivePtr<T> UpdateYsonStruct( diff --git a/yt/yt/core/ytree/yson_struct_detail-inl.h b/yt/yt/core/ytree/yson_struct_detail-inl.h index 8c02116c43..c34a934c16 100644 --- a/yt/yt/core/ytree/yson_struct_detail-inl.h +++ b/yt/yt/core/ytree/yson_struct_detail-inl.h @@ -35,223 +35,175 @@ concept SupportsDontSerializeDefault = //////////////////////////////////////////////////////////////////////////////// -// Primitive type template <class T> -void LoadFromNode( - T& parameter, - NYTree::INodePtr node, - const NYPath::TYPath& path, - std::optional<EUnrecognizedStrategy> /*recursiveUnrecognizedStrategy*/) -{ - try { - Deserialize(parameter, node); - } catch (const std::exception& ex) { - THROW_ERROR_EXCEPTION("Error reading parameter %v", path) - << ex; - } -} - -// INodePtr -template <> -inline void LoadFromNode( - NYTree::INodePtr& parameter, - NYTree::INodePtr node, - const NYPath::TYPath& /*path*/, - std::optional<EUnrecognizedStrategy> /*recursiveUnrecognizedStrategy*/) +T DeserializeMapKey(TStringBuf value) { - if (!parameter) { - parameter = node; + if constexpr (TEnumTraits<T>::IsEnum) { + return ParseEnum<T>(value); + } else if constexpr (std::is_same_v<T, TGuid>) { + return TGuid::FromString(value); + } else if constexpr (TStrongTypedefTraits<T>::IsStrongTypedef) { + return T(DeserializeMapKey<typename TStrongTypedefTraits<T>::TUnderlying>(value)); } else { - parameter = PatchNode(parameter, node); + return FromString<T>(value); } } -// TYsonStruct -template <CYsonStructDerived T> -void LoadFromNode( - TIntrusivePtr<T>& parameterValue, - NYTree::INodePtr node, - const NYPath::TYPath& path, - std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy) +//////////////////////////////////////////////////////////////////////////////// + +template <class T> +concept CNodePtr = requires (T node) { + [] (INodePtr) { } (node); +}; + +template <CNodePtr TNodePtr> +struct TYsonSourceTraits<TNodePtr> { - if (!parameterValue) { - parameterValue = New<T>(); + static constexpr bool IsValid = true; + + static INodePtr AsNode(TNodePtr& source) + { + // NRVO. + return source; } - if (recursiveUnrecognizedStrategy) { - parameterValue->SetUnrecognizedStrategy(*recursiveUnrecognizedStrategy); + static bool IsEmpty(TNodePtr& source) + { + return source->GetType() == ENodeType::Entity; } - parameterValue->Load(node, /*postprocess*/ false, /*setDefaults*/ false, path); -} + static void Advance(TNodePtr& /*source*/) + { } -// YsonStructLite -template <std::derived_from<TYsonStructLite> T> -void LoadFromNode( - T& parameter, - NYTree::INodePtr node, - const NYPath::TYPath& path, - std::optional<EUnrecognizedStrategy> /*recursiveUnrecognizedStrategy*/) -{ - try { - parameter.Load(node, /*postprocess*/ false, /*setDefaults*/ false); - } catch (const std::exception& ex) { - THROW_ERROR_EXCEPTION("Error reading parameter %v", path) - << ex; + template <class... TArgs, class TFiller> + static void FillVector(TNodePtr& source, std::vector<TArgs...>& vector, TFiller filler) + { + auto listNode = source->AsList(); + auto size = listNode->GetChildCount(); + vector.reserve(size); + for (int i = 0; i < size; ++i) { + filler(vector, std::move(listNode->GetChildOrThrow(i))); + } } -} -// ExternalizedYsonStruct -template <CExternallySerializable T> -void LoadFromNode( - T& parameter, - NYTree::INodePtr node, - const NYPath::TYPath& path, - std::optional<EUnrecognizedStrategy> /*recursiveUnrecognizedStrategy*/) -{ - try { - DeserializeExternalized(parameter, node, /*postprocess*/ false, /*setDefaults*/ false); - } catch (const std::exception& ex) { - THROW_ERROR_EXCEPTION("Error reading parameter %v", path) - << ex; + template <CAnyMap TMap, class TFiller> + static void FillMap(TNodePtr& source, TMap& map, TFiller filler) + { + auto mapNode = source->AsMap(); + + // NB: We iterate over temporary object anyway. + // Might as well move key/child into the filler + for (auto [key, child] : mapNode->GetChildren()) { + filler(map, std::move(key), std::move(child)); + } } -} +}; -// std::optional -template <class T> -void LoadFromNode( - std::optional<T>& parameter, - NYTree::INodePtr node, - const NYPath::TYPath& path, - std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy) +template <> +struct TYsonSourceTraits<NYson::TYsonPullParserCursor*> { - if (node->GetType() == NYTree::ENodeType::Entity) { - parameter = std::nullopt; - return; + static constexpr bool IsValid = true; + + static INodePtr AsNode(NYson::TYsonPullParserCursor*& source) + { + return NYson::ExtractTo<NYTree::INodePtr>(source); } - if (parameter.has_value()) { - LoadFromNode(*parameter, node, path, recursiveUnrecognizedStrategy); - } else { - T value; - LoadFromNode(value, node, path, recursiveUnrecognizedStrategy); - parameter = std::move(value); + static bool IsEmpty(NYson::TYsonPullParserCursor*& source) + { + return (*source)->GetType() == NYson::EYsonItemType::EntityValue; } -} -// std::vector -template <class... T> -void LoadFromNode( - std::vector<T...>& parameter, - NYTree::INodePtr node, - const NYPath::TYPath& path, - std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy) -{ - auto listNode = node->AsList(); - auto size = listNode->GetChildCount(); - parameter.clear(); - parameter.reserve(size); - for (int i = 0; i < size; ++i) { - LoadFromNode( - parameter.emplace_back(), - listNode->GetChildOrThrow(i), - path + "/" + NYPath::ToYPathLiteral(i), - recursiveUnrecognizedStrategy); + static void Advance(NYson::TYsonPullParserCursor*& source) + { + source->Next(); } -} -template <class T> -T DeserializeMapKey(TStringBuf value) -{ - if constexpr (TEnumTraits<T>::IsEnum) { - return ParseEnum<T>(value); - } else if constexpr (std::is_same_v<T, TGuid>) { - return TGuid::FromString(value); - } else if constexpr (TStrongTypedefTraits<T>::IsStrongTypedef) { - return T(DeserializeMapKey<typename TStrongTypedefTraits<T>::TUnderlying>(value)); - } else { - return FromString<T>(value); + template <class... TArgs, class TFiller> + static void FillVector(NYson::TYsonPullParserCursor*& source, std::vector<TArgs...>& vector, TFiller filler) + { + source->ParseList([&](NYson::TYsonPullParserCursor* cursor) { + filler(vector, cursor); + }); } -} -// For any map. -template <template <typename...> class Map, class... T, class M = typename Map<T...>::mapped_type> -void LoadFromNode( - Map<T...>& parameter, - NYTree::INodePtr node, - const NYPath::TYPath& path, - std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy) -{ - auto mapNode = node->AsMap(); - for (const auto& [key, child] : mapNode->GetChildren()) { - M value; - LoadFromNode( - value, - child, - path + "/" + NYPath::ToYPathLiteral(key), - recursiveUnrecognizedStrategy); - parameter[DeserializeMapKey<typename Map<T...>::key_type>(key)] = std::move(value); + template <CAnyMap TMap, class TFiller> + static void FillMap(NYson::TYsonPullParserCursor*& source, TMap& map, TFiller filler) + { + source->ParseMap([&] (NYson::TYsonPullParserCursor* cursor) { + auto key = ExtractTo<TString>(cursor); + filler(map, std::move(key), source); + }); } -} +}; //////////////////////////////////////////////////////////////////////////////// -// Primitive type or YsonStructLite -// See LoadFromNode for further specialization. -template <class T> -void LoadFromCursor( - T& parameter, - NYson::TYsonPullParserCursor* cursor, - const NYPath::TYPath& path, - std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy) -{ - LoadFromNode(parameter, NYson::ExtractTo<NYTree::INodePtr>(cursor), path, recursiveUnrecognizedStrategy); -} - -//////////////////////////////////////////////////////////////////////////////// +// NB(arkady-e1ppa): We perform forward declaration of containers +// so that we can find the correct overload for any composition of them +// e.g. std::optional<std::vector<T>>. -template <CYsonStructDerived T> -void LoadFromCursor( - TIntrusivePtr<T>& parameterValue, - NYson::TYsonPullParserCursor* cursor, +// std::optional +template <class T, CYsonStructSource TSource> +void LoadFromSource( + std::optional<T>& parameter, + TSource source, const NYPath::TYPath& path, std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy); -template <class... T> -void LoadFromCursor( - std::vector<T...>& parameter, - NYson::TYsonPullParserCursor* cursor, +// std::vector +template <CStdVector TVector, CYsonStructSource TSource> +void LoadFromSource( + TVector& parameter, + TSource source, const NYPath::TYPath& path, std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy); -// std::optional -template <class T> -void LoadFromCursor( - std::optional<T>& parameter, - NYson::TYsonPullParserCursor* cursor, +// any map. +template <CAnyMap TMap, CYsonStructSource TSource> +void LoadFromSource( + TMap& parameter, + TSource source, const NYPath::TYPath& path, std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy); -template <template <typename...> class Map, class... T, class M = typename Map<T...>::mapped_type> -void LoadFromCursor( - Map<T...>& parameter, - NYson::TYsonPullParserCursor* cursor, +//////////////////////////////////////////////////////////////////////////////// + +// Primitive type +template <class T, CYsonStructSource TSource> +void LoadFromSource( + T& parameter, + TSource source, const NYPath::TYPath& path, - std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy); + std::optional<EUnrecognizedStrategy> /*ignored*/) +{ + using TTraits = TYsonSourceTraits<TSource>; -//////////////////////////////////////////////////////////////////////////////// + try { + Deserialize(parameter, TTraits::AsNode(source)); + } catch (const std::exception& ex) { + THROW_ERROR_EXCEPTION("Error reading parameter %v", path) + << ex; + } +} // INodePtr -template <> -inline void LoadFromCursor( - NYTree::INodePtr& parameter, - NYson::TYsonPullParserCursor* cursor, +template <CYsonStructSource TSource> +void LoadFromSource( + INodePtr& parameter, + TSource source, const NYPath::TYPath& path, - std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy) + std::optional<EUnrecognizedStrategy> /*ignored*/) { + using TTraits = TYsonSourceTraits<TSource>; + try { - auto node = NYson::ExtractTo<INodePtr>(cursor); - LoadFromNode(parameter, std::move(node), path, recursiveUnrecognizedStrategy); + auto node = TTraits::AsNode(source); + if (!parameter) { + parameter = std::move(node); + } else { + parameter = PatchNode(parameter, std::move(node)); + } } catch (const std::exception& ex) { THROW_ERROR_EXCEPTION("Error loading parameter %v", path) << ex; @@ -259,45 +211,82 @@ inline void LoadFromCursor( } // TYsonStruct -template <CYsonStructDerived T> -void LoadFromCursor( - TIntrusivePtr<T>& parameterValue, - NYson::TYsonPullParserCursor* cursor, +template <CYsonStructDerived T, CYsonStructSource TSource> +void LoadFromSource( + TIntrusivePtr<T>& parameter, + TSource source, const NYPath::TYPath& path, std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy) { - if (!parameterValue) { - parameterValue = New<T>(); + if (!parameter) { + parameter = New<T>(); } if (recursiveUnrecognizedStrategy) { - parameterValue->SetUnrecognizedStrategy(*recursiveUnrecognizedStrategy); + parameter->SetUnrecognizedStrategy(*recursiveUnrecognizedStrategy); } - parameterValue->Load(cursor, /*postprocess*/ false, /*setDefaults*/ false, path); + parameter->Load(std::move(source), /*postprocess*/ false, /*setDefaults*/ false, path); +} + +// YsonStructLite +template <std::derived_from<TYsonStructLite> T, CYsonStructSource TSource> +void LoadFromSource( + T& parameter, + TSource source, + const NYPath::TYPath& path, + std::optional<EUnrecognizedStrategy> /*ignored*/) +{ + try { + parameter.Load(std::move(source), /*postprocess*/ false, /*setDefaults*/ false, path); + } catch (const std::exception& ex) { + THROW_ERROR_EXCEPTION("Error reading parameter %v", path) + << ex; + } +} + +// ExternalizedYsonStruct +template <CExternallySerializable T, CYsonStructSource TSource> +void LoadFromSource( + T& parameter, + TSource source, + const NYPath::TYPath& path, + std::optional<EUnrecognizedStrategy> /*ignored*/) +{ + try { + Deserialize(parameter, std::move(source), /*postprocess*/ false, /*setDefaults*/ false); + } catch (const std::exception& ex) { + THROW_ERROR_EXCEPTION("Error reading parameter %v", path) + << ex; + } } // std::optional -template <class T> -void LoadFromCursor( +template <class T, CYsonStructSource TSource> +void LoadFromSource( std::optional<T>& parameter, - NYson::TYsonPullParserCursor* cursor, + TSource source, const NYPath::TYPath& path, std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy) { + using TTraits = TYsonSourceTraits<TSource>; + try { - if ((*cursor)->GetType() == NYson::EYsonItemType::EntityValue) { + if (TTraits::IsEmpty(source)) { parameter = std::nullopt; - cursor->Next(); - } else { - if (parameter.has_value()) { - LoadFromCursor(*parameter, cursor, path, recursiveUnrecognizedStrategy); - } else { - T value; - LoadFromCursor(value, cursor, path, recursiveUnrecognizedStrategy); - parameter = std::move(value); - } + TTraits::Advance(source); + return; + } + + if (parameter.has_value()) { + LoadFromSource(*parameter, std::move(source), path, recursiveUnrecognizedStrategy); + return; } + + T value; + LoadFromSource(value, std::move(source), path, recursiveUnrecognizedStrategy); + parameter = std::move(value); + } catch (const std::exception& ex) { THROW_ERROR_EXCEPTION("Error loading parameter %v", path) << ex; @@ -305,20 +294,23 @@ void LoadFromCursor( } // std::vector -template <class... T> -void LoadFromCursor( - std::vector<T...>& parameter, - NYson::TYsonPullParserCursor* cursor, +template <CStdVector TVector, CYsonStructSource TSource> +void LoadFromSource( + TVector& parameter, + TSource source, const NYPath::TYPath& path, std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy) { + using TTraits = TYsonSourceTraits<TSource>; + try { parameter.clear(); int index = 0; - cursor->ParseList([&] (NYson::TYsonPullParserCursor* cursor) { - LoadFromCursor( - parameter.emplace_back(), - cursor, + + TTraits::FillVector(source, parameter, [&] (auto& vector, auto elementSource) { + LoadFromSource( + vector.emplace_back(), + elementSource, path + "/" + NYPath::ToYPathLiteral(index), recursiveUnrecognizedStrategy); ++index; @@ -329,24 +321,28 @@ void LoadFromCursor( } } -// For any map. -template <template <typename...> class Map, class... T, class M> -void LoadFromCursor( - Map<T...>& parameter, - NYson::TYsonPullParserCursor* cursor, +// any map. +template <CAnyMap TMap, CYsonStructSource TSource> +void LoadFromSource( + TMap& parameter, + TSource source, const NYPath::TYPath& path, std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy) { + using TTraits = TYsonSourceTraits<TSource>; + // TODO(arkady-e1ppa): Remove "typename" when clang-14 is abolished. + using TKey = typename TMap::key_type; + using TValue = typename TMap::mapped_type; + try { - cursor->ParseMap([&] (NYson::TYsonPullParserCursor* cursor) { - auto key = ExtractTo<TString>(cursor); - M value; - LoadFromCursor( + TTraits::FillMap(source, parameter, [&] (TMap& map, const TString& key, auto childSource) { + TValue value; + LoadFromSource( value, - cursor, + childSource, path + "/" + NYPath::ToYPathLiteral(key), recursiveUnrecognizedStrategy); - parameter[DeserializeMapKey<typename Map<T...>::key_type>(key)] = std::move(value); + map[DeserializeMapKey<TKey>(key)] = std::move(value); }); } catch (const std::exception& ex) { THROW_ERROR_EXCEPTION("Error loading parameter %v", path) @@ -440,9 +436,9 @@ inline void PostprocessRecursive( } // std::vector -template <class T> +template <CStdVector TVector> inline void PostprocessRecursive( - std::vector<T>& parameter, + TVector& parameter, const NYPath::TYPath& path) { for (size_t i = 0; i < parameter.size(); ++i) { @@ -453,9 +449,9 @@ inline void PostprocessRecursive( } // any map -template <template <typename...> class Map, class... T, class M = typename Map<T...>::mapped_type> +template <CAnyMap TMap> inline void PostprocessRecursive( - Map<T...>& parameter, + TMap& parameter, const NYPath::TYPath& path) { for (auto& [key, value] : parameter) { @@ -503,15 +499,15 @@ inline void ResetOnLoad(std::optional<T>& parameter) } // std::vector -template <class T> -inline void ResetOnLoad(std::vector<T>& parameter) +template <CStdVector TVector> +inline void ResetOnLoad(TVector& parameter) { parameter.clear(); } // any map -template <template <typename...> class Map, class... T, class M = typename Map<T...>::mapped_type> -inline void ResetOnLoad(Map<T...>& parameter) +template <CAnyMap TMap> +inline void ResetOnLoad(TMap& parameter) { parameter.clear(); } @@ -564,7 +560,7 @@ void TYsonStructParameter<TValue>::Load( if (ResetOnLoad_) { NPrivate::ResetOnLoad(FieldAccessor_->GetValue(self)); } - NPrivate::LoadFromNode( + NPrivate::LoadFromSource( FieldAccessor_->GetValue(self), std::move(node), options.Path, @@ -585,7 +581,7 @@ void TYsonStructParameter<TValue>::Load( if (ResetOnLoad_) { NPrivate::ResetOnLoad(FieldAccessor_->GetValue(self)); } - NPrivate::LoadFromCursor( + NPrivate::LoadFromSource( FieldAccessor_->GetValue(self), cursor, options.Path, @@ -607,7 +603,7 @@ void TYsonStructParameter<TValue>::SafeLoad( TValue oldValue = FieldAccessor_->GetValue(self); try { FieldAccessor_->GetValue(self) = TValue(); - NPrivate::LoadFromNode( + NPrivate::LoadFromSource( FieldAccessor_->GetValue(self), node, options.Path, diff --git a/yt/yt/core/ytree/yson_struct_detail.h b/yt/yt/core/ytree/yson_struct_detail.h index 17da9bf149..91700f89e7 100644 --- a/yt/yt/core/ytree/yson_struct_detail.h +++ b/yt/yt/core/ytree/yson_struct_detail.h @@ -1,6 +1,6 @@ #pragma once -#include "yson_struct_enum.h" +#include "yson_struct_public.h" #include <yt/yt/core/yson/public.h> #include <yt/yt/core/ypath/public.h> @@ -12,6 +12,38 @@ namespace NYT::NYTree { //////////////////////////////////////////////////////////////////////////////// +namespace NPrivate { + +// Least common denominator between INodePtr +// and TYsonPullParserCursor. +// Maybe something else in the future. +template <class T> +struct TYsonSourceTraits +{ + static constexpr bool IsValid = false; + + static INodePtr AsNode(T& source) + requires false; + + static bool IsEmpty(T& source) + requires false; + + static void Advance(T& source) + requires false; + + template <CStdVector TVector, class TFiller> + static void FillVector(T& source, TVector& vector, TFiller filler) + requires false; + + template <CAnyMap TMap, class TFiller> + static void FillMap(T& source, TMap& map, TFiller filler) + requires false; +}; + +} // namespace NPrivate + +//////////////////////////////////////////////////////////////////////////////// + template <class TStruct, class TValue> using TYsonStructField = TValue(TStruct::*); diff --git a/yt/yt/core/ytree/yson_struct_enum.h b/yt/yt/core/ytree/yson_struct_enum.h deleted file mode 100644 index a35fba6d0d..0000000000 --- a/yt/yt/core/ytree/yson_struct_enum.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include <library/cpp/yt/memory/serialize.h> - -#include <library/cpp/yt/misc/enum.h> - -namespace NYT::NYTree { - -/////////////////////////////////////////////////////////////////////////////// - -DEFINE_ENUM(EUnrecognizedStrategy, - (Drop) - (Keep) - (KeepRecursive) - (Throw) - (ThrowRecursive) -); - -//////////////////////////////////////////////////////////////////////////////// - -} // namespace NYT::NYTree diff --git a/yt/yt/core/ytree/yson_struct_public.h b/yt/yt/core/ytree/yson_struct_public.h new file mode 100644 index 0000000000..495a47b46f --- /dev/null +++ b/yt/yt/core/ytree/yson_struct_public.h @@ -0,0 +1,48 @@ +#pragma once + +#include <library/cpp/yt/memory/serialize.h> + +#include <library/cpp/yt/misc/enum.h> + +namespace NYT::NYTree { + +/////////////////////////////////////////////////////////////////////////////// + +DEFINE_ENUM(EUnrecognizedStrategy, + (Drop) + (Keep) + (KeepRecursive) + (Throw) + (ThrowRecursive) +); + +//////////////////////////////////////////////////////////////////////////////// + +template <class T> +concept CExternalizedYsonStructTraits = requires { + typename T::TExternalSerializer; +}; + +template <class T> +concept CExternallySerializable = requires (T t) { + { GetExternalizedYsonStructTraits(t) } -> CExternalizedYsonStructTraits; +}; + +template <CExternallySerializable T> +using TGetExternalizedYsonStructTraits = decltype(GetExternalizedYsonStructTraits(std::declval<T>())); + +//////////////////////////////////////////////////////////////////////////////// + +namespace NPrivate { + +template <class T> +struct TYsonSourceTraits; + +} // namespace NPrivate + +template <class T> +concept CYsonStructSource = NPrivate::TYsonSourceTraits<T>::IsValid; + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT::NYTree |