From d693d7c0cbb81a7c0c34ed78d94a934ed40853ac Mon Sep 17 00:00:00 2001 From: Pauan Date: Tue, 3 Sep 2019 10:45:13 +0200 Subject: [PATCH] Adding in more methods for Array --- crates/js-sys/src/lib.rs | 35 ++++++++- crates/js-sys/tests/wasm/Array.rs | 117 ++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+), 1 deletion(-) diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index 83c27c22783..951784b4c9a 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -130,10 +130,30 @@ extern "C" { #[derive(Clone, Debug, PartialEq, Eq)] pub type Array; - /// Creates a new empty array + /// Creates a new empty array. #[wasm_bindgen(constructor)] pub fn new() -> Array; + /// Creates a new array with the specified length (elements are initialized to `undefined`). + #[wasm_bindgen(constructor)] + pub fn new_with_length(len: u32) -> Array; + + /// Retrieves the element at the index (returns `undefined` if the index is out of range). + #[wasm_bindgen(method, structural, indexing_getter)] + pub fn get(this: &Array, index: u32) -> JsValue; + + /// Sets the element at the index (auto-enlarges the array if the index is out of range). + #[wasm_bindgen(method, structural, indexing_setter)] + pub fn set(this: &Array, index: u32, value: JsValue); + + /// Deletes the element at the index (does nothing if the index is out of range). + /// + /// The element at the index is set to `undefined`. + /// + /// This does not resize the array, the array will still be the same length. + #[wasm_bindgen(method, structural, indexing_deleter)] + pub fn delete(this: &Array, index: u32); + /// The `Array.from()` method creates a new, shallow-copied `Array` instance /// from an array-like or iterable object. #[wasm_bindgen(static_method_of = Array)] @@ -405,6 +425,19 @@ extern "C" { pub fn unshift(this: &Array, value: &JsValue) -> u32; } +// TODO pre-initialize the Array with the correct length using TrustedLen +impl std::iter::FromIterator for Array where A: AsRef { + fn from_iter(iter: T) -> Array where T: IntoIterator { + let out = Array::new(); + + for value in iter { + out.push(value.as_ref()); + } + + out + } +} + // ArrayBuffer #[wasm_bindgen] extern "C" { diff --git a/crates/js-sys/tests/wasm/Array.rs b/crates/js-sys/tests/wasm/Array.rs index 61bd08ed1c4..eb903e2cfd5 100644 --- a/crates/js-sys/tests/wasm/Array.rs +++ b/crates/js-sys/tests/wasm/Array.rs @@ -1,4 +1,5 @@ use js_sys::*; +use std::iter::FromIterator; use wasm_bindgen::JsCast; use wasm_bindgen::JsValue; use wasm_bindgen_test::*; @@ -25,6 +26,122 @@ fn to_rust(arr: &Array) -> Vec { result } +#[wasm_bindgen_test] +fn from_iter() { + assert_eq!( + to_rust(&vec![ + JsValue::from("a"), + JsValue::from("b"), + JsValue::from("c"), + ].into_iter().collect()), + vec!["a", "b", "c"], + ); + + assert_eq!( + to_rust(&vec![ + JsValue::from("a"), + JsValue::from("b"), + JsValue::from("c"), + ].iter().collect()), + vec!["a", "b", "c"], + ); + + let array = js_array![1u32, 2u32, 3u32]; + + assert_eq!( + to_rust(&vec![ + array.clone(), + ].into_iter().collect()), + vec![JsValue::from(array.clone())], + ); + + assert_eq!( + to_rust(&vec![ + array.clone(), + ].iter().collect()), + vec![JsValue::from(array)], + ); + + assert_eq!( + to_rust(&vec![ + 5, + 10, + 20, + ].into_iter().map(JsValue::from).collect()), + vec![5, 10, 20], + ); + + assert_eq!( + to_rust(&Array::from_iter(&[ + JsValue::from("a"), + JsValue::from("b"), + JsValue::from("c"), + ])), + vec!["a", "b", "c"], + ); + + let v = vec![ + "a", + "b", + "c", + ]; + + assert_eq!( + to_rust(&Array::from_iter(v.into_iter().map(|s| JsValue::from(s)))), + vec!["a", "b", "c"], + ); +} + +#[wasm_bindgen_test] +fn new_with_length() { + let array = Array::new_with_length(5); + assert_eq!(array.length(), 5); + assert_eq!(array.get(4), JsValue::undefined()); + array.set(4, JsValue::from("a")); + assert_eq!(array.get(4), "a"); + assert_eq!(array.length(), 5); +} + +#[wasm_bindgen_test] +fn get() { + let array = js_array!["a", "c", "x", "n"]; + assert_eq!(array.length(), 4); + assert_eq!(array.get(0), "a"); + assert_eq!(array.get(3), "n"); + assert_eq!(array.get(4), JsValue::undefined()); +} + +#[wasm_bindgen_test] +fn set() { + let array = js_array!["a", "c", "x", "n"]; + assert_eq!(array.length(), 4); + assert_eq!(array.get(0), "a"); + array.set(0, JsValue::from("b")); + assert_eq!(array.get(0), "b"); + + assert_eq!(array.get(4), JsValue::undefined()); + assert_eq!(array.length(), 4); + array.set(4, JsValue::from("d")); + assert_eq!(array.length(), 5); + assert_eq!(array.get(4), "d"); + + assert_eq!(array.get(10), JsValue::undefined()); + assert_eq!(array.length(), 5); + array.set(10, JsValue::from("z")); + assert_eq!(array.length(), 11); + assert_eq!(array.get(10), "z"); + assert_eq!(array.get(9), JsValue::undefined()); +} + +#[wasm_bindgen_test] +fn delete() { + let array = js_array!["a", "c", "x", "n"]; + assert_eq!(array.length(), 4); + assert_eq!(array.get(0), "a"); + array.delete(0); + assert_eq!(array.get(0), JsValue::undefined()); +} + #[wasm_bindgen_test] fn filter() { let array = js_array!["a", "c", "x", "n"];