I am stuck with mutable struct

Hi Rusters,

I am trying to understand mutable structs. So let's say I have a struct, and I want to get the value of that struct but it doesn't work.

pub struct DataService {
    _cfg: ServiceRef<ConfigService>,
    _db: Option<DatabaseConnection>,
}

#[injectable]
impl DataService {
    pub fn new(cfg: ServiceRef<ConfigService>) -> Self {
        return Self { _cfg: cfg, _db: None };
    }

    pub async fn db(&mut self) -> &DatabaseConnection {
        if let None = &self._db {
            self._db.replace(connect(self._cfg.db_type.clone()).await.expect("Database connection failed."));
        }
        return self._db.as_ref().unwrap();
    }
}
pub struct MigratorService {
    data: ServiceRef<DataService>,
}

#[injectable]
impl MigratorService {
    fn new(data: ServiceRef<DataService>) -> Self {
        return Self { data };
    }

    pub async fn migrate_up(&self) {
        let db = self.data.db().await; // Error: cannot borrow data in an `Rc` as mutable trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Rc<DataService>`rustcE0596
        migrate_up(db).await.expect("Migration failed.");
    }
}

Looks like the self.data.db() requires a mutable reference, but the code pub async fn migrate_up(&mut self) does not work ether.

Or it could be related to the ServiceRef, which is pub type ServiceRef<T> = std::rc::Rc<T>;. It probably goes to the level I must understand reference counters first before to code in Rust.

You can't mutate through an Rc by default; if you could, that would lead to exactly the kind of shared mutability that is not memory safe and that Rust is trying to prevent. Therefore, you can only ever get a &T from an Rc<T>, even when you have mutable access to the Rc itself.

(There are workarounds for this involving interior mutability; e.g. you'll typically see Rc<RefCell<T>> as an idiom, but it's probably not the first thing you should try.)

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.