boa_engine/builtins/boolean/
mod.rs1#[cfg(test)]
13mod tests;
14
15use crate::{
16 Context, JsResult, JsString, JsValue,
17 builtins::BuiltInObject,
18 context::intrinsics::{Intrinsics, StandardConstructor, StandardConstructors},
19 error::JsNativeError,
20 js_string,
21 object::{JsObject, internal_methods::get_prototype_from_constructor},
22 realm::Realm,
23 string::StaticJsStrings,
24};
25
26use super::{BuiltInBuilder, BuiltInConstructor, IntrinsicObject};
27
28#[derive(Debug, Clone, Copy)]
30pub(crate) struct Boolean;
31
32impl IntrinsicObject for Boolean {
33 fn init(realm: &Realm) {
34 BuiltInBuilder::from_standard_constructor::<Self>(realm)
35 .method(Self::to_string, js_string!("toString"), 0)
36 .method(Self::value_of, js_string!("valueOf"), 0)
37 .build();
38 }
39
40 fn get(intrinsics: &Intrinsics) -> JsObject {
41 Self::STANDARD_CONSTRUCTOR(intrinsics.constructors()).constructor()
42 }
43}
44
45impl BuiltInObject for Boolean {
46 const NAME: JsString = StaticJsStrings::BOOLEAN;
47}
48
49impl BuiltInConstructor for Boolean {
50 const CONSTRUCTOR_ARGUMENTS: usize = 1;
51 const PROTOTYPE_STORAGE_SLOTS: usize = 2;
52 const CONSTRUCTOR_STORAGE_SLOTS: usize = 0;
53
54 const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor =
55 StandardConstructors::boolean;
56
57 fn constructor(
61 new_target: &JsValue,
62 args: &[JsValue],
63 context: &mut Context,
64 ) -> JsResult<JsValue> {
65 let data = args.first().is_some_and(JsValue::to_boolean);
67 if new_target.is_undefined() {
68 return Ok(JsValue::new(data));
69 }
70 let prototype =
71 get_prototype_from_constructor(new_target, StandardConstructors::boolean, context)?;
72 let boolean =
73 JsObject::from_proto_and_data_with_shared_shape(context.root_shape(), prototype, data);
74
75 Ok(boolean.into())
76 }
77}
78
79impl Boolean {
80 fn this_boolean_value(value: &JsValue) -> JsResult<bool> {
87 value
88 .as_boolean()
89 .or_else(|| {
90 value
91 .as_object()
92 .and_then(|obj| obj.downcast_ref::<bool>().as_deref().copied())
93 })
94 .ok_or_else(|| {
95 JsNativeError::typ()
96 .with_message("'this' is not a boolean")
97 .into()
98 })
99 }
100
101 #[allow(clippy::wrong_self_convention)]
110 pub(crate) fn to_string(this: &JsValue, _: &[JsValue], _: &mut Context) -> JsResult<JsValue> {
111 let boolean = Self::this_boolean_value(this)?;
112 Ok(JsValue::new(if boolean {
113 js_string!("true")
114 } else {
115 js_string!("false")
116 }))
117 }
118
119 pub(crate) fn value_of(this: &JsValue, _: &[JsValue], _: &mut Context) -> JsResult<JsValue> {
128 Ok(JsValue::new(Self::this_boolean_value(this)?))
129 }
130}