From f5f541337cacfd09c997ce1a9b7623712d72a475 Mon Sep 17 00:00:00 2001 From: Michael Hoffmann Date: Mon, 30 Jul 2018 01:13:42 +0200 Subject: [PATCH] Create bindings for RegExp (#580) * Create bindings for RegExp * Address review comments - Split the constructor into two: `new` and `new_regexp`. This way we can write RegExp::new("foo", "g") rather than RegExp::new(&JsValue::from("foo"), "g"). - The js_name for the setter for lastIndex should be `lastIndex` and not `set_lastIndex`. But fixing this causes a panic. Remove the method for now. --- crates/js-sys/src/lib.rs | 138 +++++++++++++++++++++++++++++ crates/js-sys/tests/wasm/RegExp.rs | 126 ++++++++++++++++++++++++++ crates/js-sys/tests/wasm/main.rs | 1 + 3 files changed, 265 insertions(+) create mode 100644 crates/js-sys/tests/wasm/RegExp.rs diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index 9e5b8b51..b68bad5c 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -2050,6 +2050,144 @@ extern "C" { pub fn set_prototype_of(target: &Object, prototype: &JsValue) -> bool; } +// RegExp +#[wasm_bindgen] +extern { + #[derive(Clone, Debug)] + pub type RegExp; + + /// The exec() method executes a search for a match in a specified + /// string. Returns a result array, or null. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec + #[wasm_bindgen(method)] + pub fn exec(this: &RegExp, text: &str) -> Option; + + /// The flags property returns a string consisting of the flags of + /// the current regular expression object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/flags + #[wasm_bindgen(method, getter)] + pub fn flags(this: &RegExp) -> JsString; + + /// The global property indicates whether or not the "g" flag is + /// used with the regular expression. global is a read-only + /// property of an individual regular expression instance. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/global + #[wasm_bindgen(method, getter)] + pub fn global(this: &RegExp) -> bool; + + /// The ignoreCase property indicates whether or not the "i" flag + /// is used with the regular expression. ignoreCase is a read-only + /// property of an individual regular expression instance. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/ignoreCase + #[wasm_bindgen(method, getter, js_name = ignoreCase)] + pub fn ignore_case(this: &RegExp) -> bool; + + /// The non-standard input property is a static property of + /// regular expressions that contains the string against which a + /// regular expression is matched. RegExp.$_ is an alias for this + /// property. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/input + #[wasm_bindgen(static_method_of = RegExp, getter)] + pub fn input() -> JsString; + + /// The non-standard lastMatch property is a static and read-only + /// property of regular expressions that contains the last matched + /// characters. RegExp.$& is an alias for this property. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastMatch + #[wasm_bindgen(static_method_of = RegExp, getter, js_name = lastMatch)] + pub fn last_match() -> JsString; + + /// The non-standard lastParen property is a static and read-only + /// property of regular expressions that contains the last + /// parenthesized substring match, if any. RegExp.$+ is an alias + /// for this property. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastParen + #[wasm_bindgen(static_method_of = RegExp, getter, js_name = lastParen)] + pub fn last_paren() -> JsString; + + /// The non-standard leftContext property is a static and + /// read-only property of regular expressions that contains the + /// substring preceding the most recent match. RegExp.$` is an + /// alias for this property. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/leftContext + #[wasm_bindgen(static_method_of = RegExp, getter, js_name = leftContext)] + pub fn left_context() -> JsString; + + /// The multiline property indicates whether or not the "m" flag + /// is used with the regular expression. multiline is a read-only + /// property of an individual regular expression instance. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/multiline + #[wasm_bindgen(method, getter)] + pub fn multiline(this: &RegExp) -> bool; + + /// The RegExp constructor creates a regular expression object for matching text with a pattern. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp + #[wasm_bindgen(constructor)] + pub fn new(pattern: &str, flags: &str) -> RegExp; + #[wasm_bindgen(constructor)] + pub fn new_regexp(pattern: &RegExp, flags: &str) -> RegExp; + + /// The non-standard rightContext property is a static and + /// read-only property of regular expressions that contains the + /// substring following the most recent match. RegExp.$' is an + /// alias for this property. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/rightContext + #[wasm_bindgen(static_method_of = RegExp, getter, js_name = rightContext)] + pub fn right_context() -> JsString; + + /// The source property returns a String containing the source + /// text of the regexp object, and it doesn't contain the two + /// forward slashes on both sides and any flags. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/source + #[wasm_bindgen(method, getter)] + pub fn source(this: &RegExp) -> JsString; + + /// The sticky property reflects whether or not the search is + /// sticky (searches in strings only from the index indicated by + /// the lastIndex property of this regular expression). sticky is + /// a read-only property of an individual regular expression + /// object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky + #[wasm_bindgen(method, getter)] + pub fn sticky(this: &RegExp) -> bool; + + /// The test() method executes a search for a match between a + /// regular expression and a specified string. Returns true or + /// false. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test + #[wasm_bindgen(method)] + pub fn test(this: &RegExp, text: &str) -> bool; + + /// The toString() method returns a string representing the + /// regular expression. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/toString + #[wasm_bindgen(method, js_name = toString)] + pub fn to_string(this: &RegExp) -> JsString; + + /// The unicode property indicates whether or not the "u" flag is + /// used with a regular expression. unicode is a read-only + /// property of an individual regular expression instance. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/unicode + #[wasm_bindgen(method, getter)] + pub fn unicode(this: &RegExp) -> bool; +} + // Set #[wasm_bindgen] extern { diff --git a/crates/js-sys/tests/wasm/RegExp.rs b/crates/js-sys/tests/wasm/RegExp.rs new file mode 100644 index 00000000..8af4946a --- /dev/null +++ b/crates/js-sys/tests/wasm/RegExp.rs @@ -0,0 +1,126 @@ +use wasm_bindgen::JsValue; +use wasm_bindgen_test::*; +use js_sys::*; + +#[wasm_bindgen_test] +fn exec() { + + let re = RegExp::new("quick\\s(brown).+?(jumps)", "ig"); + let result = re.exec("The Quick Brown Fox Jumps Over The Lazy Dog"); + + let mut v = vec![]; + result.unwrap().for_each(&mut |x, _, _| v.push(x)); + + assert_eq!(v[0], "Quick Brown Fox Jumps"); + assert_eq!(v[1], "Brown"); + assert_eq!(v[2], "Jumps"); + + let result = re.exec("foo"); + assert!(result.is_none()); +} + +#[wasm_bindgen_test] +fn flags() { + let re = RegExp::new("foo", "ig"); + assert_eq!(re.flags(), "gi"); +} + +#[wasm_bindgen_test] +fn global() { + let re = RegExp::new("foo", "g"); + assert!(re.global()); + + let re = RegExp::new("bar", "i"); + assert!(!re.global()); +} + +#[wasm_bindgen_test] +fn ignore_case() { + let re = RegExp::new("foo", ""); + assert!(!re.ignore_case()); + + let re = RegExp::new("foo", "i"); + assert!(re.ignore_case()); +} + +#[wasm_bindgen_test] +fn input() { + let re = RegExp::new("hi", "g"); + re.test("hi there!"); + assert_eq!(RegExp::input(), "hi there!"); +} + +#[wasm_bindgen_test] +fn last_match() { + let re = RegExp::new("hi", "g"); + re.test("hi there!"); + assert_eq!(RegExp::last_match(), "hi"); +} + +#[wasm_bindgen_test] +fn last_paren() { + let re = RegExp::new("(hi)", "g"); + re.test("hi there!"); + assert_eq!(RegExp::last_paren(), "hi"); +} + +#[wasm_bindgen_test] +fn left_context() { + let re = RegExp::new("world", "g"); + re.test("hello world!"); + assert_eq!(RegExp::left_context(), "hello "); +} + +#[wasm_bindgen_test] +fn multiline() { + let re = RegExp::new("foo", "m"); + assert!(re.multiline()); +} + +#[wasm_bindgen_test] +fn new() { + let re = RegExp::new("foo", ""); + let re = RegExp::new_regexp(&re, "g"); + assert_eq!(re.to_string(), "/foo/g"); +} + +#[wasm_bindgen_test] +fn right_context() { + let re = RegExp::new("hello", "g"); + re.test("hello world!"); + assert_eq!(RegExp::right_context(), " world!"); +} + +#[wasm_bindgen_test] +fn source() { + let re = RegExp::new("fooBar", "ig"); + assert_eq!(re.source(), "fooBar"); + + let re = RegExp::new("", "ig"); + assert_eq!(re.source(), "(?:)"); +} + +#[wasm_bindgen_test] +fn sticky() { + let re = RegExp::new("foo", "y"); + assert!(re.sticky()); +} + +#[wasm_bindgen_test] +fn test() { + let re = RegExp::new("foo", ""); + assert!(re.test("football")); + assert!(!re.test("bar")); +} + +#[wasm_bindgen_test] +fn to_string() { + let re = RegExp::new("a+b+c", "g"); + assert_eq!(re.to_string(), "/a+b+c/g"); +} + +#[wasm_bindgen_test] +fn unicode() { + let re = RegExp::new("\u{61}", "u"); + assert!(re.unicode()); +} diff --git a/crates/js-sys/tests/wasm/main.rs b/crates/js-sys/tests/wasm/main.rs index ba056755..1c4414b0 100755 --- a/crates/js-sys/tests/wasm/main.rs +++ b/crates/js-sys/tests/wasm/main.rs @@ -25,6 +25,7 @@ pub mod Number; pub mod Object; pub mod Proxy; pub mod Reflect; +pub mod RegExp; pub mod Set; pub mod SetIterator; pub mod Symbol;