Skip to content

Commit

Permalink
feat(core/url): introduce 'URL::Builder'
Browse files Browse the repository at this point in the history
  • Loading branch information
jwerle committed Jun 28, 2024
1 parent 7f9c96a commit 65da59d
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 0 deletions.
113 changes: 113 additions & 0 deletions src/core/url.cc
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,119 @@ namespace SSC {
return components;
}

URL::Builder& URL::Builder::setProtocol (const String& protocol) {
this->protocol = protocol;
return *this;
}

URL::Builder& URL::Builder::setUsername (const String& username) {
this->username = username;
return *this;
}

URL::Builder& URL::Builder::setPassword (const String& password) {
this->password = password;
return *this;
}

URL::Builder& URL::Builder::setHostname (const String& hostname) {
this->hostname = hostname;
return *this;
}

URL::Builder& URL::Builder::setPort (const String& port) {
this->port = port;
return *this;
}

URL::Builder& URL::Builder::setPort (const int port) {
this->port = std::to_string(port);
return *this;
}

URL::Builder& URL::Builder::setPathname (const String& pathname) {
this->pathname = pathname;
return *this;
}

URL::Builder& URL::Builder::setQuery (const String& query) {
this->search = "?" + query;
return *this;
}

URL::Builder& URL::Builder::setSearch (const String& search) {
this->search = search;
return *this;
}

URL::Builder& URL::Builder::setHash (const String& hash) {
this->hash = hash;
return *this;
}

URL::Builder& URL::Builder::setFragment (const String& fragment) {
this->hash = "#" + fragment;
return *this;
}

URL::Builder& URL::Builder::setSearchParam (const String& key, const String& value) {
this->searchParams[key] = value;
return *this;
}

URL::Builder& URL::Builder::setSearchParam (const String& key, const JSON::Any& value) {
if (JSON::typeof(value) == "string" || JSON::typeof(value) == "number" || JSON::typeof(value) == "boolean") {
return this->setSearchParam(key, value.str());
}

return *this;
}

URL::Builder& URL::Builder::setSearchParams (const Map& params) {
for (const auto& entry : params) {
this->searchParams.insert_or_assign(entry.first, entry.second);
}
return *this;
}

URL URL::Builder::build () const {
StringStream stream;

if (this->protocol.size() == 0) {
return String("");
}

stream << this->protocol << ":";

if (
(this->username.size() > 0 || this->password.size() > 0) &&
this->hostname.size() > 0
) {
stream << "//";
if (this->username.size() > 0) {
stream << this->username;
if (this->password.size() > 0) {
stream << ":" << this->password;
}

stream << "@" << this->hostname;
if (this->port.size() > 0) {
stream << ":" << this->port;
}
}
}

if (this->hostname.size() > 0 && this->pathname.size() > 0) {
if (!this->pathname.starts_with("/")) {
stream << "/";
}
}

stream << this->pathname << this->search << this->hash;

return stream.str();
}

URL::URL (const JSON::Object& json)
: URL(json["href"].str())
{}
Expand Down
31 changes: 31 additions & 0 deletions src/core/url.hh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,36 @@ namespace SSC {
static const Components parse (const String& url);
};

struct Builder {
String protocol = "";
String username = "";
String password = "";
String hostname = "";
String port = "";
String pathname = "";
String search = ""; // includes '?' and 'query' if 'query' is not empty
String hash = ""; // include '#' and 'fragment' if 'fragment' is not empty

Map searchParams;

Builder& setProtocol (const String& protocol);
Builder& setUsername (const String& username);
Builder& setPassword (const String& password);
Builder& setHostname (const String& hostname);
Builder& setPort (const String& port);
Builder& setPort (const int port);
Builder& setPathname (const String& pathname);
Builder& setQuery (const String& query);
Builder& setSearch (const String& search);
Builder& setHash (const String& hash);
Builder& setFragment (const String& fragment);
Builder& setSearchParam (const String& key, const String& value);
Builder& setSearchParam (const String& key, const JSON::Any& value);
Builder& setSearchParams (const Map& params);

URL build () const;
};

// core properties
String href = "";
String origin = "";
Expand All @@ -37,6 +67,7 @@ namespace SSC {
URL () = default;
URL (const String& href);
URL (const JSON::Object& json);

void set (const String& href);
void set (const JSON::Object& json);
const String str () const;
Expand Down

0 comments on commit 65da59d

Please sign in to comment.