#include #include namespace { inline auto ToOptionalString(const pugi::xml_attribute& attribute) -> std::optional { return attribute ? std::optional{std::string{attribute.as_string()}} : std::nullopt; } template inline auto ToOptionalUser(const pugi::xml_attribute& attribute) { if constexpr(IsJid) { return attribute ? std::optional{larra::xmpp::BareJid::Parse(attribute.as_string())} : std::nullopt; } else { return attribute ? std::optional{std::string{attribute.as_string()}} : std::nullopt; } } auto ToString(std::string data) -> std::string { return std::move(data); }; } // namespace namespace larra::xmpp { template auto impl::BasicStream::SerializeStream(pugi::xml_node& node) const -> void { if(this->from) { node.append_attribute("from") = ToString(*this->from).c_str(); } if(this->to) { node.append_attribute("to") = ToString(*this->to).c_str(); } if(this->id) { node.append_attribute("id") = this->id->c_str(); } if(this->version) { node.append_attribute("version") = this->version->c_str(); } if(this->xmlLang) { node.append_attribute("xml:lang") = this->xmlLang->c_str(); } if constexpr(JidFrom || JidTo) { node.append_attribute("xmlns") = "jabber:client"; } else { node.append_attribute("xmlns") = "jabber:server"; } node.append_attribute("xmlns:stream") = "http://etherx.jabber.org/streams"; } template auto ServerStream::SerializeStream(pugi::xml_node& node) const -> void; template auto ServerToUserStream::SerializeStream(pugi::xml_node& node) const -> void; template auto UserStream::SerializeStream(pugi::xml_node& node) const -> void; namespace impl { template inline auto ToStringHelper(const BasicStream& stream) { return std::format("", stream.id ? std::format(" id='{}'", *stream.id) : "", stream.from ? std::format(" from='{}'", *stream.from) : "", stream.to ? std::format(" to='{}'", *stream.to) : "", stream.version ? std::format(" version='{}'", *stream.version) : "", stream.xmlLang ? std::format(" xml:lang='{}'", *stream.xmlLang) : "", JidFrom || JidTo ? " xmlns='jabber:client'" : "xmlns='jabber:server'"); }; auto ToString(const ServerStream& ref) -> std::string { return ToStringHelper(ref); } auto ToString(const UserStream& ref) -> std::string { return ToStringHelper(ref); } auto ToString(const ServerToUserStream& ref) -> std::string { return ToStringHelper(ref); } } // namespace impl template auto impl::BasicStream::Parse(const pugi::xml_node& node) -> impl::BasicStream { return {ToOptionalUser(node.attribute("from")), ToOptionalUser(node.attribute("to")), ToOptionalString(node.attribute("id")), ToOptionalString(node.attribute("version")), ToOptionalString(node.attribute("xml:lang"))}; } template auto UserStream::Parse(const pugi::xml_node& node) -> UserStream; template auto ServerStream::Parse(const pugi::xml_node& node) -> ServerStream; template auto ServerToUserStream::Parse(const pugi::xml_node& node) -> ServerToUserStream; } // namespace larra::xmpp