How to create a Rc<RefCell<>> of a self-mutable reference?

pub struct VirtualTapInterface {
    mtu:    usize,
    packetsFromOutside: VecDeque<CBuffer>,
    packetsFromInside: VecDeque<CBuffer>
}

I'm implementing a trait for VirtualTapInterface. The receive function of this trait should create a TxToken struct, where the lower property must be an Rc<RefCell<VirtualTapInterface>> containing the current VirtualTapInterface, that is self

impl<'a> Device<'a> for VirtualTapInterface {
    type TxToken = TxToken;

    fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
                let tx = TxToken { lower: Rc::new(RefCell::new(*self))};

I tried this but I get that

cannot move out of *self which is behind a mutable reference

move occurs because *self has type
phy::virtual_tun::VirtualTapInterface, which does not implement the
Copy traitrustc(E0507)

How is it possible to create a Rc<RefCell<>> of a self mutable reference?

The best idea I has was to, instead of having VirtualTapInterface the way it is, I use this instead:

pub struct VirtualTapInterface {
    mtu:    usize,
    packetsFromOutside: Rc<RefCell<VecDeque<CBuffer>>>,
    packetsFromInside:Rc<RefCell<VecDeque<CBuffer>>>
}

this way I can clone the object like this:

let tx = TxToken { lower: Rc::new(RefCell::new(self.clone()))};

and end up with the same VecDeques as in self, since they're just references.

Anyone have a better idea? I cannot modify the trait, so I need it to receive a mut &

Does the TxToken need to reference self, or could it just have a Rc<RefCell<VecDeque>> member?

I think you read wrong.

pub struct TxToken {
    lower: Rc<RefCell<VirtualTunInterface>>,
}

Only thing in TxToken is the lower. I'm trying to put an Rc<RefCell<VirtualTunInterface>>.

The self is from VirtualTunInterface:

impl<'a> Device<'a> for VirtualTapInterface {
    type TxToken = TxToken;

    fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
                let tx = TxToken { lower: Rc::new(RefCell::new(*self))};

I realize all of that, but do you need TxToken to reference the interface? If you define it yourself, you could just as well define it as

pub struct TxToken {
    queue: Rc<RefCell<VecDeque>>,
}

or similar and avoid the double refcell.

I understood now. Yes, TxToken just needs to hold a reference to one VecDeque. So this is essentially the same solution that I thought:

pub struct VirtualTapInterface {
    mtu:    usize,
    packetsFromOutside: Rc<RefCell<VecDeque<CBuffer>>>,
    packetsFromInside:Rc<RefCell<VecDeque<CBuffer>>>
}

and cloning VirtualTapInterface inside TxToken into an Rc<RefCell<...>>

Do you agree?

If so, do you think it's ok to do this? I thought maybe there was an easier solution.

ps: if it's all ok I'll move to holding only the reference to the vecdeque, as there's no need to hold the entire VirtualTapInterface cloned reference

Yes, I think that's a fine solution.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.