diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index 55d9a617..02a566a6 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -379,29 +379,26 @@ extern "C" { // Array Iterator #[wasm_bindgen] extern "C" { - #[derive(Clone, Debug)] - pub type ArrayIterator; - /// The keys() method returns a new Array Iterator object that contains the /// keys for each index in the array. /// /// http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/keys #[wasm_bindgen(method)] - pub fn keys(this: &Array) -> ArrayIterator; + pub fn keys(this: &Array) -> Iterator; /// The entries() method returns a new Array Iterator object that contains /// the key/value pairs for each index in the array. /// /// http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries #[wasm_bindgen(method)] - pub fn entries(this: &Array) -> ArrayIterator; + pub fn entries(this: &Array) -> Iterator; /// The values() method returns a new Array Iterator object that /// contains the values for each index in the array. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/values #[wasm_bindgen(method)] - pub fn values(this: &Array) -> ArrayIterator; + pub fn values(this: &Array) -> Iterator; } // Boolean @@ -1015,30 +1012,70 @@ extern { // Map Iterator #[wasm_bindgen] extern { - #[derive(Clone, Debug)] - pub type MapIterator; - /// The entries() method returns a new Iterator object that contains /// the [key, value] pairs for each element in the Map object in /// insertion order. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries #[wasm_bindgen(method)] - pub fn entries(this: &Map) -> MapIterator; + pub fn entries(this: &Map) -> Iterator; /// The keys() method returns a new Iterator object that contains the /// keys for each element in the Map object in insertion order. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys #[wasm_bindgen(method)] - pub fn keys(this: &Map) -> MapIterator; + pub fn keys(this: &Map) -> Iterator; /// The values() method returns a new Iterator object that contains the /// values for each element in the Map object in insertion order. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values #[wasm_bindgen(method)] - pub fn values(this: &Map) -> MapIterator; + pub fn values(this: &Map) -> Iterator; +} + +// Iterator +#[wasm_bindgen] +extern { + /// Any object that conforms to the JS iterator protocol. For example, + /// something returned by `myArray[Symbol.iterator]()`. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols + #[derive(Clone, Debug)] + pub type Iterator; + + /// The next method always has to return an object with appropriate + /// properties including done and value. If a non-object value gets returned + /// (such as false or undefined), a TypeError ("iterator.next() returned a + /// non-object value") will be thrown. + #[wasm_bindgen(catch, method, structural)] + pub fn next(this: &Iterator) -> Result; +} + +// IteratorNext +#[wasm_bindgen] +extern { + /// The result of calling `next()` on a JS iterator. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols + #[derive(Clone, Debug)] + pub type IteratorNext; + + /// Has the value `true` if the iterator is past the end of the iterated + /// sequence. In this case value optionally specifies the return value of + /// the iterator. + /// + /// Has the value `false` if the iterator was able to produce the next value + /// in the sequence. This is equivalent of not specifying the done property + /// altogether. + #[wasm_bindgen(method, getter, structural)] + pub fn done(this: &IteratorNext) -> bool; + + /// Any JavaScript value returned by the iterator. Can be omitted when done + /// is true. + #[wasm_bindgen(method, getter, structural)] + pub fn value(this: &IteratorNext) -> JsValue; } // Math @@ -2064,9 +2101,6 @@ extern { // SetIterator #[wasm_bindgen] extern { - #[derive(Clone, Debug)] - pub type SetIterator; - /// The `entries()` method returns a new Iterator object that contains an /// array of [value, value] for each element in the Set object, in insertion /// order. For Set objects there is no key like in Map objects. However, to @@ -2075,7 +2109,7 @@ extern { /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries #[wasm_bindgen(method)] - pub fn entries(set: &Set) -> SetIterator; + pub fn entries(set: &Set) -> Iterator; /// The `keys()` method is an alias for this method (for similarity with /// Map objects); it behaves exactly the same and returns values @@ -2083,14 +2117,14 @@ extern { /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values #[wasm_bindgen(method)] - pub fn keys(set: &Set) -> SetIterator; + pub fn keys(set: &Set) -> Iterator; /// The `values()` method returns a new Iterator object that contains the /// values for each element in the Set object in insertion order. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values #[wasm_bindgen(method)] - pub fn values(set: &Set) -> SetIterator; + pub fn values(set: &Set) -> Iterator; } // Uint8Array diff --git a/crates/js-sys/tests/headless.rs b/crates/js-sys/tests/headless.rs old mode 100644 new mode 100755 index 59ba2c01..6bc28f4a --- a/crates/js-sys/tests/headless.rs +++ b/crates/js-sys/tests/headless.rs @@ -26,7 +26,7 @@ fn ArrayIterator_values() { use wasm_bindgen::prelude::*; #[wasm_bindgen] - pub fn get_values(this: &js_sys::Array) -> js_sys::ArrayIterator { + pub fn get_values(this: &js_sys::Array) -> js_sys::Iterator { this.values() } "#, diff --git a/crates/js-sys/tests/wasm/MapIterator.rs b/crates/js-sys/tests/wasm/MapIterator.rs index 486c9891..ee76a85e 100644 --- a/crates/js-sys/tests/wasm/MapIterator.rs +++ b/crates/js-sys/tests/wasm/MapIterator.rs @@ -1,23 +1,52 @@ -use wasm_bindgen::JsValue; use wasm_bindgen_test::*; use js_sys::*; -// TODO: not much you can do with `MapIterator` types yet :( - #[wasm_bindgen_test] fn entries() { let map = Map::new(); - assert!(JsValue::from(map.entries()).is_object()); + map.set(&"uno".into(), &1.into()); + + let entries = map.entries(); + + let next = entries.next().unwrap(); + assert_eq!(next.done(), false); + assert!(next.value().is_object()); + assert_eq!(Reflect::get(&next.value(), &0.into()), "uno"); + assert_eq!(Reflect::get(&next.value(), &1.into()), 1); + + let next = entries.next().unwrap(); + assert!(next.done()); + assert!(next.value().is_undefined()); } #[wasm_bindgen_test] fn keys() { let map = Map::new(); - assert!(JsValue::from(map.keys()).is_object()); + map.set(&"uno".into(), &1.into()); + + let keys = map.keys(); + + let next = keys.next().unwrap(); + assert_eq!(next.done(), false); + assert_eq!(next.value(), "uno"); + + let next = keys.next().unwrap(); + assert!(next.done()); + assert!(next.value().is_undefined()); } #[wasm_bindgen_test] fn values() { let map = Map::new(); - assert!(JsValue::from(map.values()).is_object()); + map.set(&"uno".into(), &1.into()); + + let values = map.values(); + + let next = values.next().unwrap(); + assert_eq!(next.done(), false); + assert_eq!(next.value(), 1); + + let next = values.next().unwrap(); + assert!(next.done()); + assert!(next.value().is_undefined()); } diff --git a/crates/js-sys/tests/wasm/SetIterator.rs b/crates/js-sys/tests/wasm/SetIterator.rs index 5df4b254..45e25319 100644 --- a/crates/js-sys/tests/wasm/SetIterator.rs +++ b/crates/js-sys/tests/wasm/SetIterator.rs @@ -2,25 +2,12 @@ use wasm_bindgen::prelude::*; use wasm_bindgen_test::*; use js_sys::*; -#[wasm_bindgen] -extern { - type GenericIterator; - #[wasm_bindgen(method, structural)] - fn next(this: &GenericIterator) -> IteratorNext; - - type IteratorNext; - #[wasm_bindgen(method, structural, getter)] - fn value(this: &IteratorNext) -> JsValue; - #[wasm_bindgen(method, structural, getter)] - fn done(this: &IteratorNext) -> bool; -} - #[wasm_bindgen_test] fn entries() { let s = Set::new(&JsValue::undefined()); s.add(&1.into()); - let iter = GenericIterator::from(JsValue::from(s.entries())); - let obj = iter.next(); + let iter = s.entries(); + let obj = iter.next().unwrap(); assert!(!obj.done()); let array = Array::from(&obj.value()); assert_eq!(array.length(), 2); @@ -28,27 +15,27 @@ fn entries() { assert_eq!(a, 1); }); - assert!(iter.next().done()); + assert!(iter.next().unwrap().done()); } #[wasm_bindgen_test] fn keys() { let s = Set::new(&JsValue::undefined()); s.add(&1.into()); - let iter = GenericIterator::from(JsValue::from(s.keys())); - let obj = iter.next(); + let iter = s.keys(); + let obj = iter.next().unwrap(); assert!(!obj.done()); assert_eq!(obj.value(), 1); - assert!(iter.next().done()); + assert!(iter.next().unwrap().done()); } #[wasm_bindgen_test] fn values() { let s = Set::new(&JsValue::undefined()); s.add(&1.into()); - let iter = GenericIterator::from(JsValue::from(s.values())); - let obj = iter.next(); + let iter = s.values(); + let obj = iter.next().unwrap(); assert!(!obj.done()); assert_eq!(obj.value(), 1); - assert!(iter.next().done()); + assert!(iter.next().unwrap().done()); }