Making a Rc<RefCell<Trait2>> from Rc<RefCell<Trait1>>


#1

I am having problems downcasting a trait inside a Rc and a RefCell. My code reads as follows.

pub trait Eventful
{
	// ... some methods
}

#[derive(Clone)]
pub enum Event
{
	// ... other events,
	Generic(Rc<RefCell<Eventful>>),
}

pub trait Router: Eventful
{
	// ... more methods
}

struct Network
{
	// ... other fields
	routers: Vec<Rc<RefCell<Router>>>,
}

Then with this I get an error[E0308]: mismatched types.

Event::Generic(network.routers[router])

And with this I get an error[E0605]: non-primitive cast.

Event::Generic(network.routers[router] as Rc<RefCell<Eventful>>)

Can I resolve this cast?


#2

Crosscasting, the bottom paragraph; (note: embedding with stripped space sucks.)


#3

Thanks jonh. It works. I am not completely comfortable with having to store a pointer to yourself, but it is fine.

The working code, for if it is useful to anyone.

struct BasicRouter
{
	self_rc: Weak<RefCell<BasicRouter>>,
	//... fields
}
impl BasicRouter
{
	fn new(cv:&ConfigurationValue) -> Rc<RefCell<BasicRouter>>
	{
		//... many things
		let r=Rc::new(RefCell::new(BasicRouter{
			self_rc: Weak::new(),
			//... other fields
		}));
		//r.borrow_mut().self_rc=r.downgrade();//Why does not this work?
		r.borrow_mut().self_rc=Rc::<_>::downgrade(&r);
		r
	}
}
pub trait Eventful
{
	// ...  methods
	fn as_eventful(&self)->Weak<RefCell<Eventful>>;
}
impl Eventful for BasicRouter
{
	// ... implementations
	fn as_eventful(&self)->Weak<RefCell<Eventful>>
	{
		self.self_rc.clone()
	}
}
let mut brouter=network.routers[router].borrow_mut();
Event::Generic(brouter.as_eventful().upgrade().expect("missing router"))

#4

Because downgrade is an associated function, not a method (it doesn’t take &self).

I must say it’s a bit odd, conceptually, to return a Weak referencing self from a method that has self as the receiver.