0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2025-01-21 05:02:11 -05:00

feat: add bindings for RegExp (#1674)

This commit is contained in:
Leo Kettmeir 2025-01-03 01:00:56 -08:00 committed by GitHub
parent 3b44a17594
commit bf4b66c56b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 125 additions and 0 deletions

View file

@ -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));

View file

@ -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;
@ -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;

73
src/regexp.rs Normal file
View file

@ -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()
}
}

View file

@ -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());
}