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