Skip to content

Commit b3edf4e

Browse files
committed
url: refactor URLPattern::{Exec,Test}
Refactor these `URLPattern` methods and extract common logic into a helper function, reducing code duplication. Signed-off-by: Tobias Nießen <tniessen@tnie.de>
1 parent 79def6d commit b3edf4e

2 files changed

Lines changed: 33 additions & 53 deletions

File tree

src/node_url_pattern.cc

Lines changed: 32 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,10 @@ using v8::FunctionCallbackInfo;
6060
using v8::FunctionTemplate;
6161
using v8::Global;
6262
using v8::Isolate;
63+
using v8::Just;
6364
using v8::Local;
6465
using v8::LocalVector;
66+
using v8::Maybe;
6567
using v8::MaybeLocal;
6668
using v8::Name;
6769
using v8::NewStringType;
@@ -556,25 +558,31 @@ MaybeLocal<Value> URLPattern::Exec(Environment* env,
556558
}
557559
return Null(env->isolate());
558560
}
561+
THROW_ERR_OPERATION_FAILED(env, "Failed to exec URLPattern");
559562
return {};
560563
}
561564

562-
bool URLPattern::Test(Environment* env,
563-
const ada::url_pattern_input& input,
564-
std::optional<std::string_view>& baseURL) {
565+
Maybe<bool> URLPattern::Test(Environment* env,
566+
const ada::url_pattern_input& input,
567+
std::optional<std::string_view>& baseURL) {
565568
if (auto result = url_pattern_.test(input, baseURL ? &*baseURL : nullptr)) {
566-
return *result;
569+
return Just(*result);
567570
}
568571
THROW_ERR_OPERATION_FAILED(env, "Failed to test URLPattern");
569-
return false;
572+
return {};
570573
}
571574

572-
// V8 Methods
573-
574-
void URLPattern::Exec(const FunctionCallbackInfo<Value>& args) {
575+
namespace {
576+
template <typename R,
577+
typename M,
578+
bool (M::*to_r)(R*) const,
579+
M (URLPattern::*func)(Environment*,
580+
const ada::url_pattern_input&,
581+
std::optional<std::string_view>&)>
582+
void ExecOrTest(const FunctionCallbackInfo<Value>& args) {
575583
URLPattern* url_pattern;
576584
ASSIGN_OR_RETURN_UNWRAP(&url_pattern, args.This());
577-
auto env = Environment::GetCurrent(args);
585+
Environment* env = Environment::GetCurrent(args);
578586

579587
ada::url_pattern_input input;
580588
std::optional<std::string> baseURL{};
@@ -586,7 +594,8 @@ void URLPattern::Exec(const FunctionCallbackInfo<Value>& args) {
586594
input_base = input_value.ToString();
587595
input = std::string_view(input_base);
588596
} else if (args[0]->IsObject()) {
589-
auto maybeInput = URLPatternInit::FromJsObject(env, args[0].As<Object>());
597+
auto maybeInput =
598+
URLPattern::URLPatternInit::FromJsObject(env, args[0].As<Object>());
590599
if (!maybeInput.has_value()) return;
591600
input = std::move(*maybeInput);
592601
} else {
@@ -607,55 +616,26 @@ void URLPattern::Exec(const FunctionCallbackInfo<Value>& args) {
607616
}
608617
}
609618

610-
Local<Value> result;
611619
std::optional<std::string_view> baseURL_opt =
612620
baseURL ? std::optional<std::string_view>(*baseURL) : std::nullopt;
613-
if (!url_pattern->Exec(env, input, baseURL_opt).ToLocal(&result)) {
614-
THROW_ERR_OPERATION_FAILED(env, "Failed to exec URLPattern");
615-
return;
621+
R result{};
622+
if (((url_pattern->*func)(env, input, baseURL_opt).*to_r)(&result)) {
623+
args.GetReturnValue().Set(result);
616624
}
617-
args.GetReturnValue().Set(result);
618625
}
626+
} // namespace
619627

620-
void URLPattern::Test(const FunctionCallbackInfo<Value>& args) {
621-
URLPattern* url_pattern;
622-
ASSIGN_OR_RETURN_UNWRAP(&url_pattern, args.This());
623-
auto env = Environment::GetCurrent(args);
624-
625-
ada::url_pattern_input input;
626-
std::optional<std::string> baseURL{};
627-
std::string input_base;
628-
if (args.Length() == 0 || args[0]->IsNullOrUndefined()) {
629-
input = ada::url_pattern_init{};
630-
} else if (args[0]->IsString()) {
631-
Utf8Value input_value(env->isolate(), args[0].As<String>());
632-
input_base = input_value.ToString();
633-
input = std::string_view(input_base);
634-
} else if (args[0]->IsObject()) {
635-
auto maybeInput = URLPatternInit::FromJsObject(env, args[0].As<Object>());
636-
if (!maybeInput.has_value()) return;
637-
input = std::move(*maybeInput);
638-
} else {
639-
THROW_ERR_INVALID_ARG_TYPE(
640-
env, "URLPattern input needs to be a string or an object");
641-
return;
642-
}
628+
// V8 Methods
643629

644-
if (args.Length() > 1 && !args[1]->IsUndefined()) {
645-
if (args[1]->IsNull()) {
646-
baseURL = std::string("null");
647-
} else if (args[1]->IsString()) {
648-
Utf8Value base_url_value(env->isolate(), args[1].As<String>());
649-
baseURL = base_url_value.ToStringView();
650-
} else {
651-
THROW_ERR_INVALID_ARG_TYPE(env, "baseURL must be a string");
652-
return;
653-
}
654-
}
630+
void URLPattern::Exec(const FunctionCallbackInfo<Value>& args) {
631+
ExecOrTest<Local<Value>,
632+
MaybeLocal<Value>,
633+
&MaybeLocal<Value>::ToLocal,
634+
&URLPattern::Exec>(args);
635+
}
655636

656-
std::optional<std::string_view> baseURL_opt =
657-
baseURL ? std::optional<std::string_view>(*baseURL) : std::nullopt;
658-
args.GetReturnValue().Set(url_pattern->Test(env, input, baseURL_opt));
637+
void URLPattern::Test(const FunctionCallbackInfo<Value>& args) {
638+
ExecOrTest<bool, Maybe<bool>, &Maybe<bool>::To, &URLPattern::Test>(args);
659639
}
660640

661641
#define URL_PATTERN_COMPONENT_GETTERS(uppercase_name, lowercase_name) \

src/node_url_pattern.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ class URLPattern : public BaseObject {
102102
Environment* env,
103103
const ada::url_pattern_input& input,
104104
std::optional<std::string_view>& baseURL); // NOLINT (runtime/references)
105-
bool Test(
105+
v8::Maybe<bool> Test(
106106
Environment* env,
107107
const ada::url_pattern_input& input,
108108
std::optional<std::string_view>& baseURL); // NOLINT (runtime/references)

0 commit comments

Comments
 (0)