.
This commit is contained in:
parent
ed4276338d
commit
ae1f5c2d24
2 changed files with 45 additions and 7 deletions
|
@ -68,10 +68,23 @@ struct Config<std::string> {
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace impl {
|
namespace impl {
|
||||||
|
template <typename T>
|
||||||
|
concept HasParse = requires(xmlpp::Element* e) {
|
||||||
|
{ T::Parse(e) } -> std::same_as<T>;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T, typename V>
|
template <typename T, typename V>
|
||||||
struct Config : V {
|
struct Config : V {
|
||||||
using V::V;
|
using V::V;
|
||||||
|
constexpr Config()
|
||||||
|
requires HasParse<T>
|
||||||
|
: V(::larra::xmpp::serialization::Config<T>{}) {
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr Config()
|
||||||
|
requires(!HasParse<T>)
|
||||||
|
: V(AttributeConfig{}) {
|
||||||
|
}
|
||||||
constexpr auto Base() const -> const V& {
|
constexpr auto Base() const -> const V& {
|
||||||
return static_cast<const V&>(*this);
|
return static_cast<const V&>(*this);
|
||||||
}
|
}
|
||||||
|
@ -116,14 +129,18 @@ consteval auto FindElement(std::string_view field, utempl::TypeList<T> = {}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <auto& Config, typename Info>
|
template <auto& Config, typename Info>
|
||||||
auto ParseField(xmlpp::Element* main) {
|
auto ParseField(xmlpp::Element* main) -> std::decay_t<decltype(Config)>::type {
|
||||||
using Type = std::decay_t<decltype(Config)>::type;
|
using Type = std::decay_t<decltype(Config)>::type;
|
||||||
if constexpr(std::holds_alternative<AttributeConfig>(Config.Base())) {
|
if constexpr(std::holds_alternative<AttributeConfig>(Config.Base())) {
|
||||||
xmlpp::Attribute* node = main->get_attribute(Info::kName);
|
xmlpp::Attribute* node = main->get_attribute(Info::kName);
|
||||||
if(!node) {
|
if(!node) {
|
||||||
throw AttributeSerializationError(std::format("Attribute [{}] serialization error", Info::kName));
|
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 {
|
} else {
|
||||||
return ElementSerializer<Type, Config, Info>::Parse(main);
|
return ElementSerializer<Type, Config, Info>::Parse(main);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <larra/jid.hpp>
|
||||||
#include <larra/serialization.hpp>
|
#include <larra/serialization.hpp>
|
||||||
#include <larra/serialization/auto.hpp>
|
#include <larra/serialization/auto.hpp>
|
||||||
#include <larra/serialization/error.hpp>
|
#include <larra/serialization/error.hpp>
|
||||||
|
@ -55,6 +56,12 @@ struct SomeStruct4 {
|
||||||
[[nodiscard]] static auto Parse(xmlpp::Element* element) -> 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 tests::serialization
|
||||||
|
|
||||||
namespace serialization {
|
namespace serialization {
|
||||||
|
@ -63,12 +70,13 @@ template <>
|
||||||
constexpr auto kSerializationConfig<tests::serialization::SomeStruct> = SerializationConfig<tests::serialization::SomeStruct>{};
|
constexpr auto kSerializationConfig<tests::serialization::SomeStruct> = SerializationConfig<tests::serialization::SomeStruct>{};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
constexpr auto kSerializationConfig<tests::serialization::SomeStruct2> =
|
constexpr auto kSerializationConfig<tests::serialization::SomeStruct2> = SerializationConfig<tests::serialization::SomeStruct2>{};
|
||||||
SerializationConfig<tests::serialization::SomeStruct2>{}.With<"value">(serialization::Config<tests::serialization::SomeStruct>{});
|
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
constexpr auto kSerializationConfig<tests::serialization::SomeStruct4> =
|
constexpr auto kSerializationConfig<tests::serialization::SomeStruct4> = SerializationConfig<tests::serialization::SomeStruct4>{};
|
||||||
SerializationConfig<tests::serialization::SomeStruct4>{}.With<"value">(serialization::Config<tests::serialization::SomeStruct3>{});
|
|
||||||
|
template <>
|
||||||
|
constexpr auto kSerializationConfig<tests::serialization::SomeStruct5> = SerializationConfig<tests::serialization::SomeStruct5>{};
|
||||||
|
|
||||||
} // namespace serialization
|
} // namespace serialization
|
||||||
|
|
||||||
|
@ -88,7 +96,11 @@ auto tests::serialization::SomeStruct4::Parse(xmlpp::Element* element) -> SomeSt
|
||||||
return ::larra::xmpp::serialization::Parse<tests::serialization::SomeStruct4>(element);
|
return ::larra::xmpp::serialization::Parse<tests::serialization::SomeStruct4>(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Parse, Auto) {
|
auto tests::serialization::SomeStruct5::Parse(xmlpp::Element* element) -> SomeStruct5 {
|
||||||
|
return ::larra::xmpp::serialization::Parse<tests::serialization::SomeStruct5>(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(AutoParse, Basic) {
|
||||||
xmlpp::Document doc;
|
xmlpp::Document doc;
|
||||||
auto node = doc.create_root_node("some2");
|
auto node = doc.create_root_node("some2");
|
||||||
node = node->add_child_element("some");
|
node = node->add_child_element("some");
|
||||||
|
@ -104,4 +116,13 @@ TEST(Parse, Auto) {
|
||||||
EXPECT_EQ(c.value.value, 42);
|
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<tests::serialization::SomeStruct5>::Parse(node);
|
||||||
|
EXPECT_EQ(a.value.server, "server.i2p"sv);
|
||||||
|
EXPECT_EQ(a.value.username, "user"sv);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace larra::xmpp
|
} // namespace larra::xmpp
|
||||||
|
|
Loading…
Reference in a new issue