1
0
mirror of https://github.com/fluencelabs/wasm-bindgen synced 2025-04-03 02:41:06 +00:00

Merge pull request from RReverser/iter-is-type-of

Leverage new `is_type_of` for iterator protocol
This commit is contained in:
Alex Crichton 2019-04-12 14:45:05 -05:00 committed by GitHub
commit 744b031ad4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1025,6 +1025,7 @@ extern "C" {
/// ///
/// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols)
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
#[wasm_bindgen(is_type_of = Iterator::looks_like_iterator)]
pub type Iterator; pub type Iterator;
/// The next method always has to return an object with appropriate /// The next method always has to return an object with appropriate
@ -1035,6 +1036,26 @@ extern "C" {
pub fn next(this: &Iterator) -> Result<IteratorNext, JsValue>; pub fn next(this: &Iterator) -> Result<IteratorNext, JsValue>;
} }
impl Iterator {
fn looks_like_iterator(it: &JsValue) -> bool {
#[wasm_bindgen]
extern "C" {
type MaybeIterator;
#[wasm_bindgen(method, getter)]
fn next(this: &MaybeIterator) -> JsValue;
}
if !it.is_object() {
return false;
}
let it = it.unchecked_ref::<MaybeIterator>();
it.next().is_function()
}
}
/// An iterator over the JS `Symbol.iterator` iteration protocol. /// An iterator over the JS `Symbol.iterator` iteration protocol.
/// ///
/// Use the `IntoIterator for &js_sys::Iterator` implementation to create this. /// Use the `IntoIterator for &js_sys::Iterator` implementation to create this.
@ -1123,37 +1144,20 @@ impl IterState {
/// Create an iterator over `val` using the JS iteration protocol and /// Create an iterator over `val` using the JS iteration protocol and
/// `Symbol.iterator`. /// `Symbol.iterator`.
pub fn try_iter(val: &JsValue) -> Result<Option<IntoIter>, JsValue> { pub fn try_iter(val: &JsValue) -> Result<Option<IntoIter>, JsValue> {
#[wasm_bindgen]
extern "C" {
type MaybeIterator;
#[wasm_bindgen(method, getter)]
fn next(this: &MaybeIterator) -> JsValue;
}
let iter_sym = Symbol::iterator(); let iter_sym = Symbol::iterator();
let iter_fn = Reflect::get(val, iter_sym.as_ref())?; let iter_fn = Reflect::get(val, iter_sym.as_ref())?;
if !iter_fn.is_function() {
return Ok(None);
}
let iter_fn: Function = match iter_fn.dyn_into() { let iter_fn: Function = match iter_fn.dyn_into() {
Ok(iter_fn) => iter_fn, Ok(iter_fn) => iter_fn,
Err(_) => return Ok(None) Err(_) => return Ok(None),
}; };
let it = iter_fn.call0(val)?;
if !it.is_object() {
return Ok(None);
}
let next = it.unchecked_ref::<MaybeIterator>().next(); let it: Iterator = match iter_fn.call0(val)?.dyn_into() {
Ok(it) => it,
Err(_) => return Ok(None),
};
Ok(if next.is_function() { Ok(Some(it.into_iter()))
let it: Iterator = it.unchecked_into();
Some(it.into_iter())
} else {
None
})
} }
// IteratorNext // IteratorNext