How to downcast Rc<RefCell<dyn Trait>>?

RefCell<ConcreteType> implements Any, so one approach would be to store that inside Rc<dyn Any> and then use Rc::downcast::<RefCell<ConcreteType>>> to recover the cell.

Alternatively, if Trait: Any, you can borrow the RefCell and downcast the resulting reference with Any::downcast or Any::downcast_mut:

use std::any::{Any,TypeId};
use std::cell::{RefCell, Ref, RefMut};

pub fn borrow_downcast<T: Any>(cell: &RefCell<dyn Any>)->Option<Ref<T>> {
    let r = cell.borrow();
    if (*r).type_id() == TypeId::of::<T>() {
        Some(Ref::map(r, |x| x.downcast_ref::<T>().unwrap()))
    } else {
        None
    }
}

pub fn borrow_downcast_mut<T: Any>(cell: &RefCell<dyn Any>)->Option<RefMut<T>> {
    let r = cell.borrow_mut();
    if (*r).type_id() == TypeId::of::<T>() {
        Some(RefMut::map(r, |x| x.downcast_mut::<T>().unwrap()))
    } else {
        None
    }
}
2 Likes