#[macro_export]
macro_rules! objt {
($name:ident, $weakname:ident, $inner:ident, $($member:ident: $member_type:ty),* ) => {
#[derive(Clone)]
pub struct $name(std::rc::Rc<std::cell::RefCell<$inner>>);
pub struct $weakname(std::rc::Weak<std::cell::RefCell<$inner>>);
impl $name {
pub(crate) fn from_inner(inner: $inner) -> Self {
$name(std::rc::Rc::new(std::cell::RefCell::new(inner)))
}
#[track_caller]
pub(crate) fn borrow(&self) -> std::cell::Ref<$inner> {
(*self.0).borrow()
}
#[track_caller]
pub(crate) fn borrow_mut(&self) -> std::cell::RefMut<$inner> {
(*self.0).borrow_mut()
}
pub fn clone_ref(&self) -> Self {
$name(self.0.clone())
}
$(pub(crate) fn $member(&self) -> $member_type {
self.borrow().$member.clone()
})*
pub fn as_weak(&self) -> $weakname {
$weakname(std::rc::Rc::downgrade(&self.0))
}
pub fn in_future<F: futures::Future, FC: FnOnce($name) -> F>(&self, f: FC) -> F {
f(self.clone_ref())
}
}
impl $weakname {
pub(crate) fn upgrade(&self) -> Option<$name> {
self.0.upgrade().map($name)
}
}
};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
pub struct TestInner {
a: u32,
b: u32,
}
objt!(Test, WeakTest, TestInner, a: u32, b: u32);
let test = Test::from_inner(TestInner { a: 1, b: 2 });
println!("a: {}, b: {}", test.a(), test.b());
}
}