5#ifndef ADA_URL_PATTERN_INL_H
6#define ADA_URL_PATTERN_INL_H
16#if ADA_INCLUDE_URL_PATTERN
19inline bool url_pattern_init::operator==(
const url_pattern_init& other)
const {
20 return protocol == other.protocol && username == other.username &&
21 password == other.password && hostname == other.hostname &&
22 port == other.port && search == other.search && hash == other.hash &&
23 pathname == other.pathname;
26inline bool url_pattern_component_result::operator==(
27 const url_pattern_component_result& other)
const {
28 return input == other.input && groups == other.groups;
31template <url_pattern_regex::regex_concept regex_prov
ider>
32url_pattern_component_result
33url_pattern_component<regex_provider>::create_component_match_result(
35 std::vector<std::optional<std::string>>&& exec_result) {
40 url_pattern_component_result{.input = std::move(input), .groups = {}};
43 result.groups.reserve(exec_result.size());
48 for (
size_t index = 0; index < exec_result.size(); index++) {
50 group_name_list[index],
51 std::move(exec_result[index]),
57template <url_pattern_regex::regex_concept regex_prov
ider>
58std::string_view url_pattern<regex_provider>::get_protocol() const
61 return protocol_component.pattern;
63template <url_pattern_regex::regex_concept regex_prov
ider>
64std::string_view url_pattern<regex_provider>::get_username() const
67 return username_component.pattern;
69template <url_pattern_regex::regex_concept regex_prov
ider>
70std::string_view url_pattern<regex_provider>::get_password() const
73 return password_component.pattern;
75template <url_pattern_regex::regex_concept regex_prov
ider>
76std::string_view url_pattern<regex_provider>::get_hostname() const
79 return hostname_component.pattern;
81template <url_pattern_regex::regex_concept regex_prov
ider>
82std::string_view url_pattern<regex_provider>::get_port() const
85 return port_component.pattern;
87template <url_pattern_regex::regex_concept regex_prov
ider>
88std::string_view url_pattern<regex_provider>::get_pathname() const
91 return pathname_component.pattern;
93template <url_pattern_regex::regex_concept regex_prov
ider>
94std::string_view url_pattern<regex_provider>::get_search() const
97 return search_component.pattern;
99template <url_pattern_regex::regex_concept regex_prov
ider>
100std::string_view url_pattern<regex_provider>::get_hash() const
103 return hash_component.pattern;
105template <url_pattern_regex::regex_concept regex_prov
ider>
106bool url_pattern<regex_provider>::ignore_case()
const {
109template <url_pattern_regex::regex_concept regex_prov
ider>
110bool url_pattern<regex_provider>::has_regexp_groups()
const {
112 return protocol_component.has_regexp_groups ||
113 username_component.has_regexp_groups ||
114 password_component.has_regexp_groups ||
115 hostname_component.has_regexp_groups ||
116 port_component.has_regexp_groups ||
117 pathname_component.has_regexp_groups ||
118 search_component.has_regexp_groups || hash_component.has_regexp_groups;
121inline bool url_pattern_part::is_regexp() const noexcept {
122 return type == url_pattern_part_type::REGEXP;
125inline std::string_view url_pattern_compile_component_options::get_delimiter()
128 return {&delimiter.value(), 1};
133inline std::string_view url_pattern_compile_component_options::get_prefix()
136 return {&prefix.value(), 1};
141template <url_pattern_regex::regex_concept regex_prov
ider>
142template <url_pattern_encoding_callback F>
143tl::expected<url_pattern_component<regex_provider>,
errors>
144url_pattern_component<regex_provider>::compile(
145 std::string_view input, F& encoding_callback,
146 url_pattern_compile_component_options& options) {
147 ada_log(
"url_pattern_component::compile input: ", input);
150 auto part_list = url_pattern_helpers::parse_pattern_string(input, options,
154 ada_log(
"parse_pattern_string failed");
155 return tl::unexpected(part_list.error());
160 auto [regular_expression_string, name_list] =
161 url_pattern_helpers::generate_regular_expression_and_name_list(*part_list,
164 ada_log(
"regular expression string: ", regular_expression_string);
168 auto pattern_string =
169 url_pattern_helpers::generate_pattern_string(*part_list, options);
174 std::optional<typename regex_provider::regex_type> regular_expression =
175 regex_provider::create_instance(regular_expression_string,
176 options.ignore_case);
178 if (!regular_expression) {
184 const auto has_regexp = [](
const auto& part) {
return part.is_regexp(); };
185 const bool has_regexp_groups = std::ranges::any_of(*part_list, has_regexp);
187 ada_log(
"has regexp groups: ", has_regexp_groups);
192 return url_pattern_component<regex_provider>(
193 std::move(pattern_string), std::move(*regular_expression),
194 std::move(name_list), has_regexp_groups);
197template <url_pattern_regex::regex_concept regex_prov
ider>
199 const url_pattern_input& input,
const std::string_view* base_url) {
202 return match(input, base_url);
205template <url_pattern_regex::regex_concept regex_prov
ider>
207 const url_pattern_input& input,
const std::string_view* base_url) {
213 if (
auto result = match(input, base_url);
result.has_value()) {
214 return result->has_value();
219template <url_pattern_regex::regex_concept regex_prov
ider>
221 const url_pattern_input& input,
const std::string_view* base_url_string) {
222 std::string protocol{};
223 std::string username{};
224 std::string password{};
225 std::string hostname{};
227 std::string pathname{};
228 std::string search{};
233 std::vector inputs{input};
236 if (std::holds_alternative<url_pattern_init>(input)) {
238 "url_pattern::match called with url_pattern_init and base_url_string=",
241 if (base_url_string) {
242 ada_log(
"failed to match because base_url_string was given");
249 auto apply_result = url_pattern_init::process(
250 std::get<url_pattern_init>(input), url_pattern_init::process_type::url,
251 protocol, username, password, hostname, port, pathname, search, hash);
254 if (!apply_result.has_value()) {
255 ada_log(
"match returned std::nullopt because process threw");
261 protocol = std::move(apply_result->protocol.value());
265 username = std::move(apply_result->username.value());
269 password = std::move(apply_result->password.value());
273 hostname = std::move(apply_result->hostname.value());
277 port = std::move(apply_result->port.value());
281 pathname = std::move(apply_result->pathname.value());
285 if (apply_result->search->starts_with(
"?")) {
286 search = apply_result->search->substr(1);
288 search = std::move(apply_result->search.value());
294 hash = std::move(apply_result->hash.value());
302 if (base_url_string) {
308 ada_log(
"match returned std::nullopt because failed to parse base_url=",
314 inputs.emplace_back(*base_url_string);
318 base_url.has_value() ? &*base_url :
nullptr;
326 ada_log(
"match returned std::nullopt because url failed");
353 search = view.starts_with(
"?") ?
url->
get_search().substr(1) : view;
361 hash = view.starts_with(
"#") ?
url->
get_hash().substr(1) : view;
367 auto protocol_exec_result =
368 regex_provider::regex_search(protocol, protocol_component.regexp);
370 if (!protocol_exec_result) {
376 auto username_exec_result =
377 regex_provider::regex_search(username, username_component.regexp);
379 if (!username_exec_result) {
385 auto password_exec_result =
386 regex_provider::regex_search(password, password_component.regexp);
388 if (!password_exec_result) {
394 auto hostname_exec_result =
395 regex_provider::regex_search(hostname, hostname_component.regexp);
397 if (!hostname_exec_result) {
403 auto port_exec_result =
404 regex_provider::regex_search(port, port_component.regexp);
406 if (!port_exec_result) {
412 auto pathname_exec_result =
413 regex_provider::regex_search(pathname, pathname_component.regexp);
415 if (!pathname_exec_result) {
421 auto search_exec_result =
422 regex_provider::regex_search(search, search_component.regexp);
424 if (!search_exec_result) {
430 auto hash_exec_result =
431 regex_provider::regex_search(hash, hash_component.regexp);
433 if (!hash_exec_result) {
438 auto result = url_pattern_result{};
440 result.inputs = std::move(inputs);
443 result.protocol = protocol_component.create_component_match_result(
444 std::move(protocol), std::move(*protocol_exec_result));
448 result.username = username_component.create_component_match_result(
449 std::move(username), std::move(*username_exec_result));
453 result.password = password_component.create_component_match_result(
454 std::move(password), std::move(*password_exec_result));
458 result.hostname = hostname_component.create_component_match_result(
459 std::move(hostname), std::move(*hostname_exec_result));
463 result.port = port_component.create_component_match_result(
464 std::move(port), std::move(*port_exec_result));
468 result.pathname = pathname_component.create_component_match_result(
469 std::move(pathname), std::move(*pathname_exec_result));
473 result.search = search_component.create_component_match_result(
474 std::move(search), std::move(*search_exec_result));
478 result.hash = hash_component.create_component_match_result(
479 std::move(hash), std::move(*hash_exec_result));
Common definitions for cross-platform compiler support.
#define ADA_ASSERT_TRUE(COND)
#define ada_lifetime_bound
template ada::result< url_aggregator > parse< url_aggregator >(std::string_view input, const url_aggregator *base_url)
tl::expected< result_type, ada::errors > result
Generic URL struct reliant on std::string instantiation.
std::string get_search() const noexcept
constexpr std::string_view get_pathname() const noexcept
std::string get_hash() const noexcept
std::string get_hostname() const noexcept
const std::string & get_password() const noexcept
std::string get_port() const noexcept
const std::string & get_username() const noexcept
constexpr bool has_search() const noexcept override
std::string get_protocol() const noexcept
constexpr bool has_hash() const noexcept override
Declaration for the URLPattern implementation.
Declaration for the URLPattern helpers.