Add Jid to library

This commit is contained in:
sha512sum 2024-08-27 10:11:02 +00:00
parent a4a5df3f27
commit 6690b04a50
3 changed files with 113 additions and 0 deletions

75
src/lib/jid.cpp Normal file
View file

@ -0,0 +1,75 @@
export module larra.library.jid;
import std;
import fmt;
namespace larra::xmpp {
export struct Jid {
[[nodiscard]] static auto Parse(std::string_view jid) -> Jid {
Jid response;
const auto at = jid.find('@');
const auto slash = jid.find('/', at == std::string_view::npos ? 0 : at);
if(at != std::string_view::npos) {
response.username = jid.substr(0, at);
response.server = jid.substr(at + 1, (slash == std::string_view::npos ? jid.size() : slash) - (at + 1));
} else {
response.server = jid.substr(0, slash);
}
if(slash != std::string_view::npos) {
response.resource = jid.substr(slash + 1);
}
return response;
}
template <typename Self>
[[nodiscard]] auto Username(this Self&& self, std::string username) -> Jid {
return {std::forward_like<Self>(self.server), std::move(username), std::forward_like<Self>(self.resource)};
}
template <typename Self>
[[nodiscard]] auto Server(this Self&& self, std::string server) -> Jid {
return {std::move(server), std::forward_like<Self>(self.username), std::forward_like<Self>(self.resource)};
}
template <typename Self>
[[nodiscard]] auto Resource(this Self&& self, std::string resource) -> Jid {
return {std::forward_like<Self>(self.server), std::forward_like<Self>(self.username), std::move(resource)};
}
[[nodiscard]] auto IsValid() const -> bool {
return this->server && this->username || this->resource;
}
[[nodiscard]] auto Username() const -> std::string_view {
return *this->username;
}
[[nodiscard]] auto Server() const -> std::string_view {
return *this->server;
}
[[nodiscard]] auto Resource() const -> std::string_view {
return *this->resource;
}
[[nodiscard]] explicit operator std::string() const {
if(!IsValid()) {
throw std::invalid_argument("Invalid jid obj");
}
return !this->username ? std::format("{}/{}", *this->server, *this->resource)
: !this->resource ? std::format("{}@{}", *this->username, *this->server)
: std::format("{}@{}/{}", *this->username, *this->server, *this->resource);
}
[[nodiscard]] auto ToString() const -> std::string {
return static_cast<std::string>(*this);
};
std::optional<std::string> server{};
std::optional<std::string> username{};
std::optional<std::string> resource{};
};
} // namespace larra::xmpp

View file

@ -1 +1,2 @@
export module larra.library; export module larra.library;
export import larra.jid;

37
tests/jid.cpp Normal file
View file

@ -0,0 +1,37 @@
module;
#include <gtest/gtest.h>
export module tests.jid;
import larra.library.jid;
namespace larra::xmpp {
TEST(Jid, Basic) {
auto jid = Jid{.username = "user"};
EXPECT_FALSE(jid.IsValid());
const auto jid2 = std::move(jid).Server("server").Resource("resource");
EXPECT_EQ(jid2.Server(), "server");
EXPECT_EQ(jid2.Username(), "user");
EXPECT_EQ(jid2.Resource(), "resource");
}
TEST(Jid, Parse) {
const auto jid = Jid::Parse("user@server/resource");
EXPECT_EQ(jid.Username(), "user");
EXPECT_EQ(jid.Server(), "server");
EXPECT_EQ(jid.Resource(), "resource");
const auto jid2 = Jid::Parse("server/resource");
EXPECT_EQ(jid2.Server(), "server");
EXPECT_EQ(jid2.Resource(), "resource");
const auto jid3 = Jid::Parse("user@server");
EXPECT_EQ(jid3.Username(), "user");
EXPECT_EQ(jid3.Server(), "server");
}
TEST(Jid, ToString) {
EXPECT_EQ((Jid{.server = "server", .username = "user", .resource = "resource"}.ToString()), "user@server/resource");
EXPECT_EQ((Jid{.server = "server", .username = "user"}.ToString()), "user@server");
EXPECT_THROW(std::ignore = Jid{}.ToString(), std::invalid_argument);
}
} // namespace larra::xmpp