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