Add presence types

This commit is contained in:
sha512sum 2024-10-09 15:58:36 +00:00
parent 3e18243f79
commit f72ee713d8
2 changed files with 125 additions and 1 deletions

View file

@ -64,7 +64,10 @@ struct Client {
this->Close([] {});
}
}
template <typename T>
auto Send(const T& object) -> boost::asio::awaitable<void> {
co_await this->connection.Send(object);
}
[[nodiscard]] constexpr auto Jid() const -> const BareJid& {
return this->jid;
}

View file

@ -0,0 +1,121 @@
#pragma once
#include <libxml++/libxml++.h>
#include <larra/jid.hpp>
#include <optional>
#include <variant>
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<Unavailable> {
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<Available> {
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<c2s::Unavailable, c2s::Available>;
struct Initial {
static constexpr auto kDefaultName = "presence";
FullJid from;
BareJid to;
template <typename Self>
[[nodiscard]] constexpr auto From(this Self&& self, BareJid value) -> Initial {
return utils::FieldSetHelper::With<"from", Initial>(std::forward<Self>(self), std::move(value));
}
template <typename Self>
[[nodiscard]] constexpr auto To(this Self&& self, BareJid value) -> Initial {
return utils::FieldSetHelper::With<"to", Initial>(std::forward<Self>(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 <typename Self>
[[nodiscard]] constexpr auto From(this Self&& self, BareJid value) -> Probe {
return utils::FieldSetHelper::With<"from", Probe>(std::forward<Self>(self), std::move(value));
}
template <typename Self>
[[nodiscard]] constexpr auto To(this Self&& self, BareJid value) -> Probe {
return utils::FieldSetHelper::With<"to", Probe>(std::forward<Self>(self), std::move(value));
}
template <typename Self>
[[nodiscard]] constexpr auto Id(this Self&& self, std::string value) -> Probe {
return utils::FieldSetHelper::With<"id", Probe>(std::forward<Self>(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