Merge pull request #797 from alexcrichton/iterator

Implement the `Iterator` trait for JS iterators
This commit is contained in:
Alex Crichton 2018-09-10 11:40:56 -07:00 committed by GitHub
commit be4ead7c8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 101 additions and 0 deletions

View File

@ -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 {

View File

@ -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));
}