All checks were successful
PR Check / on-push-commit-check (push) Successful in 12m18s
156 lines
4.7 KiB
C++
156 lines
4.7 KiB
C++
#pragma once
|
|
#include <larra/serialization/auto.hpp>
|
|
#include <larra/xml_language.hpp>
|
|
#include <string>
|
|
|
|
namespace larra::xmpp {
|
|
|
|
namespace message {
|
|
struct Body {
|
|
std::string content;
|
|
std::optional<XmlLanguage> language;
|
|
static constexpr auto kDefaultName = "body";
|
|
constexpr auto operator==(const Body& other) const -> bool = default;
|
|
friend constexpr auto operator<<(xmlpp::Element* node, const Body& message) -> void {
|
|
node->add_child_text(message.content);
|
|
}
|
|
static constexpr auto Parse(xmlpp::Element* node) -> Body {
|
|
auto ptr = node->get_first_child_text();
|
|
if(!ptr) {
|
|
throw std::runtime_error("Message::Body: [ Text node not found ]");
|
|
}
|
|
auto lang = node->get_attribute("lang", "xml");
|
|
return {
|
|
.content = ptr->get_content(), //
|
|
.language = lang ? std::optional{XmlLanguage::Parse(lang->get_value())} : std::nullopt //
|
|
};
|
|
}
|
|
};
|
|
|
|
namespace type {
|
|
|
|
struct Chat {
|
|
static constexpr auto TryParse(std::string_view value) -> std::optional<Chat> {
|
|
return value == "chat" ? std::optional{Chat{}} : std::nullopt;
|
|
}
|
|
friend constexpr auto ToString(const Chat&) -> std::string {
|
|
return "chat";
|
|
}
|
|
constexpr auto operator==(const Chat&) const -> bool {
|
|
return true;
|
|
};
|
|
};
|
|
|
|
static constexpr auto kChat = Chat{};
|
|
|
|
struct Error {
|
|
static constexpr auto TryParse(std::string_view value) -> std::optional<Error> {
|
|
return value == "error" ? std::optional{Error{}} : std::nullopt;
|
|
}
|
|
friend constexpr auto ToString(const Error&) -> std::string {
|
|
return "error";
|
|
}
|
|
constexpr auto operator==(const Error&) const -> bool {
|
|
return true;
|
|
};
|
|
};
|
|
|
|
static constexpr auto kError = Error{};
|
|
|
|
struct GroupChat {
|
|
static constexpr auto TryParse(std::string_view value) -> std::optional<GroupChat> {
|
|
return value == "groupchat" ? std::optional{GroupChat{}} : std::nullopt;
|
|
}
|
|
friend constexpr auto ToString(const GroupChat&) -> std::string {
|
|
return "groupchat";
|
|
}
|
|
constexpr auto operator==(const GroupChat&) const -> bool {
|
|
return true;
|
|
};
|
|
};
|
|
|
|
static constexpr auto kGroupChat = GroupChat{};
|
|
|
|
struct Headline {
|
|
static constexpr auto TryParse(std::string_view value) -> std::optional<Headline> {
|
|
return value == "headline" ? std::optional{Headline{}} : std::nullopt;
|
|
}
|
|
friend constexpr auto ToString(const Headline&) -> std::string {
|
|
return "headline";
|
|
}
|
|
constexpr auto operator==(const Headline&) const -> bool {
|
|
return true;
|
|
};
|
|
};
|
|
|
|
static constexpr auto kHeadline = Headline{};
|
|
|
|
struct Normal {
|
|
static constexpr auto Parse(std::string_view value) -> Normal {
|
|
return value == "normal" ? Normal{}
|
|
: throw std::runtime_error(
|
|
std::format(R"(message::type::Normal Parsing error: [ expected "normal" but "{}" found ])", value));
|
|
}
|
|
friend constexpr auto ToString(const Normal&) -> std::string {
|
|
return "normal";
|
|
}
|
|
constexpr auto operator==(const Normal&) const -> bool {
|
|
return true;
|
|
};
|
|
};
|
|
|
|
static constexpr auto kNormal = Normal{};
|
|
|
|
} // namespace type
|
|
|
|
using TypeVariant = std::variant<type::Chat, type::GroupChat, type::Headline, type::Error, type::Normal>;
|
|
|
|
struct Type : TypeVariant {
|
|
using TypeVariant::variant;
|
|
constexpr Type(TypeVariant variant) : TypeVariant(std::move(variant)) {
|
|
}
|
|
|
|
static constexpr auto GetDefault() -> Type {
|
|
return type::kNormal;
|
|
}
|
|
|
|
friend constexpr auto ToString(const Type& value) -> std::string {
|
|
return std::visit(
|
|
[](const auto& value) {
|
|
return ToString(value);
|
|
},
|
|
value);
|
|
}
|
|
};
|
|
|
|
} // namespace message
|
|
|
|
template <typename From, typename To>
|
|
struct Message {
|
|
static constexpr auto kDefaultName = "message";
|
|
static auto Parse(xmlpp::Element* element) -> Message {
|
|
return serialization::Parse<Message>(element);
|
|
}
|
|
friend auto operator<<(xmlpp::Element* element, const Message& message) -> void {
|
|
serialization::Serialize(element, message);
|
|
}
|
|
constexpr auto operator==(const Message& other) const -> bool = default;
|
|
From from;
|
|
To to;
|
|
message::Type type;
|
|
std::optional<std::string> id;
|
|
XmlLanguage language;
|
|
std::vector<message::Body> body;
|
|
};
|
|
|
|
template <typename From, typename To>
|
|
struct serialization::SerializationConfigT<Message<From, To>> {
|
|
static constexpr auto kValue = serialization::SerializationConfig<Message<From, To>>{} //
|
|
.template With<"type">(serialization::AttributeConfig{})
|
|
.template With<"body">(serialization::Config<std::vector<message::Body>>{});
|
|
};
|
|
|
|
template <typename Info>
|
|
struct serialization::AttributeSerializer<message::Type, Info> : serialization::AttributeSerializer<message::TypeVariant, Info> {};
|
|
|
|
} // namespace larra::xmpp
|