boa_engine/object/builtins/
jsgeneratorfunction.rs1use crate::{
3 Context, JsNativeError, JsResult, JsValue,
4 builtins::function::OrdinaryFunction,
5 object::{JsObject, builtins::JsGenerator},
6 value::TryFromJs,
7};
8use boa_gc::{Finalize, Trace};
9use std::ops::Deref;
10
11#[derive(Debug, Clone, Trace, Finalize)]
13pub struct JsGeneratorFunction {
14 inner: JsObject,
15}
16
17impl JsGeneratorFunction {
18 #[inline]
25 pub fn from_object(object: JsObject) -> JsResult<Self> {
26 if object
27 .downcast_ref::<OrdinaryFunction>()
28 .is_some_and(|f| f.code.is_generator() && !f.code.is_async())
29 {
30 Ok(Self { inner: object })
31 } else {
32 Err(JsNativeError::typ()
33 .with_message("object is not a GeneratorFunction")
34 .into())
35 }
36 }
37
38 pub fn call(
45 &self,
46 this: &JsValue,
47 args: &[JsValue],
48 context: &mut Context,
49 ) -> JsResult<JsGenerator> {
50 let value = self.inner.call(this, args, context)?;
51 let obj = value
52 .as_object()
53 .ok_or_else(|| {
54 JsNativeError::typ().with_message("generator function did not return an object")
55 })?
56 .clone();
57 JsGenerator::from_object(obj)
58 }
59}
60
61impl From<JsGeneratorFunction> for JsObject {
62 #[inline]
63 fn from(o: JsGeneratorFunction) -> Self {
64 o.inner.clone()
65 }
66}
67
68impl From<JsGeneratorFunction> for JsValue {
69 #[inline]
70 fn from(o: JsGeneratorFunction) -> Self {
71 o.inner.clone().into()
72 }
73}
74
75impl Deref for JsGeneratorFunction {
76 type Target = JsObject;
77 #[inline]
78 fn deref(&self) -> &Self::Target {
79 &self.inner
80 }
81}
82
83impl TryFromJs for JsGeneratorFunction {
84 fn try_from_js(value: &JsValue, _context: &mut Context) -> JsResult<Self> {
85 if let Some(o) = value.as_object() {
86 Self::from_object(o.clone())
87 } else {
88 Err(JsNativeError::typ()
89 .with_message("value is not a GeneratorFunction object")
90 .into())
91 }
92 }
93}