Skip to content

Commit

Permalink
simplify implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
anonrig committed Dec 29, 2024
1 parent f3d65c0 commit e7c580d
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 85 deletions.
64 changes: 18 additions & 46 deletions include/ada/url_pattern-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,16 @@

namespace ada {

inline bool url_pattern_component::has_regexp_groups() const noexcept
ada_lifetime_bound {
return has_regexp_groups_;
}

inline std::string url_pattern_component::to_string() const {
#ifdef ADA_HAS_FORMAT
return std::format(R"({{"pattern": "{}", "has_regexp_groups": {}}})", pattern,
has_regexp_groups_ ? "true" : "false" //,
has_regexp_groups ? "true" : "false" //,
);
#else
return "";
#endif
}

inline std::string_view url_pattern_component::get_pattern() const noexcept
ada_lifetime_bound {
return pattern;
}

inline const std::regex& url_pattern_component::get_regexp() const noexcept
ada_lifetime_bound {
return regexp;
}

inline std::regex_constants::syntax_option_type
url_pattern_component::get_regexp_flags() const noexcept ada_lifetime_bound {
return flags;
}

inline const std::vector<std::string>&
url_pattern_component::get_group_name_list() const noexcept ada_lifetime_bound {
return group_name_list;
}

inline url_pattern_component_result
url_pattern_component::create_component_match_result(
std::string_view input, const std::smatch& exec_result) {
Expand Down Expand Up @@ -89,51 +64,48 @@ inline std::string url_pattern::to_string() const {

inline std::string_view url_pattern::get_protocol() const ada_lifetime_bound {
// Return this's associated URL pattern's protocol component's pattern string.
return protocol_component.get_pattern();
return protocol_component.pattern;
}
inline std::string_view url_pattern::get_username() const ada_lifetime_bound {
// Return this's associated URL pattern's username component's pattern string.
return username_component.get_pattern();
return username_component.pattern;
}
inline std::string_view url_pattern::get_password() const ada_lifetime_bound {
// Return this's associated URL pattern's password component's pattern string.
return password_component.get_pattern();
return password_component.pattern;
}
inline std::string_view url_pattern::get_hostname() const ada_lifetime_bound {
// Return this's associated URL pattern's hostname component's pattern string.
return hostname_component.get_pattern();
return hostname_component.pattern;
}
inline std::string_view url_pattern::get_port() const ada_lifetime_bound {
// Return this's associated URL pattern's port component's pattern string.
return port_component.get_pattern();
return port_component.pattern;
}
inline std::string_view url_pattern::get_pathname() const ada_lifetime_bound {
// Return this's associated URL pattern's pathname component's pattern string.
return pathname_component.get_pattern();
return pathname_component.pattern;
}
inline std::string_view url_pattern::get_search() const ada_lifetime_bound {
// Return this's associated URL pattern's search component's pattern string.
return search_component.get_pattern();
return search_component.pattern;
}
inline std::string_view url_pattern::get_hash() const ada_lifetime_bound {
// Return this's associated URL pattern's hash component's pattern string.
return hash_component.get_pattern();
return hash_component.pattern;
}

inline bool url_pattern::ignore_case() const ada_lifetime_bound {
return ignore_case_;
}
inline bool url_pattern::ignore_case() const { return ignore_case_; }

inline bool url_pattern::has_regexp_groups() const ada_lifetime_bound {
inline bool url_pattern::has_regexp_groups() const {
// If this's associated URL pattern's has regexp groups, then return true.
return protocol_component.has_regexp_groups() ||
username_component.has_regexp_groups() ||
password_component.has_regexp_groups() ||
hostname_component.has_regexp_groups() ||
port_component.has_regexp_groups() ||
pathname_component.has_regexp_groups() ||
search_component.has_regexp_groups() ||
hash_component.has_regexp_groups();
return protocol_component.has_regexp_groups ||
username_component.has_regexp_groups ||
password_component.has_regexp_groups ||
hostname_component.has_regexp_groups ||
port_component.has_regexp_groups ||
pathname_component.has_regexp_groups ||
search_component.has_regexp_groups || hash_component.has_regexp_groups;
}

inline bool url_pattern_part::is_regexp() const noexcept {
Expand Down
32 changes: 10 additions & 22 deletions include/ada/url_pattern.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,15 +184,15 @@ class url_pattern_component {

// This function explicitly takes a std::string because it is moved.
// To avoid unnecessary copy, move each value while calling the constructor.
url_pattern_component(std::string&& new_pattern, std::regex&& new_regexp,
std::regex_constants::syntax_option_type&& new_flags,
url_pattern_component(std::string_view new_pattern, std::regex&& new_regexp,
std::regex_constants::syntax_option_type new_flags,
std::vector<std::string>&& new_group_name_list,
bool new_has_regexp_groups)
: pattern(std::move(new_pattern)),
: regexp(new_regexp),
pattern(std::move(new_pattern)),
flags(new_flags),
regexp(std::move(new_regexp)),
group_name_list(std::move(new_group_name_list)),
has_regexp_groups_(new_has_regexp_groups) {}
group_name_list(new_group_name_list),
has_regexp_groups(new_has_regexp_groups) {}

// @see https://urlpattern.spec.whatwg.org/#compile-a-component
template <url_pattern_encoding_callback F>
Expand All @@ -204,25 +204,13 @@ class url_pattern_component {
url_pattern_component_result create_component_match_result(
std::string_view input, const std::smatch& exec_result);

std::string_view get_pattern() const noexcept ada_lifetime_bound
ada_warn_unused;
const std::regex& get_regexp() const noexcept ada_lifetime_bound
ada_warn_unused;
std::regex_constants::syntax_option_type get_regexp_flags() const noexcept
ada_lifetime_bound ada_warn_unused;
const std::vector<std::string>& get_group_name_list() const noexcept
ada_lifetime_bound ada_warn_unused;
bool has_regexp_groups() const noexcept ada_lifetime_bound ada_warn_unused;

std::string to_string() const;

private:
std::regex regexp{};
std::string pattern{};
std::regex_constants::syntax_option_type flags = std::regex::ECMAScript;
std::regex regexp{};
std::vector<std::string> group_name_list{};

bool has_regexp_groups_ = false;
bool has_regexp_groups = false;
};

using url_pattern_input = std::variant<url_aggregator, url_pattern_init>;
Expand Down Expand Up @@ -292,10 +280,10 @@ class url_pattern {

// If ignoreCase is true, the JavaScript regular expression created for each
// pattern must use the `vi` flag. Otherwise, they must use the `v` flag.
bool ignore_case() const ada_lifetime_bound;
bool ignore_case() const;

// @see https://urlpattern.spec.whatwg.org/#url-pattern-has-regexp-groups
bool has_regexp_groups() const ada_lifetime_bound;
bool has_regexp_groups() const;

std::string to_string() const;

Expand Down
33 changes: 16 additions & 17 deletions src/url_pattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,9 +505,9 @@ url_pattern_component::compile(std::string_view input, F encoding_callback,
// Let flags be an empty string.
// If options’s ignore case is true then set flags to "vi".
// Otherwise set flags to "v"
std::regex_constants::syntax_option_type flags =
options.ignore_case ? std::regex::icase | std::regex_constants::ECMAScript
: std::regex_constants::ECMAScript;
auto flags = options.ignore_case
? std::regex::icase | std::regex_constants::ECMAScript
: std::regex_constants::ECMAScript;

// Let pattern string be the result of running generate a pattern
// string given part list and options.
Expand Down Expand Up @@ -536,9 +536,8 @@ url_pattern_component::compile(std::string_view input, F encoding_callback,
// Return a new component whose pattern string is pattern string, regular
// expression is regular expression, group name list is name list, and has
// regexp groups is has regexp groups.
return url_pattern_component(std::move(pattern_string),
std::move(regular_expression), std::move(flags),
std::move(name_list), has_regexp_groups);
return url_pattern_component(pattern_string, std::move(regular_expression),
flags, std::move(name_list), has_regexp_groups);
}

namespace url_pattern_helpers {
Expand Down Expand Up @@ -728,7 +727,7 @@ std::string generate_segment_wildcard_regexp(

bool protocol_component_matches_special_scheme(
url_pattern_component& component) {
const auto& regex = component.get_regexp();
auto regex = component.regexp;
return std::regex_match("http", regex) || std::regex_match("https", regex) ||
std::regex_match("ws", regex) || std::regex_match("wss", regex) ||
std::regex_match("ftp", regex);
Expand Down Expand Up @@ -901,49 +900,49 @@ url_pattern::match(url_pattern_input&& input,
// component's regular expression, protocol).
std::smatch protocol_exec_result_value;
auto protocol_exec_result = std::regex_match(
protocol, protocol_exec_result_value, protocol_component.get_regexp());
protocol, protocol_exec_result_value, protocol_component.regexp);

// Let usernameExecResult be RegExpBuiltinExec(urlPattern’s username
// component's regular expression, username).
std::smatch username_exec_result_value;
auto username_exec_result = std::regex_match(
username, username_exec_result_value, username_component.get_regexp());
username, username_exec_result_value, username_component.regexp);

// Let passwordExecResult be RegExpBuiltinExec(urlPattern’s password
// component's regular expression, password).
std::smatch password_exec_result_value;
auto password_exec_result = std::regex_match(
password, password_exec_result_value, password_component.get_regexp());
password, password_exec_result_value, password_component.regexp);

// Let hostnameExecResult be RegExpBuiltinExec(urlPattern’s hostname
// component's regular expression, hostname).
std::smatch hostname_exec_result_value;
auto hostname_exec_result = std::regex_match(
hostname, hostname_exec_result_value, hostname_component.get_regexp());
hostname, hostname_exec_result_value, hostname_component.regexp);

// Let portExecResult be RegExpBuiltinExec(urlPattern’s port component's
// regular expression, port).
std::smatch port_exec_result_value;
auto port_exec_result = std::regex_match(port, port_exec_result_value,
port_component.get_regexp());
auto port_exec_result =
std::regex_match(port, port_exec_result_value, port_component.regexp);

// Let pathnameExecResult be RegExpBuiltinExec(urlPattern’s pathname
// component's regular expression, pathname).
std::smatch pathname_exec_result_value;
auto pathname_exec_result = std::regex_match(
pathname, pathname_exec_result_value, pathname_component.get_regexp());
pathname, pathname_exec_result_value, pathname_component.regexp);

// Let searchExecResult be RegExpBuiltinExec(urlPattern’s search component's
// regular expression, search).
std::smatch search_exec_result_value;
auto search_exec_result = std::regex_match(search, search_exec_result_value,
search_component.get_regexp());
search_component.regexp);

// Let hashExecResult be RegExpBuiltinExec(urlPattern’s hash component's
// regular expression, hash).
std::smatch hash_exec_result_value;
auto hash_exec_result = std::regex_match(hash, hash_exec_result_value,
hash_component.get_regexp());
auto hash_exec_result =
std::regex_match(hash, hash_exec_result_value, hash_component.regexp);

// If protocolExecResult, usernameExecResult, passwordExecResult,
// hostnameExecResult, portExecResult, pathnameExecResult, searchExecResult,
Expand Down
17 changes: 17 additions & 0 deletions tests/wpt_urlpattern_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,23 @@ using namespace simdjson;
constexpr std::string_view URL_PATTERN_TEST_DATA =
"wpt/urlpatterntestdata.json";

TEST(wpt_urlpattern_tests, basic_tests) {
auto init = ada::url_pattern_init{};
init.pathname = "/books";
auto url = ada::parse_url_pattern(init);
ASSERT_TRUE(url);
ASSERT_EQ(url->get_protocol(), "*");
ASSERT_EQ(url->get_hostname(), "*");
ASSERT_EQ(url->get_username(), "*");
ASSERT_EQ(url->get_password(), "*");
ASSERT_EQ(url->get_port(), "*");
ASSERT_EQ(url->get_pathname(), "/books");
ASSERT_EQ(url->get_search(), "*");
ASSERT_EQ(url->get_hash(), "*");
ASSERT_FALSE(url->has_regexp_groups());
SUCCEED();
}

// Tests are taken from WPT
// https://github.com/web-platform-tests/wpt/blob/0c1d19546fd4873bb9f4147f0bbf868e7b4f91b7/urlpattern/resources/urlpattern-hasregexpgroups-tests.js
TEST(wpt_urlpattern_tests, has_regexp_groups) {
Expand Down

0 comments on commit e7c580d

Please sign in to comment.