resynth/
object.rs

1use std::any::Any;
2use std::cell::{Ref, RefCell, RefMut};
3use std::fmt::Debug;
4use std::ops::Deref;
5use std::rc::Rc;
6
7use crate::libapi::Class;
8use crate::sym::Symbol;
9use crate::traits::Dispatchable;
10
11pub trait Obj: Class + Debug + Dispatchable {
12    fn as_any(&self) -> &dyn Any;
13    fn as_mut_any(&mut self) -> &mut dyn Any;
14    fn equals_obj(&self, _: &dyn Obj) -> bool;
15}
16
17impl<T: 'static + PartialEq + Eq + Class + Debug> Obj for T {
18    fn as_any(&self) -> &dyn Any {
19        self
20    }
21
22    fn as_mut_any(&mut self) -> &mut dyn Any {
23        self
24    }
25
26    fn equals_obj(&self, other: &dyn Obj) -> bool {
27        other
28            .as_any()
29            .downcast_ref::<T>()
30            .map_or(false, |a| self == a)
31    }
32}
33
34impl<T: Obj> Dispatchable for T {
35    fn lookup_symbol(&self, name: &str) -> Option<Symbol> {
36        self.symbols().get(name).copied()
37    }
38}
39
40#[derive(Debug, Clone)]
41pub struct ObjRef {
42    inner: Rc<RefCell<dyn Obj>>,
43}
44
45impl From<Rc<RefCell<dyn Obj>>> for ObjRef {
46    fn from(obj: Rc<RefCell<dyn Obj>>) -> Self {
47        Self { inner: obj }
48    }
49}
50
51impl<T: 'static + Obj> From<T> for ObjRef {
52    fn from(obj: T) -> Self {
53        Self {
54            inner: Rc::new(RefCell::new(obj)),
55        }
56    }
57}
58
59impl Eq for ObjRef {}
60impl PartialEq for ObjRef {
61    fn eq(&self, other: &ObjRef) -> bool {
62        self.inner.borrow().equals_obj(other.inner.borrow().deref())
63    }
64}
65
66impl Dispatchable for ObjRef {
67    fn lookup_symbol(&self, name: &str) -> Option<Symbol> {
68        self.inner.borrow().lookup_symbol(name)
69    }
70}
71
72impl ObjRef {
73    pub fn borrow(&self) -> Ref<dyn Obj> {
74        self.inner.borrow()
75    }
76
77    pub fn borrow_mut(&self) -> RefMut<dyn Obj> {
78        self.inner.borrow_mut()
79    }
80}