|
@@ -35,223 +35,175 @@ concept SupportsDontSerializeDefault =
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
-// Primitive type
|
|
|
|
template <class T>
|
|
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 {
|
|
} 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,
|
|
const NYPath::TYPath& path,
|
|
std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy);
|
|
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,
|
|
const NYPath::TYPath& path,
|
|
std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy);
|
|
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,
|
|
const NYPath::TYPath& path,
|
|
std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy);
|
|
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,
|
|
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
|
|
// INodePtr
|
|
-template <>
|
|
|
|
-inline void LoadFromCursor(
|
|
|
|
- NYTree::INodePtr& parameter,
|
|
|
|
- NYson::TYsonPullParserCursor* cursor,
|
|
|
|
|
|
+template <CYsonStructSource TSource>
|
|
|
|
+void LoadFromSource(
|
|
|
|
+ INodePtr& parameter,
|
|
|
|
+ TSource source,
|
|
const NYPath::TYPath& path,
|
|
const NYPath::TYPath& path,
|
|
- std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy)
|
|
|
|
|
|
+ std::optional<EUnrecognizedStrategy> /*ignored*/)
|
|
{
|
|
{
|
|
|
|
+ using TTraits = TYsonSourceTraits<TSource>;
|
|
|
|
+
|
|
try {
|
|
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) {
|
|
} catch (const std::exception& ex) {
|
|
THROW_ERROR_EXCEPTION("Error loading parameter %v", path)
|
|
THROW_ERROR_EXCEPTION("Error loading parameter %v", path)
|
|
<< ex;
|
|
<< ex;
|
|
@@ -259,45 +211,82 @@ inline void LoadFromCursor(
|
|
}
|
|
}
|
|
|
|
|
|
// TYsonStruct
|
|
// 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,
|
|
const NYPath::TYPath& path,
|
|
std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy)
|
|
std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy)
|
|
{
|
|
{
|
|
- if (!parameterValue) {
|
|
|
|
- parameterValue = New<T>();
|
|
|
|
|
|
+ if (!parameter) {
|
|
|
|
+ parameter = New<T>();
|
|
}
|
|
}
|
|
|
|
|
|
if (recursiveUnrecognizedStrategy) {
|
|
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
|
|
// std::optional
|
|
-template <class T>
|
|
|
|
-void LoadFromCursor(
|
|
|
|
|
|
+template <class T, CYsonStructSource TSource>
|
|
|
|
+void LoadFromSource(
|
|
std::optional<T>& parameter,
|
|
std::optional<T>& parameter,
|
|
- NYson::TYsonPullParserCursor* cursor,
|
|
|
|
|
|
+ TSource source,
|
|
const NYPath::TYPath& path,
|
|
const NYPath::TYPath& path,
|
|
std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy)
|
|
std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy)
|
|
{
|
|
{
|
|
|
|
+ using TTraits = TYsonSourceTraits<TSource>;
|
|
|
|
+
|
|
try {
|
|
try {
|
|
- if ((*cursor)->GetType() == NYson::EYsonItemType::EntityValue) {
|
|
|
|
|
|
+ if (TTraits::IsEmpty(source)) {
|
|
parameter = std::nullopt;
|
|
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) {
|
|
} catch (const std::exception& ex) {
|
|
THROW_ERROR_EXCEPTION("Error loading parameter %v", path)
|
|
THROW_ERROR_EXCEPTION("Error loading parameter %v", path)
|
|
<< ex;
|
|
<< ex;
|
|
@@ -305,20 +294,23 @@ void LoadFromCursor(
|
|
}
|
|
}
|
|
|
|
|
|
// std::vector
|
|
// 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,
|
|
const NYPath::TYPath& path,
|
|
std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy)
|
|
std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy)
|
|
{
|
|
{
|
|
|
|
+ using TTraits = TYsonSourceTraits<TSource>;
|
|
|
|
+
|
|
try {
|
|
try {
|
|
parameter.clear();
|
|
parameter.clear();
|
|
int index = 0;
|
|
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),
|
|
path + "/" + NYPath::ToYPathLiteral(index),
|
|
recursiveUnrecognizedStrategy);
|
|
recursiveUnrecognizedStrategy);
|
|
++index;
|
|
++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,
|
|
const NYPath::TYPath& path,
|
|
std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy)
|
|
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 {
|
|
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,
|
|
value,
|
|
- cursor,
|
|
|
|
|
|
+ childSource,
|
|
path + "/" + NYPath::ToYPathLiteral(key),
|
|
path + "/" + NYPath::ToYPathLiteral(key),
|
|
recursiveUnrecognizedStrategy);
|
|
recursiveUnrecognizedStrategy);
|
|
- parameter[DeserializeMapKey<typename Map<T...>::key_type>(key)] = std::move(value);
|
|
|
|
|
|
+ map[DeserializeMapKey<TKey>(key)] = std::move(value);
|
|
});
|
|
});
|
|
} catch (const std::exception& ex) {
|
|
} catch (const std::exception& ex) {
|
|
THROW_ERROR_EXCEPTION("Error loading parameter %v", path)
|
|
THROW_ERROR_EXCEPTION("Error loading parameter %v", path)
|
|
@@ -440,9 +436,9 @@ inline void PostprocessRecursive(
|
|
}
|
|
}
|
|
|
|
|
|
// std::vector
|
|
// std::vector
|
|
-template <class T>
|
|
|
|
|
|
+template <CStdVector TVector>
|
|
inline void PostprocessRecursive(
|
|
inline void PostprocessRecursive(
|
|
- std::vector<T>& parameter,
|
|
|
|
|
|
+ TVector& parameter,
|
|
const NYPath::TYPath& path)
|
|
const NYPath::TYPath& path)
|
|
{
|
|
{
|
|
for (size_t i = 0; i < parameter.size(); ++i) {
|
|
for (size_t i = 0; i < parameter.size(); ++i) {
|
|
@@ -453,9 +449,9 @@ inline void PostprocessRecursive(
|
|
}
|
|
}
|
|
|
|
|
|
// any map
|
|
// any map
|
|
-template <template <typename...> class Map, class... T, class M = typename Map<T...>::mapped_type>
|
|
|
|
|
|
+template <CAnyMap TMap>
|
|
inline void PostprocessRecursive(
|
|
inline void PostprocessRecursive(
|
|
- Map<T...>& parameter,
|
|
|
|
|
|
+ TMap& parameter,
|
|
const NYPath::TYPath& path)
|
|
const NYPath::TYPath& path)
|
|
{
|
|
{
|
|
for (auto& [key, value] : parameter) {
|
|
for (auto& [key, value] : parameter) {
|
|
@@ -503,15 +499,15 @@ inline void ResetOnLoad(std::optional<T>& parameter)
|
|
}
|
|
}
|
|
|
|
|
|
// std::vector
|
|
// std::vector
|
|
-template <class T>
|
|
|
|
-inline void ResetOnLoad(std::vector<T>& parameter)
|
|
|
|
|
|
+template <CStdVector TVector>
|
|
|
|
+inline void ResetOnLoad(TVector& parameter)
|
|
{
|
|
{
|
|
parameter.clear();
|
|
parameter.clear();
|
|
}
|
|
}
|
|
|
|
|
|
// any map
|
|
// 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();
|
|
parameter.clear();
|
|
}
|
|
}
|
|
@@ -564,7 +560,7 @@ void TYsonStructParameter<TValue>::Load(
|
|
if (ResetOnLoad_) {
|
|
if (ResetOnLoad_) {
|
|
NPrivate::ResetOnLoad(FieldAccessor_->GetValue(self));
|
|
NPrivate::ResetOnLoad(FieldAccessor_->GetValue(self));
|
|
}
|
|
}
|
|
- NPrivate::LoadFromNode(
|
|
|
|
|
|
+ NPrivate::LoadFromSource(
|
|
FieldAccessor_->GetValue(self),
|
|
FieldAccessor_->GetValue(self),
|
|
std::move(node),
|
|
std::move(node),
|
|
options.Path,
|
|
options.Path,
|
|
@@ -585,7 +581,7 @@ void TYsonStructParameter<TValue>::Load(
|
|
if (ResetOnLoad_) {
|
|
if (ResetOnLoad_) {
|
|
NPrivate::ResetOnLoad(FieldAccessor_->GetValue(self));
|
|
NPrivate::ResetOnLoad(FieldAccessor_->GetValue(self));
|
|
}
|
|
}
|
|
- NPrivate::LoadFromCursor(
|
|
|
|
|
|
+ NPrivate::LoadFromSource(
|
|
FieldAccessor_->GetValue(self),
|
|
FieldAccessor_->GetValue(self),
|
|
cursor,
|
|
cursor,
|
|
options.Path,
|
|
options.Path,
|
|
@@ -607,7 +603,7 @@ void TYsonStructParameter<TValue>::SafeLoad(
|
|
TValue oldValue = FieldAccessor_->GetValue(self);
|
|
TValue oldValue = FieldAccessor_->GetValue(self);
|
|
try {
|
|
try {
|
|
FieldAccessor_->GetValue(self) = TValue();
|
|
FieldAccessor_->GetValue(self) = TValue();
|
|
- NPrivate::LoadFromNode(
|
|
|
|
|
|
+ NPrivate::LoadFromSource(
|
|
FieldAccessor_->GetValue(self),
|
|
FieldAccessor_->GetValue(self),
|
|
node,
|
|
node,
|
|
options.Path,
|
|
options.Path,
|