From ae1f5c2d24dbf9c2f94c4a883f3ec801e0b9c18a Mon Sep 17 00:00:00 2001 From: sha512sum Date: Sat, 19 Oct 2024 18:15:24 +0000 Subject: [PATCH] . --- library/include/larra/serialization/auto.hpp | 21 +++++++++++-- tests/serialization.cpp | 31 ++++++++++++++++---- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/library/include/larra/serialization/auto.hpp b/library/include/larra/serialization/auto.hpp index be4afec..29953fa 100644 --- a/library/include/larra/serialization/auto.hpp +++ b/library/include/larra/serialization/auto.hpp @@ -68,10 +68,23 @@ struct Config { }; namespace impl { +template +concept HasParse = requires(xmlpp::Element* e) { + { T::Parse(e) } -> std::same_as; +}; template struct Config : V { using V::V; + constexpr Config() + requires HasParse + : V(::larra::xmpp::serialization::Config{}) { + } + + constexpr Config() + requires(!HasParse) + : V(AttributeConfig{}) { + } constexpr auto Base() const -> const V& { return static_cast(*this); } @@ -116,14 +129,18 @@ consteval auto FindElement(std::string_view field, utempl::TypeList = {}) { } template -auto ParseField(xmlpp::Element* main) { +auto ParseField(xmlpp::Element* main) -> std::decay_t::type { using Type = std::decay_t::type; if constexpr(std::holds_alternative(Config.Base())) { xmlpp::Attribute* node = main->get_attribute(Info::kName); if(!node) { throw AttributeSerializationError(std::format("Attribute [{}] serialization error", Info::kName)); } - return node->get_value(); + if constexpr(requires(std::string_view view) { Type::Parse(view); }) { + return Type::Parse(node->get_value()); + } else { + return node->get_value(); + } } else { return ElementSerializer::Parse(main); } diff --git a/tests/serialization.cpp b/tests/serialization.cpp index a51b17f..97f31f6 100644 --- a/tests/serialization.cpp +++ b/tests/serialization.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -55,6 +56,12 @@ struct SomeStruct4 { [[nodiscard]] static auto Parse(xmlpp::Element* element) -> SomeStruct4; }; +struct SomeStruct5 { + static constexpr auto kDefaultName = "some5"; + BareJid value; + [[nodiscard]] static auto Parse(xmlpp::Element* element) -> SomeStruct5; +}; + } // namespace tests::serialization namespace serialization { @@ -63,12 +70,13 @@ template <> constexpr auto kSerializationConfig = SerializationConfig{}; template <> -constexpr auto kSerializationConfig = - SerializationConfig{}.With<"value">(serialization::Config{}); +constexpr auto kSerializationConfig = SerializationConfig{}; template <> -constexpr auto kSerializationConfig = - SerializationConfig{}.With<"value">(serialization::Config{}); +constexpr auto kSerializationConfig = SerializationConfig{}; + +template <> +constexpr auto kSerializationConfig = SerializationConfig{}; } // namespace serialization @@ -88,7 +96,11 @@ auto tests::serialization::SomeStruct4::Parse(xmlpp::Element* element) -> SomeSt return ::larra::xmpp::serialization::Parse(element); } -TEST(Parse, Auto) { +auto tests::serialization::SomeStruct5::Parse(xmlpp::Element* element) -> SomeStruct5 { + return ::larra::xmpp::serialization::Parse(element); +} + +TEST(AutoParse, Basic) { xmlpp::Document doc; auto node = doc.create_root_node("some2"); node = node->add_child_element("some"); @@ -104,4 +116,13 @@ TEST(Parse, Auto) { EXPECT_EQ(c.value.value, 42); } +TEST(AutoParse, Attribute) { + xmlpp::Document doc; + auto node = doc.create_root_node("some5"); + node->set_attribute("value", "user@server.i2p"); + auto a = Serialization::Parse(node); + EXPECT_EQ(a.value.server, "server.i2p"sv); + EXPECT_EQ(a.value.username, "user"sv); +} + } // namespace larra::xmpp