Skip to content

Commit

Permalink
make progress
Browse files Browse the repository at this point in the history
  • Loading branch information
anonrig committed Jan 20, 2025
1 parent ee9559b commit 74f6cc3
Show file tree
Hide file tree
Showing 14 changed files with 359 additions and 180 deletions.
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

0 comments on commit 74f6cc3

Please sign in to comment.