Skip to main content

boa_engine/object/builtins/
jsasyncgenerator.rs

1//! A Rust API wrapper for Boa's `AsyncGenerator` Builtin ECMAScript Object
2use super::JsPromise;
3use crate::{
4    Context, JsNativeError, JsResult, JsValue,
5    builtins::{async_generator::AsyncGenerator, promise::PromiseCapability},
6    js_error,
7    object::JsObject,
8    value::TryFromJs,
9};
10use boa_gc::{Finalize, Trace};
11use std::ops::Deref;
12
13/// `JsAsyncGenerator` provides a wrapper for Boa's implementation of the ECMAScript `AsyncGenerator` builtin object.
14#[derive(Debug, Clone, Trace, Finalize)]
15#[boa_gc(unsafe_no_drop)]
16pub struct JsAsyncGenerator {
17    inner: JsObject<AsyncGenerator>,
18}
19
20impl JsAsyncGenerator {
21    /// Creates a `JsAsyncGenerator` from an async generator `JsObject`.
22    ///
23    /// More information:
24    ///  - [MDN documentation][mdn]
25    ///
26    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncGenerator
27    #[inline]
28    pub fn from_object(object: JsObject) -> JsResult<Self> {
29        object
30            .downcast::<AsyncGenerator>()
31            .map(|inner| Self { inner })
32            .map_err(|_| js_error!(TypeError: "object is not an AsyncGenerator object"))
33    }
34
35    /// Calls `AsyncGenerator.prototype.next()`.
36    ///
37    /// More information:
38    ///  - [MDN documentation][mdn]
39    ///
40    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncGenerator/next
41    pub fn next<T>(&self, value: T, context: &mut Context) -> JsResult<JsPromise>
42    where
43        T: Into<JsValue>,
44    {
45        let (typed_promise, functions) = JsPromise::new_pending(context);
46        let capability = PromiseCapability {
47            functions,
48            promise: JsObject::clone(&typed_promise).clone().upcast(),
49        };
50        AsyncGenerator::inner_next(&self.inner, capability, value.into(), context)?;
51
52        Ok(typed_promise)
53    }
54
55    /// Calls `AsyncGenerator.prototype.return()`.
56    ///
57    /// More information:
58    ///  - [MDN documentation][mdn]
59    ///
60    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncGenerator/return
61    pub fn r#return<T>(&self, value: T, context: &mut Context) -> JsResult<JsPromise>
62    where
63        T: Into<JsValue>,
64    {
65        let (typed_promise, functions) = JsPromise::new_pending(context);
66        let capability = PromiseCapability {
67            functions,
68            promise: JsObject::clone(&typed_promise).upcast(),
69        };
70        AsyncGenerator::inner_return(&self.inner, capability, value.into(), context)?;
71        Ok(typed_promise)
72    }
73
74    /// Calls `AsyncGenerator.prototype.throw()`.
75    ///
76    /// More information:
77    ///  - [MDN documentation][mdn]
78    ///
79    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncGenerator/throw
80    pub fn throw<T>(&self, value: T, context: &mut Context) -> JsResult<JsPromise>
81    where
82        T: Into<JsValue>,
83    {
84        let (typed_promise, functions) = JsPromise::new_pending(context);
85        let capability = PromiseCapability {
86            functions,
87            promise: JsObject::clone(&typed_promise).clone().upcast(),
88        };
89        AsyncGenerator::inner_throw(&self.inner, capability, value.into(), context)?;
90        Ok(typed_promise)
91    }
92}
93
94impl From<JsAsyncGenerator> for JsObject {
95    #[inline]
96    fn from(o: JsAsyncGenerator) -> Self {
97        o.inner.upcast()
98    }
99}
100
101impl From<JsAsyncGenerator> for JsValue {
102    #[inline]
103    fn from(o: JsAsyncGenerator) -> Self {
104        o.inner.clone().into()
105    }
106}
107
108impl Deref for JsAsyncGenerator {
109    type Target = JsObject<AsyncGenerator>;
110
111    #[inline]
112    fn deref(&self) -> &Self::Target {
113        &self.inner
114    }
115}
116
117impl TryFromJs for JsAsyncGenerator {
118    fn try_from_js(value: &JsValue, _context: &mut Context) -> JsResult<Self> {
119        if let Some(o) = value.as_object() {
120            Self::from_object(o.clone())
121        } else {
122            Err(JsNativeError::typ()
123                .with_message("value is not an AsyncGenerator object")
124                .into())
125        }
126    }
127}