diff --git a/library/include/larra/client/client.hpp b/library/include/larra/client/client.hpp index eb14506..ac91a07 100644 --- a/library/include/larra/client/client.hpp +++ b/library/include/larra/client/client.hpp @@ -64,7 +64,10 @@ struct Client { this->Close([] {}); } } - + template + auto Send(const T& object) -> boost::asio::awaitable { + co_await this->connection.Send(object); + } [[nodiscard]] constexpr auto Jid() const -> const BareJid& { return this->jid; } diff --git a/library/include/larra/presence.hpp b/library/include/larra/presence.hpp new file mode 100644 index 0000000..ae8b705 --- /dev/null +++ b/library/include/larra/presence.hpp @@ -0,0 +1,121 @@ +#pragma once +#include + +#include +#include +#include + +namespace larra::xmpp::presence { + +namespace c2s { + +struct Unavailable { + static constexpr auto kDefaultName = "presence"; + friend constexpr auto operator<<(xmlpp::Element* element, const Unavailable&) { + element->set_attribute("type", "unavailable"); + } + [[nodiscard]] static constexpr auto TryParse(xmlpp::Element* element) -> std::optional { + if(auto type = element->get_attribute("type")) { + if(type->get_value() == "unavailable") { + return Unavailable{}; + }; + } + return std::nullopt; + } + [[nodiscard]] static constexpr auto Parse(xmlpp::Element* element) -> Unavailable { + return Unavailable::TryParse(element).value(); + } +}; + +struct Available { + static constexpr auto kDefaultName = "presence"; + friend constexpr auto operator<<(xmlpp::Element*, const Available&) { + } + [[nodiscard]] static constexpr auto TryParse(xmlpp::Element* element) -> std::optional { + return Unavailable::TryParse(element).has_value() ? std::nullopt : std::optional{Available{}}; + } + [[nodiscard]] static constexpr auto Parse(xmlpp::Element* element) -> Available { + return Available::TryParse(element).value(); + } +}; + +} // namespace c2s + +using ClientToServer = std::variant; + +struct Initial { + static constexpr auto kDefaultName = "presence"; + FullJid from; + BareJid to; + template + [[nodiscard]] constexpr auto From(this Self&& self, BareJid value) -> Initial { + return utils::FieldSetHelper::With<"from", Initial>(std::forward(self), std::move(value)); + } + template + [[nodiscard]] constexpr auto To(this Self&& self, BareJid value) -> Initial { + return utils::FieldSetHelper::With<"to", Initial>(std::forward(self), std::move(value)); + } + friend constexpr auto operator<<(xmlpp::Element* element, const Initial& presence) { + element->set_attribute("from", ToString(presence.from)); + element->set_attribute("to", ToString(presence.to)); + } + [[nodiscard]] static constexpr auto Parse(xmlpp::Element* element) -> Initial { + auto from = element->get_attribute("from"); + if(!from) { + throw std::runtime_error("Not found attribute from for Parse presence::Initial"); + } + auto to = element->get_attribute("to"); + if(!to) { + throw std::runtime_error("Not found attribute to for Parse presence::Initial"); + } + return {.from = FullJid::Parse(from->get_value()), .to = BareJid::Parse(to->get_value())}; + } +}; + +struct Probe { + static constexpr auto kDefaultName = "presence"; + BareJid from; + BareJid to; + std::string id; + template + [[nodiscard]] constexpr auto From(this Self&& self, BareJid value) -> Probe { + return utils::FieldSetHelper::With<"from", Probe>(std::forward(self), std::move(value)); + } + template + [[nodiscard]] constexpr auto To(this Self&& self, BareJid value) -> Probe { + return utils::FieldSetHelper::With<"to", Probe>(std::forward(self), std::move(value)); + } + template + [[nodiscard]] constexpr auto Id(this Self&& self, std::string value) -> Probe { + return utils::FieldSetHelper::With<"id", Probe>(std::forward(self), std::move(value)); + } + friend constexpr auto operator<<(xmlpp::Element* element, const Probe& presence) { + element->set_attribute("from", ToString(presence.from)); + element->set_attribute("to", ToString(presence.to)); + } + [[nodiscard]] static constexpr auto Parse(xmlpp::Element* element) -> Probe { + auto type = element->get_attribute("type"); + if(!type) { + throw std::runtime_error("Not found attribute type for Parse presence::Probe"); + } + if(type->get_value() != "probe") { + throw std::runtime_error("Invalid attribute type value for Parse presence::Probe"); + } + auto from = element->get_attribute("from"); + if(!from) { + throw std::runtime_error("Not found attribute from for Parse presence::Probe"); + } + auto to = element->get_attribute("to"); + if(!to) { + throw std::runtime_error("Not found attribute to for Parse presence::Probe"); + } + auto id = element->get_attribute("id"); + if(!id) { + throw std::runtime_error("Not found attribute id for Parse presence::Probe"); + } + + return {.from = BareJid::Parse(from->get_value()), .to = BareJid::Parse(to->get_value()), .id = id->get_value()}; + } +}; + +} // namespace larra::xmpp::presence