Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
make progress
  • Loading branch information
anonrig committed Jan 22, 2025
commit e53335ee0555f2aa636016f71bc1ab547d6458d9
15 changes: 7 additions & 8 deletions include/ada/implementation.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@

#include "ada/parser.h"
#include "ada/common_defs.h"
#include "ada/encoding_type.h"
#include "ada/url.h"
#include "ada/state.h"
#include "ada/url_aggregator.h"
#include "ada/url_pattern_regex.h"

namespace ada {
Expand Down Expand Up @@ -61,11 +58,13 @@ bool can_parse(std::string_view input,
* use ada::url_pattern_regex::std_regex_provider
* @return url_pattern instance
*/
ada_warn_unused tl::expected<url_pattern, errors> parse_url_pattern(
std::variant<std::string_view, url_pattern_init> input,
const std::string_view* base_url = nullptr,
const url_pattern_options* options = nullptr,
std::optional<url_pattern_regex::provider> regex_provider = std::nullopt);
template <class regex_provider, class regex_type>
requires url_pattern_regex::derived_from_provider<regex_provider, regex_type>
ada_warn_unused tl::expected<url_pattern<regex_provider, regex_type>, errors>
parse_url_pattern(std::variant<std::string_view, url_pattern_init> input,
const std::string_view* base_url = nullptr,
const url_pattern_options* options = nullptr,
std::optional<regex_provider> provider = std::nullopt);

/**
* Computes a href string from a file path. The function assumes
Expand Down
13 changes: 9 additions & 4 deletions include/ada/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
namespace ada {
struct url_aggregator;
struct url;
template <class regex_provider, class regex_type>
requires url_pattern_regex::derived_from_provider<regex_provider, regex_type>
class url_pattern;
struct url_pattern_options;
struct url_pattern_init;
Expand Down Expand Up @@ -52,10 +54,13 @@ extern template url_aggregator parse_url_impl<url_aggregator>(
extern template url parse_url_impl<url>(std::string_view user_input,
const url* base_url);

tl::expected<url_pattern, errors> parse_url_pattern_impl(
std::variant<std::string_view, url_pattern_init> input,
const std::string_view* base_url, const url_pattern_options* options,
url_pattern_regex::provider&& regex_provider);
template <class regex_provider, class regex_type>
requires url_pattern_regex::derived_from_provider<regex_provider, regex_type>
tl::expected<url_pattern<regex_provider, regex_type>, errors>
parse_url_pattern_impl(std::variant<std::string_view, url_pattern_init> input,
const std::string_view* base_url,
const url_pattern_options* options,
regex_provider&& provider);

} // namespace ada::parser

Expand Down
10 changes: 7 additions & 3 deletions include/ada/url_aggregator.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,13 @@ struct url_aggregator : url_base {
friend url_aggregator parser::parse_url_impl<url_aggregator, false>(
std::string_view, const url_aggregator *);
// url_pattern methods
friend tl::expected<url_pattern, errors> parse_url_pattern_impl(
std::variant<std::string_view, url_pattern_init> input,
const std::string_view *base_url, const url_pattern_options *options);
template <class regex_provider, class regex_type>
requires url_pattern_regex::derived_from_provider<regex_provider,
regex_type>
friend tl::expected<url_pattern<regex_provider, regex_type>, errors>
parse_url_pattern_impl(std::variant<std::string_view, url_pattern_init> input,
const std::string_view *base_url,
const url_pattern_options *options);

std::string buffer{};
url_components components{};
Expand Down
69 changes: 52 additions & 17 deletions include/ada/url_pattern-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ inline bool url_pattern_component_result::operator==(
return input == other.input && groups == other.groups;
}

inline std::string url_pattern_component::to_string() const {
template <class regex_provider, class regex_type>
requires url_pattern_regex::derived_from_provider<regex_provider, regex_type>
std::string url_pattern_component<regex_provider, regex_type>::to_string()
const {
#ifdef ADA_HAS_FORMAT
return std::format(R"({{"pattern": "{}", "has_regexp_groups": {}}})", pattern,
has_regexp_groups ? "true" : "false" //,
Expand All @@ -34,9 +37,11 @@ inline std::string url_pattern_component::to_string() const {
#endif
}

inline url_pattern_component_result
url_pattern_component::create_component_match_result(
std::string_view input, const std::smatch& exec_result) {
template <class regex_provider, class regex_type>
requires url_pattern_regex::derived_from_provider<regex_provider, regex_type>
url_pattern_component_result url_pattern_component<regex_provider, regex_type>::
create_component_match_result(std::string_view input,
const std::smatch& exec_result) {
// Let result be a new URLPatternComponentResult.
// Set result["input"] to input.
// Let groups be a record<USVString, (USVString or undefined)>.
Expand Down Expand Up @@ -70,7 +75,9 @@ url_pattern_component::create_component_match_result(
return result;
}

inline std::string url_pattern::to_string() const {
template <class regex_provider, class regex_type>
requires url_pattern_regex::derived_from_provider<regex_provider, regex_type>
std::string url_pattern<regex_provider, regex_type>::to_string() const {
#ifdef ADA_HAS_FORMAT
return std::format(
R"({{"protocol_component": "{}", "username_component": {}, "password_component": {}, "hostname_component": {}, "port_component": {}, "pathname_component": {}, "search_component": {}, "hash_component": {}, "ignore_case": {}}})",
Expand All @@ -84,42 +91,70 @@ inline std::string url_pattern::to_string() const {
#endif
}

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

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

inline bool url_pattern::has_regexp_groups() const {
template <class regex_provider, class regex_type>
requires url_pattern_regex::derived_from_provider<regex_provider, regex_type>
bool url_pattern<regex_provider, regex_type>::ignore_case() const {
return ignore_case_;
}
template <class regex_provider, class regex_type>
requires url_pattern_regex::derived_from_provider<regex_provider, regex_type>
bool url_pattern<regex_provider, regex_type>::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 ||
Expand Down
67 changes: 35 additions & 32 deletions include/ada/url_pattern.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ namespace ada {

namespace parser {
template <typename result_type, typename url_pattern_init,
typename url_pattern_options>
typename url_pattern_options, typename regex_provider>
tl::expected<result_type, errors> parse_url_pattern_impl(
std::variant<std::string_view, url_pattern_init> input,
const std::string_view* base_url, const url_pattern_options* options,
url_pattern_regex::provider&& regex_provider);
regex_provider&& provider);
}

// Important: C++20 allows us to use concept rather than `using` or `typedef
Expand Down Expand Up @@ -207,37 +207,37 @@ struct url_pattern_component_result {
#endif // ADA_TESTING
};

template <class regex_provider, class regex_type>
requires url_pattern_regex::derived_from_provider<regex_provider, regex_type>
class url_pattern_component {
public:
url_pattern_component() = default;

// 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&& new_pattern, regex_type&& new_regexp,
std::vector<std::string>&& new_group_name_list,
bool new_has_regexp_groups)
: regexp(std::move(new_regexp)),
pattern(std::move(new_pattern)),
flags(new_flags),
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>
static tl::expected<url_pattern_component, errors> compile(
std::string_view input, F& encoding_callback,
url_pattern_compile_component_options& options);
url_pattern_compile_component_options& options,
const regex_provider& provider);

// @see https://urlpattern.spec.whatwg.org/#create-a-component-match-result
url_pattern_component_result create_component_match_result(
std::string_view input, const std::smatch& exec_result);

std::string to_string() const;

std::regex regexp{};
regex_type regexp{};
std::string pattern{};
std::regex_constants::syntax_option_type flags = std::regex::ECMAScript;
std::vector<std::string> group_name_list{};
bool has_regexp_groups = false;
};
Expand Down Expand Up @@ -270,10 +270,13 @@ struct url_pattern_options {
// defined in https://wicg.github.io/urlpattern.
// More information about the URL Pattern syntax can be found at
// https://developer.mozilla.org/en-US/docs/Web/API/URL_Pattern_API
template <class regex_provider, class regex_type>
requires url_pattern_regex::derived_from_provider<regex_provider, regex_type>
class url_pattern {
public:
explicit url_pattern(url_pattern_regex::provider&& regex_provider)
: regex_provider_(std::move(regex_provider)) {}
explicit url_pattern(
url_pattern_regex::provider<regex_type>&& new_regex_provider)
: regex_provider_(std::move(new_regex_provider)) {}

/**
* @see https://urlpattern.spec.whatwg.org/#dom-urlpattern-exec
Expand All @@ -294,48 +297,48 @@ class url_pattern {
const url_pattern_input& input, std::string_view* base_url_string);

// @see https://urlpattern.spec.whatwg.org/#dom-urlpattern-protocol
std::string_view get_protocol() const ada_lifetime_bound;
[[nodiscard]] std::string_view get_protocol() const ada_lifetime_bound;
// @see https://urlpattern.spec.whatwg.org/#dom-urlpattern-username
std::string_view get_username() const ada_lifetime_bound;
[[nodiscard]] std::string_view get_username() const ada_lifetime_bound;
// @see https://urlpattern.spec.whatwg.org/#dom-urlpattern-password
std::string_view get_password() const ada_lifetime_bound;
[[nodiscard]] std::string_view get_password() const ada_lifetime_bound;
// @see https://urlpattern.spec.whatwg.org/#dom-urlpattern-hostname
std::string_view get_hostname() const ada_lifetime_bound;
[[nodiscard]] std::string_view get_hostname() const ada_lifetime_bound;
// @see https://urlpattern.spec.whatwg.org/#dom-urlpattern-port
std::string_view get_port() const ada_lifetime_bound;
[[nodiscard]] std::string_view get_port() const ada_lifetime_bound;
// @see https://urlpattern.spec.whatwg.org/#dom-urlpattern-pathname
std::string_view get_pathname() const ada_lifetime_bound;
[[nodiscard]] std::string_view get_pathname() const ada_lifetime_bound;
// @see https://urlpattern.spec.whatwg.org/#dom-urlpattern-search
std::string_view get_search() const ada_lifetime_bound;
[[nodiscard]] std::string_view get_search() const ada_lifetime_bound;
// @see https://urlpattern.spec.whatwg.org/#dom-urlpattern-hash
std::string_view get_hash() const ada_lifetime_bound;
[[nodiscard]] std::string_view get_hash() const ada_lifetime_bound;

// 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;
[[nodiscard]] bool ignore_case() const;

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

std::string to_string() const;
[[nodiscard]] std::string to_string() const;

url_pattern_component protocol_component{};
url_pattern_component username_component{};
url_pattern_component password_component{};
url_pattern_component hostname_component{};
url_pattern_component port_component{};
url_pattern_component pathname_component{};
url_pattern_component search_component{};
url_pattern_component hash_component{};
url_pattern_component<regex_provider, regex_type> protocol_component{};
url_pattern_component<regex_provider, regex_type> username_component{};
url_pattern_component<regex_provider, regex_type> password_component{};
url_pattern_component<regex_provider, regex_type> hostname_component{};
url_pattern_component<regex_provider, regex_type> port_component{};
url_pattern_component<regex_provider, regex_type> pathname_component{};
url_pattern_component<regex_provider, regex_type> search_component{};
url_pattern_component<regex_provider, regex_type> hash_component{};
bool ignore_case_ = false;
url_pattern_regex::provider regex_provider_;
regex_provider regex_provider_;

template <typename result_type, typename url_pattern_init,
typename url_pattern_options>
typename url_pattern_options, typename regex_provider_>
friend tl::expected<result_type, errors> parser::parse_url_pattern_impl(
std::variant<std::string_view, url_pattern_init> input,
const std::string_view* base_url, const url_pattern_options* options,
url_pattern_regex::provider&& regex_provider);
regex_provider_&& provider);
};

} // namespace ada
Expand Down
Loading