mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-04-25 14:12:13 +00:00
Adding in support for async iterators (#1895)
* Adding in support for async iterators * Adding in some unit tests for asyncIterator * Fixing unit tests * Fixing UI tests
This commit is contained in:
parent
203d86f343
commit
a1d90398d0
@ -1349,6 +1349,25 @@ impl Iterator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Async Iterator
|
||||||
|
#[wasm_bindgen]
|
||||||
|
extern "C" {
|
||||||
|
/// Any object that conforms to the JS async iterator protocol. For example,
|
||||||
|
/// something returned by `myObject[Symbol.asyncIterator]()`.
|
||||||
|
///
|
||||||
|
/// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of)
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
#[wasm_bindgen(is_type_of = Iterator::looks_like_iterator)]
|
||||||
|
pub type AsyncIterator;
|
||||||
|
|
||||||
|
/// The next method always has to return a Promise which resolves to an object
|
||||||
|
/// with appropriate properties including done and value. If a non-object value
|
||||||
|
/// gets returned (such as false or undefined), a TypeError ("iterator.next()
|
||||||
|
/// returned a non-object value") will be thrown.
|
||||||
|
#[wasm_bindgen(catch, method, structural)]
|
||||||
|
pub fn next(this: &AsyncIterator) -> Result<Promise, JsValue>;
|
||||||
|
}
|
||||||
|
|
||||||
/// 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.
|
||||||
@ -4165,6 +4184,13 @@ extern "C" {
|
|||||||
#[wasm_bindgen(static_method_of = Symbol, getter, structural, js_name = isConcatSpreadable)]
|
#[wasm_bindgen(static_method_of = Symbol, getter, structural, js_name = isConcatSpreadable)]
|
||||||
pub fn is_concat_spreadable() -> Symbol;
|
pub fn is_concat_spreadable() -> Symbol;
|
||||||
|
|
||||||
|
/// The `Symbol.asyncIterator` well-known symbol specifies the default AsyncIterator for an object.
|
||||||
|
/// If this property is set on an object, it is an async iterable and can be used in a `for await...of` loop.
|
||||||
|
///
|
||||||
|
/// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator)
|
||||||
|
#[wasm_bindgen(static_method_of = Symbol, getter, structural, js_name = asyncIterator)]
|
||||||
|
pub fn async_iterator() -> Symbol;
|
||||||
|
|
||||||
/// The `Symbol.iterator` well-known symbol specifies the default iterator
|
/// The `Symbol.iterator` well-known symbol specifies the default iterator
|
||||||
/// for an object. Used by `for...of`.
|
/// for an object. Used by `for...of`.
|
||||||
///
|
///
|
||||||
|
@ -36,6 +36,41 @@ exports.test_iterator = function(sym) {
|
|||||||
assert.deepEqual([...iterable1], [1, 2, 3]);
|
assert.deepEqual([...iterable1], [1, 2, 3]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.test_async_iterator = async function(sym) {
|
||||||
|
const iterable1 = new Object();
|
||||||
|
|
||||||
|
iterable1[sym] = function () {
|
||||||
|
let done = false;
|
||||||
|
|
||||||
|
return {
|
||||||
|
next() {
|
||||||
|
if (done) {
|
||||||
|
return Promise.resolve({
|
||||||
|
done: true,
|
||||||
|
value: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
done = true;
|
||||||
|
|
||||||
|
return Promise.resolve({
|
||||||
|
done: false,
|
||||||
|
value: 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const values = [];
|
||||||
|
|
||||||
|
for await (let value of iterable1) {
|
||||||
|
values.push(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.deepEqual(values, [0]);
|
||||||
|
};
|
||||||
|
|
||||||
exports.test_match = function(sym) {
|
exports.test_match = function(sym) {
|
||||||
const regexp1 = /foo/;
|
const regexp1 = /foo/;
|
||||||
assert.throws(() => '/foo/'.startsWith(regexp1));
|
assert.throws(() => '/foo/'.startsWith(regexp1));
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
use js_sys::*;
|
use js_sys::*;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use wasm_bindgen_test::*;
|
use wasm_bindgen_test::*;
|
||||||
|
use wasm_bindgen_futures::JsFuture;
|
||||||
|
|
||||||
#[wasm_bindgen(module = "tests/wasm/Symbol.js")]
|
#[wasm_bindgen(module = "tests/wasm/Symbol.js")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn test_has_instance(sym: &Symbol);
|
fn test_has_instance(sym: &Symbol);
|
||||||
fn test_is_concat_spreadable(sym: &Symbol);
|
fn test_is_concat_spreadable(sym: &Symbol);
|
||||||
fn test_iterator(sym: &Symbol);
|
fn test_iterator(sym: &Symbol);
|
||||||
|
fn test_async_iterator(sym: &Symbol) -> Promise;
|
||||||
fn test_match(sym: &Symbol);
|
fn test_match(sym: &Symbol);
|
||||||
fn test_replace(sym: &Symbol);
|
fn test_replace(sym: &Symbol);
|
||||||
fn test_search(sym: &Symbol);
|
fn test_search(sym: &Symbol);
|
||||||
@ -37,6 +39,11 @@ fn iterator() {
|
|||||||
test_iterator(&Symbol::iterator());
|
test_iterator(&Symbol::iterator());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
async fn async_iterator() {
|
||||||
|
JsFuture::from(test_async_iterator(&Symbol::async_iterator())).await.unwrap_throw();
|
||||||
|
}
|
||||||
|
|
||||||
#[wasm_bindgen_test]
|
#[wasm_bindgen_test]
|
||||||
fn match_() {
|
fn match_() {
|
||||||
test_match(&Symbol::match_());
|
test_match(&Symbol::match_());
|
||||||
@ -89,12 +96,14 @@ fn key_for() {
|
|||||||
let sym = Symbol::for_("foo");
|
let sym = Symbol::for_("foo");
|
||||||
assert_eq!(Symbol::key_for(&sym), "foo");
|
assert_eq!(Symbol::key_for(&sym), "foo");
|
||||||
assert!(Symbol::key_for(&Symbol::iterator()).is_undefined());
|
assert!(Symbol::key_for(&Symbol::iterator()).is_undefined());
|
||||||
|
assert!(Symbol::key_for(&Symbol::async_iterator()).is_undefined());
|
||||||
assert!(Symbol::key_for(&gensym(JsValue::undefined())).is_undefined());
|
assert!(Symbol::key_for(&gensym(JsValue::undefined())).is_undefined());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen_test]
|
#[wasm_bindgen_test]
|
||||||
fn to_string() {
|
fn to_string() {
|
||||||
assert_eq!(Symbol::iterator().to_string(), "Symbol(Symbol.iterator)");
|
assert_eq!(Symbol::iterator().to_string(), "Symbol(Symbol.iterator)");
|
||||||
|
assert_eq!(Symbol::async_iterator().to_string(), "Symbol(Symbol.asyncIterator)");
|
||||||
assert_eq!(Symbol::for_("foo").to_string(), "Symbol(foo)");
|
assert_eq!(Symbol::for_("foo").to_string(), "Symbol(foo)");
|
||||||
assert_eq!(gensym("desc".into()).to_string(), "Symbol(desc)");
|
assert_eq!(gensym("desc".into()).to_string(), "Symbol(desc)");
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ error[E0277]: the trait bound `wasm_bindgen::JsValue: std::convert::From<BadType
|
|||||||
<wasm_bindgen::JsValue as std::convert::From<&'a std::string::String>>
|
<wasm_bindgen::JsValue as std::convert::From<&'a std::string::String>>
|
||||||
<wasm_bindgen::JsValue as std::convert::From<&'a str>>
|
<wasm_bindgen::JsValue as std::convert::From<&'a str>>
|
||||||
<wasm_bindgen::JsValue as std::convert::From<MyType>>
|
<wasm_bindgen::JsValue as std::convert::From<MyType>>
|
||||||
and 61 others
|
and 62 others
|
||||||
= note: required because of the requirements on the impl of `std::convert::Into<wasm_bindgen::JsValue>` for `BadType`
|
= note: required because of the requirements on the impl of `std::convert::Into<wasm_bindgen::JsValue>` for `BadType`
|
||||||
= note: required because of the requirements on the impl of `wasm_bindgen::__rt::IntoJsResult` for `BadType`
|
= note: required because of the requirements on the impl of `wasm_bindgen::__rt::IntoJsResult` for `BadType`
|
||||||
= note: required by `wasm_bindgen::__rt::IntoJsResult::into_js_result`
|
= note: required by `wasm_bindgen::__rt::IntoJsResult::into_js_result`
|
||||||
|
Loading…
x
Reference in New Issue
Block a user