mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2024-11-24 14:42:35 +03:00
Merge pull request #797 from alexcrichton/iterator
Implement the `Iterator` trait for JS iterators
This commit is contained in:
commit
be4ead7c8a
@ -1174,6 +1174,79 @@ extern {
|
|||||||
pub fn next(this: &Iterator) -> Result<IteratorNext, JsValue>;
|
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
|
// IteratorNext
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
extern {
|
extern {
|
||||||
|
@ -89,3 +89,31 @@ fn set_inheritance() {
|
|||||||
assert!(set.is_instance_of::<Object>());
|
assert!(set.is_instance_of::<Object>());
|
||||||
let _: &Object = set.as_ref();
|
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