use std::any::Any;
use std::fmt;
use cljrs_gc::{GcPtr, MarkVisitor, Trace};
pub trait NativeObject: Send + Sync + fmt::Debug + Trace + 'static {
fn type_tag(&self) -> &str;
fn as_any(&self) -> &dyn Any;
}
#[derive(Debug)]
pub struct NativeObjectBox {
inner: Box<dyn NativeObject>,
}
impl NativeObjectBox {
pub fn new(obj: impl NativeObject) -> Self {
Self {
inner: Box::new(obj),
}
}
pub fn type_tag(&self) -> &str {
self.inner.type_tag()
}
pub fn downcast_ref<T: NativeObject>(&self) -> Option<&T> {
self.inner.as_any().downcast_ref::<T>()
}
pub fn inner(&self) -> &dyn NativeObject {
&*self.inner
}
}
impl Trace for NativeObjectBox {
fn trace(&self, visitor: &mut MarkVisitor) {
self.inner.trace(visitor);
}
}
pub fn gc_native_object(obj: impl NativeObject) -> GcPtr<NativeObjectBox> {
GcPtr::new(NativeObjectBox::new(obj))
}