diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index 6f9bc275..48c1cddc 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -1174,6 +1174,79 @@ extern { pub fn next(this: &Iterator) -> Result; } +pub struct Iter<'a> { + js: &'a Iterator, + state: IterState, +} + +pub struct IntoIter { + js: Iterator, + state: IterState, +} + +struct IterState { + done: bool, +} + +impl<'a> IntoIterator for &'a Iterator { + type Item = Result; + type IntoIter = Iter<'a>; + + fn into_iter(self) -> Iter<'a> { + Iter { js: self, state: IterState::new() } + } +} + +impl<'a> std::iter::Iterator for Iter<'a> { + type Item = Result; + + fn next(&mut self) -> Option { + self.state.next(self.js) + } +} + +impl IntoIterator for Iterator { + type Item = Result; + type IntoIter = IntoIter; + + fn into_iter(self) -> IntoIter { + IntoIter { js: self, state: IterState::new() } + } +} + +impl std::iter::Iterator for IntoIter { + type Item = Result; + + fn next(&mut self) -> Option { + self.state.next(&self.js) + } +} + +impl IterState { + fn new() -> IterState { + IterState { done: false } + } + + fn next(&mut self, js: &Iterator) -> Option> { + if self.done { + return None + } + let next = match js.next() { + Ok(val) => val, + Err(e) => { + self.done = true; + return Some(Err(e)) + } + }; + if next.done() { + self.done = true; + None + } else { + Some(Ok(next.value())) + } + } +} + // IteratorNext #[wasm_bindgen] extern { diff --git a/crates/js-sys/tests/wasm/Set.rs b/crates/js-sys/tests/wasm/Set.rs index f475c5a0..6b70d1b6 100644 --- a/crates/js-sys/tests/wasm/Set.rs +++ b/crates/js-sys/tests/wasm/Set.rs @@ -89,3 +89,31 @@ fn set_inheritance() { assert!(set.is_instance_of::()); let _: &Object = set.as_ref(); } + +#[wasm_bindgen_test] +fn keys() { + let set = Set::new(&JsValue::undefined()); + set.add(&1.into()); + set.add(&2.into()); + set.add(&3.into()); + + let list = set.keys().into_iter().map(|e| e.unwrap()).collect::>(); + assert_eq!(list.len(), 3); + assert!(list.iter().any(|l| *l == 1)); + assert!(list.iter().any(|l| *l == 2)); + assert!(list.iter().any(|l| *l == 3)); +} + +#[wasm_bindgen_test] +fn values() { + let set = Set::new(&JsValue::undefined()); + set.add(&1.into()); + set.add(&2.into()); + set.add(&3.into()); + + let list = set.values().into_iter().map(|e| e.unwrap()).collect::>(); + assert_eq!(list.len(), 3); + assert!(list.iter().any(|l| *l == 1)); + assert!(list.iter().any(|l| *l == 2)); + assert!(list.iter().any(|l| *l == 3)); +}