#[cfg(test)]
mod tests;
use crate::{
builtins::BuiltIn,
context::intrinsics::StandardConstructors,
object::{
internal_methods::get_prototype_from_constructor, ConstructorBuilder, JsObject, ObjectData,
},
Context, JsResult, JsValue,
};
use boa_profiler::Profiler;
use tap::{Conv, Pipe};
#[derive(Debug, Clone, Copy)]
pub(crate) struct Boolean;
impl BuiltIn for Boolean {
const NAME: &'static str = "Boolean";
fn init(context: &mut Context) -> Option<JsValue> {
let _timer = Profiler::global().start_event(Self::NAME, "init");
ConstructorBuilder::with_standard_constructor(
context,
Self::constructor,
context.intrinsics().constructors().boolean().clone(),
)
.name(Self::NAME)
.length(Self::LENGTH)
.method(Self::to_string, "toString", 0)
.method(Self::value_of, "valueOf", 0)
.build()
.conv::<JsValue>()
.pipe(Some)
}
}
impl Boolean {
pub(crate) const LENGTH: usize = 1;
pub(crate) fn constructor(
new_target: &JsValue,
args: &[JsValue],
context: &mut Context,
) -> JsResult<JsValue> {
let data = args.get(0).map_or(false, JsValue::to_boolean);
if new_target.is_undefined() {
return Ok(JsValue::new(data));
}
let prototype =
get_prototype_from_constructor(new_target, StandardConstructors::boolean, context)?;
let boolean = JsObject::from_proto_and_data(prototype, ObjectData::boolean(data));
Ok(boolean.into())
}
fn this_boolean_value(value: &JsValue, context: &mut Context) -> JsResult<bool> {
value
.as_boolean()
.or_else(|| value.as_object().and_then(|obj| obj.borrow().as_boolean()))
.ok_or_else(|| context.construct_type_error("'this' is not a boolean"))
}
#[allow(clippy::wrong_self_convention)]
pub(crate) fn to_string(
this: &JsValue,
_: &[JsValue],
context: &mut Context,
) -> JsResult<JsValue> {
let boolean = Self::this_boolean_value(this, context)?;
Ok(JsValue::new(boolean.to_string()))
}
#[inline]
pub(crate) fn value_of(
this: &JsValue,
_: &[JsValue],
context: &mut Context,
) -> JsResult<JsValue> {
Ok(JsValue::new(Self::this_boolean_value(this, context)?))
}
}