use std::{fmt, ops::Deref};
use fmt::Debug;
use crate::{
class::{ClassKind, ClassRef},
impl_class,
memory::MemoryLayout,
type_context::TypeContext,
ObjectPayload, ObjectProperties, Type,
};
pub trait HasClass {
fn create_properties(ctx: &TypeContext) -> ObjectProperties
where
Self: Sized;
fn static_class(ctx: &TypeContext) -> ClassRef
where
Self: Sized;
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct ObjClass {
pub class: ClassRef,
}
impl_class! {ObjClass, Type::Type, {
CmpEq => |this: &ObjClass, other: &ObjClass| -> bool {
this == other
}
}}
impl ObjClass {
pub fn new(value: ClassRef) -> Self {
ObjClass { class: value }
}
}
impl Deref for ObjClass {
type Target = ClassRef;
fn deref(&self) -> &Self::Target {
&self.class
}
}
impl From<ClassRef> for ObjClass {
fn from(value: ClassRef) -> Self {
ObjClass::new(value)
}
}
impl ObjectPayload for ObjClass {
fn memory_layout(&self) -> &MemoryLayout {
&MemoryLayout::Unsized
}
fn get_property(
&self,
_ctx: &TypeContext,
ident: &debris_common::Ident,
) -> Option<crate::ObjectRef> {
match &self.class.kind {
ClassKind::Struct(strukt) | ClassKind::StructValue(strukt) => strukt
.namespace
.get()
.and_then(|map| map.get(ident).cloned()),
ClassKind::Tuple(_)
| ClassKind::TupleValue(_)
| ClassKind::Function(_)
| ClassKind::Type(_) => None,
}
}
}
impl fmt::Display for ObjClass {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.class, f)
}
}