Skip to content

Commit c4141be

Browse files
committed
feat: add url_search_params constructor
1 parent f4dfec9 commit c4141be

File tree

3 files changed

+79
-3
lines changed

3 files changed

+79
-3
lines changed

include/ada/url_search_params-inl.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,47 @@
1818

1919
namespace ada {
2020

21+
inline void url_search_params::initialize(std::string_view input) {
22+
if (input.front() == '?') {
23+
input.remove_prefix(1);
24+
}
25+
26+
auto process_key_value = [&](const std::string_view current) {
27+
auto equal = current.find_first_of("=");
28+
29+
if (equal == std::string_view::npos) {
30+
params.emplace_back(current, "");
31+
} else {
32+
auto plain_name = current.substr(0, equal);
33+
auto plain_value = current.substr(equal + 1);
34+
auto name =
35+
unicode::percent_decode(plain_name, plain_name.find_first_of('%'));
36+
auto value =
37+
unicode::percent_decode(plain_value, plain_value.find_first_of('%'));
38+
39+
std::replace(name.begin(), name.end(), '+', ' ');
40+
std::replace(value.begin(), value.end(), '+', ' ');
41+
42+
params.emplace_back(name, value);
43+
}
44+
};
45+
46+
while (!input.empty()) {
47+
auto ampersand_index = input.find_first_of("&");
48+
49+
if (ampersand_index == std::string_view::npos) {
50+
if (!input.empty()) {
51+
process_key_value(input);
52+
}
53+
break;
54+
} else if (ampersand_index != 0) {
55+
process_key_value(input.substr(0, ampersand_index));
56+
}
57+
58+
input.remove_prefix(ampersand_index + 1);
59+
}
60+
}
61+
2162
inline void url_search_params::append(const std::string_view key,
2263
const std::string_view value) {
2364
params.emplace_back(key, value);

include/ada/url_search_params.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,14 @@ namespace ada {
1616
* @see https://url.spec.whatwg.org/#interface-urlsearchparams
1717
*/
1818
struct url_search_params {
19-
// TODO: Add missing constructors
20-
// Add tests from
21-
// https://github.com/web-platform-tests/wpt/blob/master/url/urlsearchparams-constructor.any.js
2219
url_search_params() = default;
20+
21+
/**
22+
* @see
23+
* https://github.com/web-platform-tests/wpt/blob/master/url/urlsearchparams-constructor.any.js
24+
*/
25+
url_search_params(const std::string_view input) { initialize(input); }
26+
2327
url_search_params(const url_search_params &u) = default;
2428
url_search_params(url_search_params &&u) noexcept = default;
2529
url_search_params &operator=(url_search_params &&u) noexcept = default;
@@ -72,6 +76,11 @@ struct url_search_params {
7276
private:
7377
typedef std::pair<std::string, std::string> key_value_pair;
7478
std::vector<key_value_pair> params{};
79+
80+
/**
81+
* @see https://url.spec.whatwg.org/#concept-urlencoded-parser
82+
*/
83+
void initialize(std::string_view init);
7584
}; // url_search_params
7685

7786
} // namespace ada

tests/url_search_params.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,29 @@ TEST(url_search_params, sort) {
109109
ASSERT_EQ(search_params.to_string(), "aaa=first&bbb=second&ccc=third");
110110
SUCCEED();
111111
}
112+
113+
TEST(url_search_params, string_constructor) {
114+
auto p = ada::url_search_params("?a=b");
115+
ASSERT_EQ(p.to_string(), "a=b");
116+
SUCCEED();
117+
}
118+
119+
TEST(url_search_params, string_constructor_without_value) {
120+
auto p = ada::url_search_params("a=b&c");
121+
ASSERT_EQ(p.to_string(), "a=b&c=");
122+
SUCCEED();
123+
}
124+
125+
// Taken from
126+
// https://github.com/web-platform-tests/wpt/blob/master/url/urlsearchparams-constructor.any.js
127+
TEST(url_search_params, string_constructor_with_edge_cases) {
128+
auto p = ada::url_search_params("&a&&& &&&&&a+b=& c&m%c3%b8%c3%b8");
129+
p.to_string();
130+
ASSERT_TRUE(p.has("a"));
131+
ASSERT_TRUE(p.has("a b"));
132+
ASSERT_TRUE(p.has(" "));
133+
ASSERT_TRUE(!p.has("c"));
134+
ASSERT_TRUE(p.has(" c"));
135+
ASSERT_TRUE(p.has("møø"));
136+
SUCCEED();
137+
}

0 commit comments

Comments
 (0)