147 lines
4.7 KiB
C++
147 lines
4.7 KiB
C++
export module larra.library.jid;
|
|
import std;
|
|
import fmt;
|
|
|
|
namespace larra::xmpp {
|
|
|
|
export struct BareJid;
|
|
|
|
auto ParseBareJid(std::string_view, std::size_t) -> BareJid;
|
|
|
|
export struct BareJid {
|
|
std::string username;
|
|
std::string server;
|
|
|
|
[[nodiscard]] friend auto ToString(const BareJid& jid) -> std::string {
|
|
return std::format("{}@{}", jid.username, jid.server);
|
|
}
|
|
|
|
template <typename Self>
|
|
[[nodiscard]] auto Username(this Self&& self, std::string username) -> BareJid {
|
|
return {std::move(username), std::forward_like<Self>(self.resource)};
|
|
}
|
|
|
|
template <typename Self>
|
|
[[nodiscard]] auto Server(this Self&& self, std::string server) -> BareJid {
|
|
return {std::forward_like<Self>(self.server), std::move(server)};
|
|
}
|
|
|
|
[[nodiscard]] static auto Parse(std::string_view jid) -> BareJid {
|
|
const auto at = jid.find('@');
|
|
if(at == std::string_view::npos) {
|
|
throw std::invalid_argument("Invalid string for jid");
|
|
}
|
|
|
|
return ParseBareJid(jid, at);
|
|
}
|
|
};
|
|
|
|
auto ParseBareJid(std::string_view jid, std::size_t at) -> BareJid {
|
|
return {static_cast<std::string>(jid.substr(0, at)), static_cast<std::string>(jid.substr(at + 1))};
|
|
}
|
|
|
|
export struct BareResourceJid;
|
|
|
|
auto ParseBareResourceJid(std::string_view, std::size_t) -> BareResourceJid;
|
|
|
|
export struct BareResourceJid {
|
|
std::string server;
|
|
std::string resource;
|
|
|
|
[[nodiscard]] friend auto ToString(const BareResourceJid& jid) -> std::string {
|
|
return std::format("{}/{}", jid.server, jid.resource);
|
|
};
|
|
|
|
template <typename Self>
|
|
[[nodiscard]] auto Server(this Self&& self, std::string server) -> BareResourceJid {
|
|
return {std::move(server), std::forward_like<Self>(self.resource)};
|
|
};
|
|
|
|
template <typename Self>
|
|
[[nodiscard]] auto Resource(this Self&& self, std::string resource) -> BareResourceJid {
|
|
return {std::forward_like<Self>(self.server), std::move(resource)};
|
|
};
|
|
|
|
[[nodiscard]] static auto Parse(std::string_view jid) -> BareResourceJid {
|
|
const auto slash = jid.find('/');
|
|
if(slash == std::string_view::npos) {
|
|
throw std::invalid_argument("Invalid string for jid");
|
|
};
|
|
|
|
return ParseBareResourceJid(jid, slash);
|
|
};
|
|
};
|
|
|
|
auto ParseBareResourceJid(std::string_view jid, std::size_t slash) -> BareResourceJid {
|
|
return {static_cast<std::string>(jid.substr(0, slash)), static_cast<std::string>(jid.substr(slash + 1))};
|
|
}
|
|
|
|
export struct FullJid;
|
|
|
|
auto ParseFullJid(std::string_view jid, std::size_t at, std::size_t slash) -> FullJid;
|
|
|
|
export struct FullJid {
|
|
std::string username;
|
|
std::string server;
|
|
std::string resource;
|
|
|
|
[[nodiscard]] friend auto ToString(const FullJid& jid) -> std::string {
|
|
return std::format("{}@{}/{}", jid.username, jid.server, jid.resource);
|
|
};
|
|
|
|
template <typename Self>
|
|
[[nodiscard]] auto Username(this Self&& self, std::string username) -> FullJid {
|
|
return {std::move(username), std::forward_like<Self>(self.server), std::forward_like<Self>(self.resource)};
|
|
};
|
|
|
|
template <typename Self>
|
|
[[nodiscard]] auto Server(this Self&& self, std::string server) -> FullJid {
|
|
return {std::forward_like<Self>(self.username), std::move(server), std::forward_like<Self>(self.resource)};
|
|
};
|
|
|
|
template <typename Self>
|
|
[[nodiscard]] auto Resource(this Self&& self, std::string resource) -> FullJid {
|
|
return {std::forward_like<Self>(self.username), std::forward_like<Self>(self.server), std::move(resource)};
|
|
};
|
|
|
|
[[nodiscard]] static auto Parse(std::string_view jid) -> FullJid {
|
|
const auto at = jid.find('@');
|
|
const auto slash = jid.find('/', at);
|
|
if(at == std::string_view::npos || slash == std::string_view::npos) {
|
|
throw std::invalid_argument("Invalid string for jid");
|
|
};
|
|
|
|
return ParseFullJid(jid, at, slash);
|
|
};
|
|
};
|
|
|
|
auto ParseFullJid(std::string_view jid, std::size_t at, std::size_t slash) -> FullJid {
|
|
return {static_cast<std::string>(jid.substr(0, at)),
|
|
static_cast<std::string>(jid.substr(at + 1, slash - at - 1)),
|
|
static_cast<std::string>(jid.substr(slash + 1))};
|
|
}
|
|
using JidVariant = std::variant<BareJid, BareResourceJid, FullJid>;
|
|
|
|
export struct Jid : JidVariant {
|
|
using JidVariant::variant;
|
|
[[nodiscard]] static auto Parse(std::string_view jid) -> Jid {
|
|
const auto at = jid.find('@');
|
|
const auto slash = jid.find('/', at == std::string_view::npos ? 0 : at);
|
|
if(at == std::string_view::npos) {
|
|
return ParseBareResourceJid(jid, slash);
|
|
}
|
|
if(slash == std::string_view::npos) {
|
|
return ParseBareJid(jid, at);
|
|
}
|
|
return ParseFullJid(jid, at, slash);
|
|
}
|
|
[[nodiscard]] friend auto ToString(const Jid& jid) -> std::string {
|
|
return std::visit<std::string>(
|
|
[](const auto& jid) -> std::string {
|
|
return ToString(jid);
|
|
},
|
|
jid);
|
|
};
|
|
};
|
|
|
|
} // namespace larra::xmpp
|