use std::fmt::{self, Debug, Display}; use gc::{Finalize, Trace}; use crate::obj::macros::*; use crate::obj::prelude::*; use crate::obj::BaseObj; use crate::vm::Vm; #[derive(Trace, Finalize)] pub struct Bool { base: BaseObj, bool_value: bool, } impl Bool { pub fn new(bool_value: bool) -> Self { Self { bool_value, base: Default::default(), } } impl_create!(bool_value: bool); pub fn bool_value(&self) -> bool { self.bool_value } } impl Display for Bool { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "{}", self.bool_value) } } impl Debug for Bool { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "{}", self.bool_value) } } impl Object for Bool { fn is_truthy(&self) -> bool { self.bool_value } fn equals(&self, other: &dyn Object) -> bool { if let Some(other) = other.as_any().downcast_ref::() { self.bool_value == other.bool_value } else { false } } impl_base_obj!(Bool); } impl Bool { impl_do_call!(to_bool); pub(crate) fn init(_vm: &mut Vm, _state: FunctionState) -> FunctionResult { // This is a no-op. We don't want the user-exposed `__init__` function to do anything, // instantiation is done in the `__call__` function. FunctionResult::ReturnPush(Nil::create()) } pub(crate) fn to_int(vm: &mut Vm, _state: FunctionState) -> FunctionResult { let bool_value = with_obj_downcast(vm.frame_stack()[0].clone(), Bool::bool_value); Int::create(bool_value as i64).into() } pub(crate) fn to_float(vm: &mut Vm, _state: FunctionState) -> FunctionResult { let bool_value = with_obj_downcast(vm.frame_stack()[0].clone(), Bool::bool_value); Float::create(bool_value as i64 as f64).into() } }