boa/builtins/boolean/
mod.rs1#[cfg(test)]
13mod tests;
14
15use crate::{
16 builtins::BuiltIn,
17 context::StandardObjects,
18 object::{internal_methods::get_prototype_from_constructor, ConstructorBuilder, ObjectData},
19 property::Attribute,
20 BoaProfiler, Context, JsResult, JsValue,
21};
22
23#[derive(Debug, Clone, Copy)]
25pub(crate) struct Boolean;
26
27impl BuiltIn for Boolean {
28 const NAME: &'static str = "Boolean";
30
31 fn attribute() -> Attribute {
32 Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE
33 }
34
35 fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) {
36 let _timer = BoaProfiler::global().start_event(Self::NAME, "init");
37
38 let boolean_object = ConstructorBuilder::with_standard_object(
39 context,
40 Self::constructor,
41 context.standard_objects().boolean_object().clone(),
42 )
43 .name(Self::NAME)
44 .length(Self::LENGTH)
45 .method(Self::to_string, "toString", 0)
46 .method(Self::value_of, "valueOf", 0)
47 .build();
48
49 (Self::NAME, boolean_object.into(), Self::attribute())
50 }
51}
52
53impl Boolean {
54 pub(crate) const LENGTH: usize = 1;
56
57 pub(crate) fn constructor(
61 new_target: &JsValue,
62 args: &[JsValue],
63 context: &mut Context,
64 ) -> JsResult<JsValue> {
65 let data = args.get(0).map(|x| x.to_boolean()).unwrap_or(false);
67 if new_target.is_undefined() {
68 return Ok(JsValue::new(data));
69 }
70 let prototype =
71 get_prototype_from_constructor(new_target, StandardObjects::boolean_object, context)?;
72 let boolean = JsValue::new_object(context);
73
74 boolean
75 .as_object()
76 .expect("this should be an object")
77 .set_prototype_instance(prototype.into());
78 boolean.set_data(ObjectData::boolean(data));
79
80 Ok(boolean)
81 }
82
83 fn this_boolean_value(value: &JsValue, context: &mut Context) -> JsResult<bool> {
90 match value {
91 JsValue::Boolean(boolean) => return Ok(*boolean),
92 JsValue::Object(ref object) => {
93 let object = object.borrow();
94 if let Some(boolean) = object.as_boolean() {
95 return Ok(boolean);
96 }
97 }
98 _ => {}
99 }
100
101 Err(context.construct_type_error("'this' is not a boolean"))
102 }
103
104 #[allow(clippy::wrong_self_convention)]
113 pub(crate) fn to_string(
114 this: &JsValue,
115 _: &[JsValue],
116 context: &mut Context,
117 ) -> JsResult<JsValue> {
118 let boolean = Self::this_boolean_value(this, context)?;
119 Ok(JsValue::new(boolean.to_string()))
120 }
121
122 #[inline]
131 pub(crate) fn value_of(
132 this: &JsValue,
133 _: &[JsValue],
134 context: &mut Context,
135 ) -> JsResult<JsValue> {
136 Ok(JsValue::new(Self::this_boolean_value(this, context)?))
137 }
138}