From 4529cb782d6962d3a1e38d761cfa24a3c1bac8dd Mon Sep 17 00:00:00 2001 From: galtsev <galtsev@yandex-team.com> Date: Wed, 19 Apr 2023 23:02:45 +0300 Subject: YT-18920: Parse unknown enum values --- library/cpp/yt/string/enum-inl.h | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'library/cpp/yt/string/enum-inl.h') diff --git a/library/cpp/yt/string/enum-inl.h b/library/cpp/yt/string/enum-inl.h index 7e6785efb4..2fa138f52f 100644 --- a/library/cpp/yt/string/enum-inl.h +++ b/library/cpp/yt/string/enum-inl.h @@ -4,6 +4,8 @@ #include "enum.h" #endif +#include <library/cpp/yt/exception/exception.h> + #include <util/string/printf.h> namespace NYT { @@ -28,7 +30,29 @@ template <class T> std::optional<T> TryParseEnum(TStringBuf value) { auto tryFromString = [] (TStringBuf value) -> std::optional<T> { - return TEnumTraits<T>::FindValueByLiteral(DecodeEnumValue(value)); + try { + return TEnumTraits<T>::FindValueByLiteral(DecodeEnumValue(value)); + } catch (const TSimpleException&) { + TStringBuf typeName; + auto isTypeNameCorrect = value.NextTok('(', typeName) && typeName == TEnumTraits<T>::GetTypeName(); + if (!isTypeNameCorrect) { + throw; + } + + TStringBuf enumValue; + std::underlying_type_t<T> underlyingValue; + auto isEnumValueCorrect = value.NextTok(')', enumValue) && TryFromString(enumValue, underlyingValue); + if (!isEnumValueCorrect) { + throw; + } + + auto isParsingComplete = value.empty(); + if (!isParsingComplete) { + throw; + } + + return static_cast<T>(underlyingValue); + } }; if constexpr (TEnumTraits<T>::IsBitEnum) { -- cgit v1.2.3