Skip to content

Commit

Permalink
feat: add bindings for RegExp (#1674)
Browse files Browse the repository at this point in the history
  • Loading branch information
crowlKats authored Jan 3, 2025
1 parent 3b44a17 commit bf4b66c
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2367,6 +2367,23 @@ bool v8__PropertyCallbackInfo__ShouldThrowOnError(
return self.ShouldThrowOnError();
}

const v8::RegExp* v8__RegExp__New(const v8::Context& context,
const v8::String& pattern,
v8::RegExp::Flags flags) {
return maybe_local_to_ptr(
v8::RegExp::New(ptr_to_local(&context), ptr_to_local(&pattern), flags));
}

const v8::Object* v8__RegExp__Exec(v8::RegExp& self, const v8::Context& context,
const v8::String& subject) {
return maybe_local_to_ptr(
self.Exec(ptr_to_local(&context), ptr_to_local(&subject)));
}

const v8::String* v8__RegExp__GetSource(const v8::RegExp& self) {
return local_to_ptr(self.GetSource());
}

void v8__ReturnValue__Value__Set(v8::ReturnValue<v8::Value>* self,
const v8::Value& value) {
self->Set(ptr_to_local(&value));
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ mod property_descriptor;
mod property_filter;
mod property_handler_flags;
mod proxy;
mod regexp;
mod scope;
mod script;
mod script_or_module;
Expand Down Expand Up @@ -138,6 +139,7 @@ pub use property_attribute::*;
pub use property_descriptor::*;
pub use property_filter::*;
pub use property_handler_flags::*;
pub use regexp::RegExpCreationFlags;
pub use scope::AllowJavascriptExecutionScope;
pub use scope::CallbackScope;
pub use scope::ContextScope;
Expand Down
73 changes: 73 additions & 0 deletions src/regexp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use crate::support::int;
use crate::Context;
use crate::HandleScope;
use crate::Local;
use crate::Object;
use crate::RegExp;
use crate::String;

bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(transparent)]
pub struct RegExpCreationFlags: int {
const GLOBAL = 1 << 0;
const IGNORE_CASE = 1 << 1;
const MULTILINE = 1 << 2;
const STICKY = 1 << 3;
const UNICODE = 1 << 4;
const DOT_ALL = 1 << 5;
const LINEAR = 1 << 6;
const HAS_INDICES = 1 << 7;
const UNICODE_SETS = 1 << 8;
}
}

extern "C" {
fn v8__RegExp__New(
context: *const Context,
pattern: *const String,
flags: RegExpCreationFlags,
) -> *const RegExp;
fn v8__RegExp__Exec(
this: *const RegExp,
context: *const Context,
subject: *const String,
) -> *const Object;
fn v8__RegExp__GetSource(this: *const RegExp) -> *const String;
}

impl RegExp {
#[inline(always)]
pub fn new<'s>(
scope: &mut HandleScope<'s>,
pattern: Local<String>,
flags: RegExpCreationFlags,
) -> Option<Local<'s, RegExp>> {
unsafe {
scope.cast_local(|sd| {
v8__RegExp__New(sd.get_current_context(), &*pattern, flags)
})
}
}

#[inline(always)]
pub fn exec<'s>(
&self,
scope: &mut HandleScope<'s>,
subject: Local<String>,
) -> Option<Local<'s, Object>> {
unsafe {
scope.cast_local(|sd| {
v8__RegExp__Exec(self, sd.get_current_context(), &*subject)
})
}
}

#[inline(always)]
pub fn get_source<'s>(
&self,
scope: &mut HandleScope<'s>,
) -> Local<'s, String> {
unsafe { scope.cast_local(|_| v8__RegExp__GetSource(self)) }.unwrap()
}
}
33 changes: 33 additions & 0 deletions tests/test_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12006,3 +12006,36 @@ fn test_eternals() {
assert!(eternal1.is_empty());
eternal1.clear();
}

#[test]
fn test_regexp() {
let _setup_guard = setup::parallel_test();

let mut isolate = v8::Isolate::new(Default::default());
let mut scope = v8::HandleScope::new(&mut isolate);
let context = v8::Context::new(&mut scope, Default::default());
let scope = &mut v8::ContextScope::new(&mut scope, context);

let pattern = v8::String::new(scope, "ab+c").unwrap();
let regexp =
v8::RegExp::new(scope, pattern, v8::RegExpCreationFlags::empty()).unwrap();
assert_eq!(regexp.get_source(scope).to_rust_string_lossy(scope), "ab+c");

let subject = v8::String::new(scope, "abbbc").unwrap();
let result = regexp.exec(scope, subject).unwrap();

let full = result.get_index(scope, 0).unwrap();
assert_eq!(full.to_rust_string_lossy(scope), "abbbc");

let index_key = v8::String::new(scope, "index").unwrap();
let index = result.get(scope, index_key.into()).unwrap();
assert_eq!(index.number_value(scope).unwrap(), 0.0);

let input_key = v8::String::new(scope, "input").unwrap();
let input = result.get(scope, input_key.into()).unwrap();
assert_eq!(input.to_rust_string_lossy(scope), "abbbc");

let groups_key = v8::String::new(scope, "groups").unwrap();
let groups = result.get(scope, groups_key.into()).unwrap();
assert!(groups.is_undefined());
}

0 comments on commit bf4b66c

Please sign in to comment.