Skip to content

Commit eaffbd4

Browse files
committed
move implementation to header files
1 parent 57d3866 commit eaffbd4

22 files changed

+961
-941
lines changed

include/ada.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66
#define ADA_H
77

88
#include "ada/ada_idna.h"
9+
#include "ada/character_sets.h"
910
#include "ada/character_sets-inl.h"
1011
#include "ada/checkers-inl.h"
1112
#include "ada/common_defs.h"
1213
#include "ada/log.h"
1314
#include "ada/encoding_type.h"
1415
#include "ada/helpers.h"
1516
#include "ada/parser.h"
17+
#include "ada/parser-inl.h"
18+
#include "ada/scheme.h"
1619
#include "ada/scheme-inl.h"
1720
#include "ada/serializers.h"
1821
#include "ada/state.h"
@@ -35,5 +38,6 @@
3538
// Public API
3639
#include "ada/ada_version.h"
3740
#include "ada/implementation.h"
41+
#include "ada/implementation-inl.h"
3842

3943
#endif // ADA_H

include/ada/helpers.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#define ADA_HELPERS_H
77

88
#include "ada/common_defs.h"
9-
#include "ada/state.h"
109
#include "ada/url_base.h"
1110

1211
#include <string_view>

include/ada/implementation-inl.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* @file implementation-inl.h
3+
*/
4+
#ifndef ADA_IMPLEMENTATION_INL_H
5+
#define ADA_IMPLEMENTATION_INL_H
6+
7+
#include "ada/url_pattern_regex.h"
8+
#include "ada/expected.h"
9+
#include "ada/implementation.h"
10+
11+
namespace ada {
12+
13+
template <url_pattern_regex::regex_concept regex_provider>
14+
ada_warn_unused tl::expected<url_pattern<regex_provider>, errors>
15+
parse_url_pattern(std::variant<std::string_view, url_pattern_init> input,
16+
const std::string_view* base_url,
17+
const url_pattern_options* options,
18+
std::optional<regex_provider> provider) {
19+
return parser::parse_url_pattern_impl<regex_provider>(
20+
std::move(input), base_url, options,
21+
provider.value_or(url_pattern_regex::std_regex_provider()));
22+
}
23+
24+
} // namespace ada
25+
26+
#endif // ADA_IMPLEMENTATION_INL_H

include/ada/implementation.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,11 @@
66
#ifndef ADA_IMPLEMENTATION_H
77
#define ADA_IMPLEMENTATION_H
88

9-
#include <string>
9+
#include <string_view>
1010
#include <optional>
1111

12-
#include "ada/parser.h"
13-
#include "ada/common_defs.h"
1412
#include "ada/url.h"
15-
#include "ada/url_pattern_regex.h"
13+
#include "ada/common_defs.h"
1614

1715
namespace ada {
1816
enum class errors : uint8_t { type_error };
@@ -54,7 +52,7 @@ bool can_parse(std::string_view input,
5452
* @param input valid UTF-8 string or URLPatternInit struct
5553
* @param base_url an optional valid UTF-8 string
5654
* @param options an optional url_pattern_options struct
57-
* @param regex_provider an optional regex provider. if not provided, it will
55+
* @param provider an optional regex provider. if not provided, it will
5856
* use ada::url_pattern_regex::std_regex_provider
5957
* @return url_pattern instance
6058
*/

include/ada/parser-inl.h

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
/**
2+
* @file parser-inl.h
3+
*/
4+
#ifndef ADA_PARSER_INL_H
5+
#define ADA_PARSER_INL_H
6+
7+
#include "ada/expected.h"
8+
#include "ada/url_pattern.h"
9+
#include "ada/url_pattern_helpers.h"
10+
11+
namespace ada::parser {
12+
template <url_pattern_regex::regex_concept regex_provider>
13+
tl::expected<url_pattern<regex_provider>, errors> parse_url_pattern_impl(
14+
std::variant<std::string_view, url_pattern_init> input,
15+
const std::string_view* base_url, const url_pattern_options* options,
16+
regex_provider&& provider) {
17+
// Let init be null.
18+
url_pattern_init init;
19+
20+
// If input is a scalar value string then:
21+
if (std::holds_alternative<std::string_view>(input)) {
22+
// Set init to the result of running parse a constructor string given input.
23+
auto parse_result =
24+
url_pattern_helpers::constructor_string_parser<regex_provider>::parse(
25+
std::get<std::string_view>(input), provider);
26+
if (!parse_result) {
27+
ada_log("constructor_string_parser::parse failed");
28+
return tl::unexpected(parse_result.error());
29+
}
30+
init = std::move(*parse_result);
31+
// If baseURL is null and init["protocol"] does not exist, then throw a
32+
// TypeError.
33+
if (!base_url && !init.protocol) {
34+
ada_log("base url is null and protocol is not set");
35+
return tl::unexpected(errors::type_error);
36+
}
37+
38+
// If baseURL is not null, set init["baseURL"] to baseURL.
39+
if (base_url) {
40+
init.base_url = std::string(*base_url);
41+
}
42+
} else {
43+
// Assert: input is a URLPatternInit.
44+
ADA_ASSERT_TRUE(std::holds_alternative<url_pattern_init>(input));
45+
// If baseURL is not null, then throw a TypeError.
46+
if (base_url) {
47+
ada_log("base url is not null");
48+
return tl::unexpected(errors::type_error);
49+
}
50+
// Optimization: Avoid copy by moving the input value.
51+
// Set init to input.
52+
init = std::move(std::get<url_pattern_init>(input));
53+
}
54+
55+
// Let processedInit be the result of process a URLPatternInit given init,
56+
// "pattern", null, null, null, null, null, null, null, and null.
57+
// TODO: Make "pattern" an enum to avoid creating a string everytime.
58+
auto processed_init = url_pattern_init::process(init, "pattern");
59+
if (!processed_init) {
60+
ada_log("url_pattern_init::process failed for init and 'pattern'");
61+
return tl::unexpected(processed_init.error());
62+
}
63+
64+
// For each componentName of « "protocol", "username", "password", "hostname",
65+
// "port", "pathname", "search", "hash" If processedInit[componentName] does
66+
// not exist, then set processedInit[componentName] to "*".
67+
ADA_ASSERT_TRUE(processed_init.has_value());
68+
if (!processed_init->protocol) processed_init->protocol = "*";
69+
if (!processed_init->username) processed_init->username = "*";
70+
if (!processed_init->password) processed_init->password = "*";
71+
if (!processed_init->hostname) processed_init->hostname = "*";
72+
if (!processed_init->port) processed_init->port = "*";
73+
if (!processed_init->pathname) processed_init->pathname = "*";
74+
if (!processed_init->search) processed_init->search = "*";
75+
if (!processed_init->hash) processed_init->hash = "*";
76+
77+
ada_log("-- processed_init->protocol: ", processed_init->protocol.value());
78+
ada_log("-- processed_init->username: ", processed_init->username.value());
79+
ada_log("-- processed_init->password: ", processed_init->password.value());
80+
ada_log("-- processed_init->hostname: ", processed_init->hostname.value());
81+
ada_log("-- processed_init->port: ", processed_init->port.value());
82+
ada_log("-- processed_init->pathname: ", processed_init->pathname.value());
83+
ada_log("-- processed_init->search: ", processed_init->search.value());
84+
ada_log("-- processed_init->hash: ", processed_init->hash.value());
85+
86+
// If processedInit["protocol"] is a special scheme and processedInit["port"]
87+
// is a string which represents its corresponding default port in radix-10
88+
// using ASCII digits then set processedInit["port"] to the empty string.
89+
// TODO: Optimization opportunity.
90+
if (scheme::is_special(*processed_init->protocol)) {
91+
std::string_view port = processed_init->port.value();
92+
helpers::trim_c0_whitespace(port);
93+
if (std::to_string(scheme::get_special_port(*processed_init->protocol)) ==
94+
port) {
95+
processed_init->port->clear();
96+
}
97+
}
98+
99+
// Let urlPattern be a new URL pattern.
100+
url_pattern<regex_provider> url_pattern_(std::move(provider));
101+
102+
// Set urlPattern’s protocol component to the result of compiling a component
103+
// given processedInit["protocol"], canonicalize a protocol, and default
104+
// options.
105+
auto protocol_component = url_pattern_component<regex_provider>::compile(
106+
processed_init->protocol.value(),
107+
url_pattern_helpers::canonicalize_protocol,
108+
url_pattern_compile_component_options::DEFAULT, provider);
109+
if (!protocol_component) {
110+
ada_log("url_pattern_component::compile failed for protocol ",
111+
processed_init->protocol.value());
112+
return tl::unexpected(protocol_component.error());
113+
}
114+
url_pattern_.protocol_component = std::move(*protocol_component);
115+
116+
// Set urlPattern’s username component to the result of compiling a component
117+
// given processedInit["username"], canonicalize a username, and default
118+
// options.
119+
auto username_component = url_pattern_component<regex_provider>::compile(
120+
processed_init->username.value(),
121+
url_pattern_helpers::canonicalize_username,
122+
url_pattern_compile_component_options::DEFAULT, provider);
123+
if (!username_component) {
124+
ada_log("url_pattern_component::compile failed for username ",
125+
processed_init->username.value());
126+
return tl::unexpected(username_component.error());
127+
}
128+
url_pattern_.username_component = std::move(*username_component);
129+
130+
// Set urlPattern’s password component to the result of compiling a component
131+
// given processedInit["password"], canonicalize a password, and default
132+
// options.
133+
auto password_component = url_pattern_component<regex_provider>::compile(
134+
processed_init->password.value(),
135+
url_pattern_helpers::canonicalize_password,
136+
url_pattern_compile_component_options::DEFAULT, provider);
137+
if (!password_component) {
138+
ada_log("url_pattern_component::compile failed for password ",
139+
processed_init->password.value());
140+
return tl::unexpected(password_component.error());
141+
}
142+
url_pattern_.password_component = std::move(*password_component);
143+
144+
// TODO: Optimization opportunity. The following if statement can be
145+
// simplified.
146+
// If the result running hostname pattern is an IPv6 address given
147+
// processedInit["hostname"] is true, then set urlPattern’s hostname component
148+
// to the result of compiling a component given processedInit["hostname"],
149+
// canonicalize an IPv6 hostname, and hostname options.
150+
if (url_pattern_helpers::is_ipv6_address(processed_init->hostname.value())) {
151+
ada_log("processed_init->hostname is ipv6 address");
152+
// then set urlPattern’s hostname component to the result of compiling a
153+
// component given processedInit["hostname"], canonicalize an IPv6 hostname,
154+
// and hostname options.
155+
auto hostname_component = url_pattern_component<regex_provider>::compile(
156+
processed_init->hostname.value(),
157+
url_pattern_helpers::canonicalize_ipv6_hostname,
158+
url_pattern_compile_component_options::DEFAULT, provider);
159+
if (!hostname_component) {
160+
ada_log("url_pattern_component::compile failed for ipv6 hostname ",
161+
processed_init->hostname.value());
162+
return tl::unexpected(hostname_component.error());
163+
}
164+
url_pattern_.hostname_component = std::move(*hostname_component);
165+
} else {
166+
// Otherwise, set urlPattern’s hostname component to the result of compiling
167+
// a component given processedInit["hostname"], canonicalize a hostname, and
168+
// hostname options.
169+
auto hostname_component = url_pattern_component<regex_provider>::compile(
170+
processed_init->hostname.value(),
171+
url_pattern_helpers::canonicalize_hostname,
172+
url_pattern_compile_component_options::HOSTNAME, provider);
173+
if (!hostname_component) {
174+
ada_log("url_pattern_component::compile failed for hostname ",
175+
processed_init->hostname.value());
176+
return tl::unexpected(hostname_component.error());
177+
}
178+
url_pattern_.hostname_component = std::move(*hostname_component);
179+
}
180+
181+
// Set urlPattern’s port component to the result of compiling a component
182+
// given processedInit["port"], canonicalize a port, and default options.
183+
auto port_component = url_pattern_component<regex_provider>::compile(
184+
processed_init->port.value(), url_pattern_helpers::canonicalize_port,
185+
url_pattern_compile_component_options::DEFAULT, provider);
186+
if (!port_component) {
187+
ada_log("url_pattern_component::compile failed for port ",
188+
processed_init->port.value());
189+
return tl::unexpected(port_component.error());
190+
}
191+
url_pattern_.port_component = std::move(*port_component);
192+
193+
// Let compileOptions be a copy of the default options with the ignore case
194+
// property set to options["ignoreCase"].
195+
auto compile_options = url_pattern_compile_component_options::DEFAULT;
196+
if (options) {
197+
compile_options.ignore_case = options->ignore_case;
198+
}
199+
200+
// TODO: Optimization opportunity: Simplify this if statement.
201+
// If the result of running protocol component matches a special scheme given
202+
// urlPattern’s protocol component is true, then:
203+
if (url_pattern_helpers::protocol_component_matches_special_scheme<
204+
regex_provider>(url_pattern_.protocol_component)) {
205+
// Let pathCompileOptions be copy of the pathname options with the ignore
206+
// case property set to options["ignoreCase"].
207+
auto path_compile_options = url_pattern_compile_component_options::PATHNAME;
208+
if (options) {
209+
path_compile_options.ignore_case = options->ignore_case;
210+
}
211+
212+
// Set urlPattern’s pathname component to the result of compiling a
213+
// component given processedInit["pathname"], canonicalize a pathname, and
214+
// pathCompileOptions.
215+
auto pathname_component = url_pattern_component<regex_provider>::compile(
216+
processed_init->pathname.value(),
217+
url_pattern_helpers::canonicalize_pathname, path_compile_options,
218+
provider);
219+
if (!pathname_component) {
220+
ada_log("url_pattern_component::compile failed for pathname ",
221+
processed_init->pathname.value());
222+
return tl::unexpected(pathname_component.error());
223+
}
224+
url_pattern_.pathname_component = std::move(*pathname_component);
225+
} else {
226+
// Otherwise set urlPattern’s pathname component to the result of compiling
227+
// a component given processedInit["pathname"], canonicalize an opaque
228+
// pathname, and compileOptions.
229+
auto pathname_component = url_pattern_component<regex_provider>::compile(
230+
processed_init->pathname.value(),
231+
url_pattern_helpers::canonicalize_opaque_pathname, compile_options,
232+
provider);
233+
if (!pathname_component) {
234+
ada_log("url_pattern_component::compile failed for opaque pathname ",
235+
processed_init->pathname.value());
236+
return tl::unexpected(pathname_component.error());
237+
}
238+
url_pattern_.pathname_component = std::move(*pathname_component);
239+
}
240+
241+
// Set urlPattern’s search component to the result of compiling a component
242+
// given processedInit["search"], canonicalize a search, and compileOptions.
243+
auto search_component = url_pattern_component<regex_provider>::compile(
244+
processed_init->search.value(), url_pattern_helpers::canonicalize_search,
245+
compile_options, provider);
246+
if (!search_component) {
247+
ada_log("url_pattern_component::compile failed for search ",
248+
processed_init->search.value());
249+
return tl::unexpected(search_component.error());
250+
}
251+
url_pattern_.search_component = std::move(*search_component);
252+
253+
// Set urlPattern’s hash component to the result of compiling a component
254+
// given processedInit["hash"], canonicalize a hash, and compileOptions.
255+
auto hash_component = url_pattern_component<regex_provider>::compile(
256+
processed_init->hash.value(), url_pattern_helpers::canonicalize_hash,
257+
compile_options, provider);
258+
if (!hash_component) {
259+
ada_log("url_pattern_component::compile failed for hash ",
260+
processed_init->hash.value());
261+
return tl::unexpected(hash_component.error());
262+
}
263+
url_pattern_.hash_component = std::move(*hash_component);
264+
265+
// Return urlPattern.
266+
return url_pattern_;
267+
}
268+
269+
template tl::expected<url_pattern<url_pattern_regex::std_regex_provider>,
270+
errors>
271+
parse_url_pattern_impl(std::variant<std::string_view, url_pattern_init> input,
272+
const std::string_view* base_url,
273+
const url_pattern_options* options,
274+
url_pattern_regex::std_regex_provider&& provider);
275+
} // namespace ada::parser
276+
277+
#endif // ADA_PARSER_INL_H

include/ada/parser.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* @private
1616
*/
1717
namespace ada {
18-
struct url_aggregator;
18+
class url_aggregator;
1919
struct url;
2020
template <url_pattern_regex::regex_concept regex_provider>
2121
class url_pattern;
@@ -59,6 +59,13 @@ tl::expected<url_pattern<regex_provider>, errors> parse_url_pattern_impl(
5959
const std::string_view* base_url, const url_pattern_options* options,
6060
regex_provider&& provider);
6161

62+
extern template tl::expected<url_pattern<url_pattern_regex::std_regex_provider>,
63+
errors>
64+
parse_url_pattern_impl(std::variant<std::string_view, url_pattern_init> input,
65+
const std::string_view* base_url,
66+
const url_pattern_options* options,
67+
url_pattern_regex::std_regex_provider&& provider);
68+
6269
} // namespace ada::parser
6370

6471
#endif // ADA_PARSER_H

include/ada/scheme.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
#include "ada/common_defs.h"
99

10-
#include <array>
1110
#include <string>
1211

1312
/**

0 commit comments

Comments
 (0)