12#ifndef ADA_URL_PATTERN_H
13#define ADA_URL_PATTERN_H
16#include "ada/expected.h"
23#include <unordered_map>
31#if ADA_INCLUDE_URL_PATTERN
34enum class url_pattern_part_type : uint8_t {
50enum class url_pattern_component_type : uint8_t {
61enum class url_pattern_part_modifier : uint8_t {
75class url_pattern_part {
77 url_pattern_part(url_pattern_part_type _type, std::string&& _value,
78 url_pattern_part_modifier _modifier)
79 :
type(_type), value(std::move(_value)), modifier(_modifier) {}
81 url_pattern_part(url_pattern_part_type _type, std::string&& _value,
82 url_pattern_part_modifier _modifier, std::string&& _name,
83 std::string&& _prefix, std::string&& _suffix)
85 value(std::move(_value)),
87 name(std::move(_name)),
88 prefix(std::move(_prefix)),
89 suffix(std::move(_suffix)) {}
91 url_pattern_part_type
type;
96 url_pattern_part_modifier modifier;
100 std::string prefix{};
102 std::string suffix{};
104 inline bool is_regexp() const noexcept;
108struct url_pattern_compile_component_options {
109 url_pattern_compile_component_options() =
default;
110 explicit url_pattern_compile_component_options(
111 std::optional<char> new_delimiter = std::nullopt,
112 std::optional<char> new_prefix = std::nullopt)
113 : delimiter(new_delimiter), prefix(new_prefix) {}
119 bool ignore_case = false;
121 static url_pattern_compile_component_options DEFAULT;
122 static url_pattern_compile_component_options HOSTNAME;
123 static url_pattern_compile_component_options PATHNAME;
127 std::optional<
char> delimiter{};
129 std::optional<char> prefix{};
134inline url_pattern_compile_component_options
135 url_pattern_compile_component_options::DEFAULT(std::nullopt, std::nullopt);
139inline url_pattern_compile_component_options
140 url_pattern_compile_component_options::HOSTNAME(
'.', std::nullopt);
144inline url_pattern_compile_component_options
145 url_pattern_compile_component_options::PATHNAME(
'/',
'/');
152struct url_pattern_component_result {
154 std::unordered_map<std::string, std::optional<std::string>> groups;
156 bool operator==(
const url_pattern_component_result&)
const;
159 friend void PrintTo(
const url_pattern_component_result& result,
161 *os <<
"input: '" <<
result.input <<
"', group: ";
162 for (
const auto& group :
result.groups) {
163 *os <<
"(" << group.first <<
", " << group.second.value_or(
"undefined")
170template <url_pattern_regex::regex_concept regex_prov
ider>
171class url_pattern_component {
173 url_pattern_component() =
default;
177 url_pattern_component(std::string&& new_pattern,
178 typename regex_provider::regex_type&& new_regexp,
179 std::vector<std::string>&& new_group_name_list,
180 bool new_has_regexp_groups,
181 url_pattern_component_type new_type,
182 std::string&& new_exact_match_value = {})
183 : regexp(std::move(new_regexp)),
184 pattern(std::move(new_pattern)),
185 group_name_list(std::move(new_group_name_list)),
186 exact_match_value(std::move(new_exact_match_value)),
187 has_regexp_groups(new_has_regexp_groups),
191 template <url_pattern_encoding_callback F>
192 static tl::expected<url_pattern_component, errors> compile(
193 std::string_view input, F& encoding_callback,
194 url_pattern_compile_component_options& options);
197 url_pattern_component_result create_component_match_result(
199 std::vector<std::optional<std::string>>&& exec_result);
203 bool fast_test(std::string_view input)
const noexcept;
208 std::optional<std::vector<std::optional<std::string>>> fast_match(
209 std::string_view input)
const;
212 friend void PrintTo(
const url_pattern_component& component,
214 *os <<
"pattern: '" << component.pattern
215 <<
"', has_regexp_groups: " << component.has_regexp_groups
216 <<
"group_name_list: ";
217 for (
const auto& name : component.group_name_list) {
223 typename regex_provider::regex_type regexp{};
224 std::string pattern{};
225 std::vector<std::string> group_name_list{};
227 std::string exact_match_value{};
228 bool has_regexp_groups =
false;
230 url_pattern_component_type
type = url_pattern_component_type::REGEXP;
235using url_pattern_input = std::variant<std::string_view, url_pattern_init>;
240struct url_pattern_result {
241 std::vector<url_pattern_input> inputs;
242 url_pattern_component_result protocol;
243 url_pattern_component_result username;
244 url_pattern_component_result password;
245 url_pattern_component_result hostname;
246 url_pattern_component_result port;
247 url_pattern_component_result pathname;
248 url_pattern_component_result search;
249 url_pattern_component_result hash;
252struct url_pattern_options {
253 bool ignore_case =
false;
256 friend void PrintTo(
const url_pattern_options& options, std::ostream* os) {
257 *os <<
"ignore_case: '" << options.ignore_case;
284template <url_pattern_regex::regex_concept regex_prov
ider>
287 url_pattern() =
default;
293 result<std::optional<url_pattern_result>> exec(
294 const url_pattern_input& input,
295 const std::string_view* base_url =
nullptr);
301 result<bool> test(
const url_pattern_input& input,
302 const std::string_view* base_url =
nullptr);
308 result<std::optional<url_pattern_result>> match(
309 const url_pattern_input& input,
310 const std::string_view* base_url_string =
nullptr);
331 [[nodiscard]]
bool ignore_case() const;
334 [[nodiscard]]
bool has_regexp_groups() const;
337 [[nodiscard]]
bool test_components(
338 std::string_view protocol, std::string_view username,
339 std::string_view password, std::string_view hostname,
340 std::string_view port, std::string_view pathname, std::string_view search,
341 std::string_view hash) const;
344 friend void PrintTo(
const url_pattern& c, std::ostream* os) {
345 *os <<
"protocol_component: '" << c.get_protocol() <<
", ";
346 *os <<
"username_component: '" << c.get_username() <<
", ";
347 *os <<
"password_component: '" << c.get_password() <<
", ";
348 *os <<
"hostname_component: '" << c.get_hostname() <<
", ";
349 *os <<
"port_component: '" << c.get_port() <<
", ";
350 *os <<
"pathname_component: '" << c.get_pathname() <<
", ";
351 *os <<
"search_component: '" << c.get_search() <<
", ";
352 *os <<
"hash_component: '" << c.get_hash();
356 template <url_pattern_regex::regex_concept P>
357 friend tl::expected<url_pattern<P>,
errors> parser::parse_url_pattern_impl(
358 std::variant<std::string_view, url_pattern_init>&& input,
359 const std::string_view* base_url,
const url_pattern_options* options);
366 url_pattern_component<regex_provider> protocol_component{};
372 url_pattern_component<regex_provider> username_component{};
378 url_pattern_component<regex_provider> password_component{};
384 url_pattern_component<regex_provider> hostname_component{};
390 url_pattern_component<regex_provider> port_component{};
396 url_pattern_component<regex_provider> pathname_component{};
402 url_pattern_component<regex_provider> search_component{};
408 url_pattern_component<regex_provider> hash_component{};
414 bool ignore_case_ =
false;
#define ada_lifetime_bound
User-facing functions for URL parsing and manipulation.
type
Enumeration of URL scheme types.
url_search_params url_search_params_iter< T, Type >::EMPTY
errors
Error codes for URL parsing operations.
tl::expected< result_type, ada::errors > result
Low-level URL parsing functions.
Declaration for the url_pattern_init implementation.