4#ifndef _Stroika_Foundation_IO_Network_URL_UniformResourceIdentification_
5#define _Stroika_Foundation_IO_Network_URL_UniformResourceIdentification_ 1
14namespace Stroika::Foundation::IO::Network::UniformResourceIdentification {
21 template <Characters::IConvertibleToString STRINGISH_T>
22 inline SchemeType::SchemeType (STRINGISH_T&& s)
26 inline strong_ordering SchemeType::operator<=> (
const SchemeType& rhs)
const
28 return TWC_ (*
this, rhs);
30 inline bool SchemeType::operator== (
const SchemeType& rhs)
const
32 return TWC_ (*
this, rhs) == 0;
40 inline Host::Host (
const String& registeredName)
41 : fEncodedName_{EncodeAsRawURL_ (registeredName)}
42 , fRegisteredName_{registeredName}
44 Require (not registeredName.empty ());
47 : fEncodedName_{EncodeAsRawURL_ (addr)}
48 , fInternetAddress_{addr}
53 Require (not rawURLHostnameText.empty ());
54 pair<optional<String>, optional<InternetAddress>> tmp{ParseRaw_ (rawURLHostnameText)};
56 h.fEncodedName_ = rawURLHostnameText;
57 h.fRegisteredName_ = tmp.first;
58 h.fInternetAddress_ = tmp.second;
61 inline optional<String> Host::AsRegisteredName ()
const
63 return fRegisteredName_;
67 return fInternetAddress_;
70 inline T
Host::As (optional<StringPCTEncodedFlag> pctEncode)
const
71 requires (same_as<T, String> or same_as<T, string>)
73 if constexpr (same_as<T, String>) {
74 switch (pctEncode.value_or (eDecoded)) {
75 case StringPCTEncodedFlag::eDecoded: {
76 if (fRegisteredName_) {
77 return *fRegisteredName_;
79 Assert (fInternetAddress_);
80 if (fInternetAddress_->GetAddressFamily () == InternetAddress::AddressFamily::V6) {
81 return "["sv + fInternetAddress_->As<
String> () +
"]"sv;
83 return fInternetAddress_->
As<String> ();
85 case StringPCTEncodedFlag::ePCTEncoded:
92 else if constexpr (same_as<T, string>) {
93 return As<String> (pctEncode.value_or (ePCTEncoded)).AsASCII ();
96 inline strong_ordering Host::operator<=> (
const Host& rhs)
const
98 return TWC_ (*
this, rhs);
100 inline bool Host::operator== (
const Host& rhs)
const
102 return TWC_ (*
this, rhs) == 0;
104 inline strong_ordering Host::TWC_ (
const Host& lhs,
const Host& rhs)
106 if (strong_ordering cmp = Common::StdCompat::compare_three_way{}(lhs.AsInternetAddress (), rhs.AsInternetAddress ());
107 cmp != strong_ordering::equal) {
110 return Common::OptionalThreeWayComparer<String, String::ThreeWayComparer>{String::ThreeWayComparer{Characters::eCaseInsensitive}}(
111 lhs.AsRegisteredName (), rhs.AsRegisteredName ());
119 inline UserInfo::UserInfo (
const String& decodedUserInfo)
120 : fEncodedUserInfo_{EncodeAsRawURL_ (decodedUserInfo)}
121 , fUserInfo_{decodedUserInfo}
123 Require (not decodedUserInfo.empty ());
127 Require (not rawURLUserInfo.empty ());
129 h.fEncodedUserInfo_ = rawURLUserInfo;
130 h.fUserInfo_ = ParseRaw_ (rawURLUserInfo);
133 template <
typename T>
134 inline T
UserInfo::As (optional<StringPCTEncodedFlag> pctEncode)
const
135 requires (same_as<T, String> or same_as<T, string>)
137 if constexpr (same_as<T, String>) {
138 switch (pctEncode.value_or (eDecoded)) {
139 case StringPCTEncodedFlag::eDecoded:
141 case StringPCTEncodedFlag::ePCTEncoded:
142 return fEncodedUserInfo_;
148 else if constexpr (same_as<T, string>) {
149 return As<String> (pctEncode.value_or (ePCTEncoded)).AsASCII ();
152 inline strong_ordering UserInfo::operator<=> (
const UserInfo& rhs)
const
154 return TWC_ (*
this, rhs);
156 inline bool UserInfo::operator== (
const UserInfo& rhs)
const
158 return As (eDecoded) == rhs.As (eDecoded);
160 inline strong_ordering UserInfo::TWC_ (
const UserInfo& lhs,
const UserInfo& rhs)
162 return lhs.As (eDecoded) <=> rhs.As (eDecoded);
170 inline Authority::Authority (
const optional<Host>& h,
const optional<PortType>& port,
const optional<UserInfo>& userInfo)
173 , fUserInfo_{userInfo}
180 inline void Authority::SetHost (
const optional<Host>& host)
184 inline optional<PortType> Authority::GetPort ()
const
188 inline void Authority::SetPort (
const optional<PortType>& port)
198 fUserInfo_ = userInfo;
200 inline strong_ordering Authority::operator<=> (
const Authority& rhs)
const
202 return TWC_ (*
this, rhs);
204 inline bool Authority::operator== (
const Authority& rhs)
const
206 return TWC_ (*
this, rhs) == 0;
208 inline strong_ordering Authority::TWC_ (
const Authority& lhs,
const Authority& rhs)
210 if (
auto cmp = Common::StdCompat::compare_three_way{}(lhs.GetHost (), rhs.GetHost ()); cmp != strong_ordering::equal) {
213 if (
auto cmp = Common::StdCompat::compare_three_way{}(lhs.GetUserInfo (), rhs.GetUserInfo ()); cmp != strong_ordering::equal) {
216 return Common::StdCompat::compare_three_way{}(lhs.GetPort (), rhs.GetPort ());
224 inline const Containers::Mapping<String, String>& Query::GetMap ()
const
228 inline String Query::operator() (
const String& idx)
const
230 return Memory::NullCoalesce (fMap_.Lookup (idx));
232 inline String Query::operator() (
const u8string& idx)
const
236 inline bool Query::HasField (
const String& idx)
const
238 return fMap_.ContainsKey (idx);
240 inline bool Query::HasField (
const u8string& idx)
const
246 return fMap_.Lookup (idx);
248 inline void Query::AddField (
const String& idx,
const String& value)
250 fMap_.Add (idx, value);
252 inline void Query::RemoveFieldIfAny (
const u8string& idx)
256 inline strong_ordering Query::operator<=> (
const Query& rhs)
const
258 return TWC_ (*
this, rhs);
260 inline bool Query::operator== (
const Query& rhs)
const
262 return TWC_ (*
this, rhs) == 0;
#define RequireNotReached()
String is like std::u32string, except it is much easier to use, often much more space efficient,...
static String FromUTF8(span< CHAR_T > from)