1

I'm using the decorator pattern and find that while it works on a mutable reference, it doesn't work on an immutable one. Does anyone have a better idea?

pub struct Slave {
    pub is_drive: bool
}

impl Slave {
    fn is_drive(&self) -> bool {
        self.is_drive
    }
}

Drive is a decorator type of Slave.

pub struct Drive<'a> {
    pub slave: &'a mut Slave,
}

impl<'a> Drive<'a> {
    // Create drive.
    pub fn new(slave: &mut Slave) -> Drive {
        Drive {
            slave: slave,
        }
    }
}

Drive can only be used with a &mut Slave, but I'd like to get a &Drive from a &Slave:

fn main() {
    let s1 = &mut Slave { is_drive: true };
    let d1 = Drive::new(s1);

    // Doesn't work
    // let s2 = & Slave { is_drive: true };
    // let d2 = Drive::new(s2);
}

Edit:

Drive can only be used with a &mut Slave, but sometimes I need it for a &Slave. I don't use accessor functions because Slave should not depend on Drive:

fn config_slave(slave: &mut Slave) {
    ...
    if slave.is_drive() {
        let drive = Drive::new(slave) {
            // call functions provided by Drive
        }
    }
    ...
}

fn print_slave(slave: &Slave) {
    ...
    if slave.is_drive() {
       let drive = Drive::new(slave) {
           // Call functions provided by Drive
       }
    }
    ...
}
Cheng-Chang Wu
  • 187
  • 1
  • 7
  • Why did you define `pub slave: &'a mut Slave,` as mutable? Just change it to `pub slave: &'a Slave,`. Otherwise yes, this is likely to be a duplicate. – Shepmaster Jul 30 '17 at 13:45
  • 3
    Standard Library Example: `std::cell::Ref` and `std::cell::RefMut`. If the standard library authors do not manage to have a single type to handle both mutable and immutable access (at compile-time), chances are good that you won't... and if you do manage it, then please explain how you did and help improved the standard library! – Matthieu M. Jul 30 '17 at 15:59

1 Answers1

0

Taking std::cell::Ref and std::cell::RefMut as example, I will provide a Drive for &Slave and a DriveMut for &mut Slave.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Cheng-Chang Wu
  • 187
  • 1
  • 7