diff --git a/chaotic/chaotic/back/cpp/templates/type.cpp.jinja b/chaotic/chaotic/back/cpp/templates/type.cpp.jinja index 908449e363c7..1752f5da2987 100644 --- a/chaotic/chaotic/back/cpp/templates/type.cpp.jinja +++ b/chaotic/chaotic/back/cpp/templates/type.cpp.jinja @@ -210,6 +210,20 @@ {% endif %} {% endmacro %} +{% macro generate_isconvertible_definition(type) %} + {# handle subtypes #} + {%- for schema in type.subtypes() -%} + {{ generate_isconvertible_definition(schema) }} + {% endfor %} + + {% if type.get_py_type() == 'CppStringEnum' %} + bool IsConvertible(std::string_view value, + {{ userver }}::formats::parse::To<{{ shortest_cpp_name(type) }}>) + { + return k{{ type.cpp_global_struct_field_name() }}_Mapping.TryFindBySecond(value).has_value(); + } + {% endif %} +{% endmacro %} {% macro generate_operator_eq_definition(type) %} {% set local_name = shortest_cpp_name(type) %} @@ -312,6 +326,8 @@ {% endif %} {{ generate_tostring_definition(type) }} + + {{ generate_isconvertible_definition(type) }} {% endfor %} {{ common.switch_namespace('') }} diff --git a/chaotic/chaotic/back/cpp/templates/type.hpp.jinja b/chaotic/chaotic/back/cpp/templates/type.hpp.jinja index d419794cb7a3..3365bb240b12 100644 --- a/chaotic/chaotic/back/cpp/templates/type.hpp.jinja +++ b/chaotic/chaotic/back/cpp/templates/type.hpp.jinja @@ -279,6 +279,19 @@ {% endif %} {% endmacro %} +{% macro generate_isconvertible_declaration(type) %} + {# handle subtypes #} + {%- for schema in type.subtypes() -%} + {{ generate_isconvertible_declaration(schema) }} + {% endfor %} + + {% if type.get_py_type() == 'CppStringEnum' %} + bool IsConvertible(std::string_view value, + {{ userver }}::formats::parse::To<{{ shortest_cpp_name(type) }}>); + {% endif %} +{% endmacro %} + + {% macro generate_fmt_formatter_declaration(type) %} {# handle subtypes #} {%- for schema in type.subtypes() -%} @@ -328,6 +341,8 @@ {% endif %} {{ generate_tostring_declaration(type) }} + + {{ generate_isconvertible_declaration(type) }} {% endfor %} {{ common.switch_namespace('') }} diff --git a/chaotic/golden_tests/output/schemas/enum/enum.cpp b/chaotic/golden_tests/output/schemas/enum/enum.cpp index 05844d4c2381..feb3e868bb3a 100644 --- a/chaotic/golden_tests/output/schemas/enum/enum.cpp +++ b/chaotic/golden_tests/output/schemas/enum/enum.cpp @@ -82,6 +82,10 @@ std::string ToString(Enum::Foo value) { throw std::runtime_error(fmt::format("Invalid enum value: {}", static_cast(value))); } +bool IsConvertible(std::string_view value, USERVER_NAMESPACE::formats::parse::To) { + return k__ns__Enum__Foo_Mapping.TryFindBySecond(value).has_value(); +} + } // namespace ns fmt::format_context::iterator fmt::formatter::format(const ns::Enum::Foo& value, diff --git a/chaotic/golden_tests/output/schemas/enum/enum.hpp b/chaotic/golden_tests/output/schemas/enum/enum.hpp index d3a755680297..76a3e889b93a 100644 --- a/chaotic/golden_tests/output/schemas/enum/enum.hpp +++ b/chaotic/golden_tests/output/schemas/enum/enum.hpp @@ -60,6 +60,8 @@ USERVER_NAMESPACE::formats::json::Value Serialize( std::string ToString(Enum::Foo value); +bool IsConvertible(std::string_view value, USERVER_NAMESPACE::formats::parse::To); + } // namespace ns template <> diff --git a/chaotic/integration_tests/tests/render/simple.cpp b/chaotic/integration_tests/tests/render/simple.cpp index 091440e2593c..9de4879f96f3 100644 --- a/chaotic/integration_tests/tests/render/simple.cpp +++ b/chaotic/integration_tests/tests/render/simple.cpp @@ -296,6 +296,11 @@ TEST(Simple, StringEnum) { EXPECT_EQ("bar", ToString(ns::StringEnum::kBar)); EXPECT_EQ("some!thing", ToString(ns::StringEnum::kSomeThing)); + EXPECT_TRUE(IsConvertible("foo", formats::parse::To{})); + EXPECT_TRUE(IsConvertible("bar", formats::parse::To{})); + EXPECT_TRUE(IsConvertible("some!thing", formats::parse::To{})); + EXPECT_FALSE(IsConvertible("invalid", formats::parse::To{})); + EXPECT_EQ(FromString("foo", formats::parse::To{}), ns::StringEnum::kFoo); UEXPECT_THROW_MSG( FromString("zoo", formats::parse::To{}),