#include "username.h"
#include <string>
#include <uni_algo/case.h>
#include <uni_algo/conv.h>
#include <uni_algo/norm.h>
#include <uni_algo/prop.h>
mw::E<NormalizedUsername> normalizeUsername(const std::string& input)
{
if(!una::is_valid_utf8(input))
{
return std::unexpected(mw::runtimeError("Invalid username"));
}
std::string username = una::norm::to_nfc_utf8(input);
if(username.empty() || username.size() > 32)
{
return std::unexpected(mw::runtimeError("Invalid username"));
}
const std::u32string codepoints = una::utf8to32u(username);
for(char32_t codepoint : codepoints)
{
if(una::codepoint::prop(codepoint).General_Category_Cc())
{
return std::unexpected(mw::runtimeError("Invalid username"));
}
}
if(una::codepoint::prop(codepoints.front()).White_Space() ||
una::codepoint::prop(codepoints.back()).White_Space())
{
return std::unexpected(mw::runtimeError("Invalid username"));
}
std::string key = una::cases::to_casefold_utf8(username);
key = una::norm::to_nfc_utf8(key);
return NormalizedUsername{std::move(username), std::move(key)};
}