mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2024-12-29 13:06:06 +03:00
Implement the Iterator
trait for JS iterators
This commit implements the standard library's `Iterator` trait for the `js_sys::Iterator` type, using the iterator protocol described on [MDN] Closes #777 [MDN]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols
This commit is contained in:
parent
f18b10ca52
commit
f2608d3155
@ -1174,6 +1174,79 @@ extern {
|
||||
pub fn next(this: &Iterator) -> Result<IteratorNext, JsValue>;
|
||||
}
|
||||
|
||||
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<JsValue, JsValue>;
|
||||
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<JsValue, JsValue>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.state.next(self.js)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for Iterator {
|
||||
type Item = Result<JsValue, JsValue>;
|
||||
type IntoIter = IntoIter;
|
||||
|
||||
fn into_iter(self) -> IntoIter {
|
||||
IntoIter { js: self, state: IterState::new() }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::iter::Iterator for IntoIter {
|
||||
type Item = Result<JsValue, JsValue>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.state.next(&self.js)
|
||||
}
|
||||
}
|
||||
|
||||
impl IterState {
|
||||
fn new() -> IterState {
|
||||
IterState { done: false }
|
||||
}
|
||||
|
||||
fn next(&mut self, js: &Iterator) -> Option<Result<JsValue, JsValue>> {
|
||||
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 {
|
||||
|
@ -89,3 +89,31 @@ fn set_inheritance() {
|
||||
assert!(set.is_instance_of::<Object>());
|
||||
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::<Vec<_>>();
|
||||
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::<Vec<_>>();
|
||||
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));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user