1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
use rust_jsc_sys::{JSObjectMakeRegExp, JSValueRef};
use crate::{JSContext, JSError, JSObject, JSRegExp, JSResult, JSValue};
impl JSRegExp {
pub fn new(object: JSObject) -> Self {
Self { object }
}
/// Creates a new `JSRegExp` object.
///
/// # Arguments
/// - `ctx`: The JavaScript context to create the regexp in.
/// - `args`: The values to initialize the regexp with.
///
/// # Example
/// ```
/// use rust_jsc::{JSContext, JSRegExp, JSValue};
///
/// let ctx = JSContext::new();
/// let regexp = JSRegExp::new_regexp(&ctx, &[JSValue::string(&ctx, "a")]).unwrap();
/// let result = regexp.exec(&ctx, "abc").unwrap();
/// assert_eq!(result.as_string().unwrap(), "a");
/// ```
///
/// # Errors
/// If an exception is thrown while creating the regexp.
/// A `JSError` will be returned.
///
/// # Returns
/// The new `JSRegExp` object.
pub fn new_regexp(ctx: &JSContext, args: &[JSValue]) -> JSResult<Self> {
let mut exception: JSValueRef = std::ptr::null_mut();
let args: Vec<JSValueRef> = args.iter().map(|arg| arg.inner).collect();
let result = unsafe {
JSObjectMakeRegExp(ctx.inner, args.len(), args.as_ptr(), &mut exception)
};
if !exception.is_null() {
let value = JSValue::new(exception, ctx.inner);
return Err(JSError::from(value));
}
Ok(Self::new(JSObject::from_ref(result, ctx.inner)))
}
/// Executes a search for a match in a specified string.
/// Returns the first match, or `null` if no match was found.
/// This is equivalent to `regexp.exec(string)` in JavaScript.
///
/// # Arguments
/// - `ctx`: The JavaScript context to execute the search in.
/// - `string`: The string to search for a match in.
///
/// # Returns
/// The first match, or `null` if no match was found.
///
/// # Errors
/// If an exception is thrown while executing the search.
/// A `JSError` will be returned.
///
/// # Example
/// ```
/// use rust_jsc::{JSContext, JSRegExp, JSValue};
///
/// let ctx = JSContext::new();
/// let regexp = JSRegExp::new_regexp(&ctx, &[JSValue::string(&ctx, "a")]).unwrap();
/// let result = regexp.exec(&ctx, "abc").unwrap();
/// assert_eq!(result.as_string().unwrap(), "a");
/// ```
pub fn exec(&self, ctx: &JSContext, string: &str) -> JSResult<JSValue> {
let string = JSValue::string(ctx, string);
self.object
.get_property("exec")?
.as_object()?
.call(Some(&self.object), &[string])
}
/// Tests for a match in a specified string.
/// Returns `true` if a match was found, otherwise `false`.
/// This is equivalent to `regexp.test(string)` in JavaScript.
///
/// # Arguments
/// - `ctx`: The JavaScript context to execute the test in.
/// - `string`: The string to test for a match in.
///
/// # Example
/// ```
/// use rust_jsc::{JSContext, JSRegExp, JSValue};
///
/// let ctx = JSContext::new();
/// let regexp = JSRegExp::new_regexp(&ctx, &[JSValue::string(&ctx, "a")]).unwrap();
/// let result = regexp.test(&ctx, "abc").unwrap();
/// assert_eq!(result.as_boolean(), true);
/// ```
///
/// # Errors
/// If an exception is thrown while executing the test.
/// A `JSError` will be returned.
///
/// # Returns
/// `true` if a match was found, otherwise `false`.
pub fn test(&self, ctx: &JSContext, string: &str) -> JSResult<JSValue> {
let string = JSValue::string(ctx, string);
self.object
.get_property("test")?
.as_object()?
.call(Some(&self.object), &[string])
}
}
impl From<JSRegExp> for JSObject {
fn from(regexp: JSRegExp) -> Self {
regexp.object
}
}
impl From<JSRegExp> for JSValue {
fn from(regexp: JSRegExp) -> Self {
regexp.object.into()
}
}
#[cfg(test)]
mod tests {
use crate::{JSContext, JSRegExp, JSValue};
#[test]
fn test_regexp() {
let ctx = JSContext::new();
let regexp = JSRegExp::new_regexp(&ctx, &[JSValue::string(&ctx, "a")]).unwrap();
let result = regexp.exec(&ctx, "abc").unwrap();
assert_eq!(result.as_string().unwrap(), "a");
let result = regexp.test(&ctx, "abc").unwrap();
assert_eq!(result.as_boolean(), true);
}
}