#include #include #include #include namespace arc::uri { uri_t:: uri_t() {} uri_t:: uri_t(std::string scheme, std::string host, std::string path) : scheme_{std::move(scheme)}, host_{std::move(host)}, path_{std::move(path)} {} uri_t:: uri_t(std::string scheme, std::string host, std::string port, std::string path) : scheme_{std::move(scheme)}, host_{std::move(host)}, port_{std::move(port)}, path_{std::move(path)} {} uri_t:: uri_t(std::string scheme, std::string host, std::string port, std::string path, std::string query) : scheme_{std::move(scheme)}, host_{std::move(host)}, port_{std::move(port)}, path_{std::move(path)}, query_{std::move(query)} {} uri_t:: uri_t(std::string scheme, std::string host, std::string port, std::string path, std::string query, std::string fragment) : scheme_{std::move(scheme)}, host_{std::move(host)}, port_{std::move(port)}, path_{std::move(path)}, query_{std::move(query)}, fragment_{std::move(fragment)} {} uri_t:: uri_t(std::string scheme, std::string userinfo, std::string host, std::string port, std::string path, std::string query, std::string fragment) : scheme_{std::move(scheme)}, userinfo_{std::move(userinfo)}, host_{std::move(host)}, port_{std::move(port)}, path_{std::move(path)}, query_{std::move(query)}, fragment_{std::move(fragment)} {} uri_t:: uri_t(std::optional scheme, std::optional userinfo, std::optional host, std::optional port, std::string path, std::optional query, std::optional fragment) : scheme_{std::move(scheme)}, userinfo_{std::move(userinfo)}, host_{std::move(host)}, port_{std::move(port)}, path_{std::move(path)}, query_{std::move(query)}, fragment_{std::move(fragment)} {} std::optional const& uri_t:: scheme() const { return scheme_; } std::string uri_t:: scheme_str() const { return scheme().value_or(std::string{}); } std::optional const& uri_t:: userinfo() const { return userinfo_; } std::string uri_t:: userinfo_str() const { return userinfo().value_or(std::string{}); } std::optional const& uri_t:: host() const { return host_; } std::string uri_t:: host_str() const { return host().value_or(std::string{}); } std::optional const& uri_t:: port() const { return port_; } std::string uri_t:: port_str() const { return port().value_or(std::string{}); } std::string uri_t:: path_str() const { return path_; } std::optional const& uri_t:: query() const { return query_; } std::string uri_t:: query_str() const { return query().value_or(std::string{}); } std::optional const& uri_t:: fragment() const { return fragment_; } std::string uri_t:: fragment_str() const { return fragment().value_or(std::string{}); } std::string to_string(uri_t const& uri) { std::ostringstream str; // Scheme // if (auto scheme = uri.scheme(); scheme) { str <<*scheme <<':'; } // Authority // if (auto host = uri.host(); host) { str <<"//"; // Userinfo // if (auto userinfo = uri.userinfo(); userinfo) { str <<*userinfo <<'@'; } // Host // str <<*host; // Port if (auto port = uri.port(); port) { str <<':' <<*port; } } // Path // str < segments; for (std::string segment; std::getline(path, segment, '/');) { std::cout << "found segment: " << segment << '\n'; if (segment.empty()) { continue; } if (segment == ".") { continue; } if (segment == "..") { if (!segments.empty()) { segments.pop_back(); } continue; } segments.push_back(segment); } std::string normalized; for (auto const& j : segments) { normalized += '/'; normalized += j; } return uri_t{ uri.scheme(), uri.userinfo(), uri.host(), uri.port(), normalized.empty() ? "/" : normalized, uri.query(), uri.fragment() }; } std::optional try_parse(std::string const& str) { return try_parse(str.begin(), str.end()); } } // namespace uri