How to store reference in struct


#1

I am following below tutorial to use diesel with rocket

https://rocket.rs/guide/state/#databases

I am trying to create a User Repository . However, I am not able to figure out how can I store the reference to MysqlConnection in my MysqlUserRepo struct . So that I don’t have to pass the connection to register_user function and only pass the user_repo.

pub trait UserRepo{
    fn find_user_by_loginid(&self, loginid: LoginId) -> Option<User>;
}


struct MysqlUserRepo {
    connection : Box<&'MysqlConnection>
}

impl MysqlUserRepo{
    fn new(conn : &MysqlConnection) -> MysqlUserRepo{
        MysqlUserRepo {
            connection : Box::new(conn)
        }
    }
}

impl UserRepo for MysqlUserRepo{
    fn find_user_by_loginid(&self, loginid : LoginId) -> Option<User>{
        use adapter::db::mysql::schema::member::dsl::*;
        let mut members = member
                        .filter(login.eq(loginid))
                        .load::<Member>(&*self.connection)
                        .expect("Error loading members");
        if members.len() > 0 {
            let m = members.pop().unwrap();
            Some(User {
                loginid : m.login,
                email : m.email,
                password : m.password,
                status : UserStatus::Incomplete
            })
        }else{
            None
        }
    }
}

#[post("/user", format = "application/json", data = "<create_user_request>")]
fn register_user_handler(conn: DbConn, create_user_request: Json<CreateUserRequest>) -> Json<CreateUserResponse> {
    let create_user_input = CreateUserInput::from(create_user_request.0);
    let user_repo = MysqlUserRepo::new(&*conn);
    let create_user_output = register_user(create_user_input, user_repo);
    let create_user_response = CreateUserResponse {
        status : "success".to_owned()
    };
    Json(create_user_response)
}

Getting following error

error: expected type, found `>`
  --> src/api.rs:15:39
   |
15 |     connection : Box<&'MysqlConnection>
   |                                       ^

error[E0560]: struct `MysqlUserRepo` has no field named `connection`
  --> src/api.rs:21:13
   |
21 |             connection : Box::new(conn)
   |             ^^^^^^^^^^^^ `MysqlUserRepo` does not have this field

error[E0609]: no field `connection` on type `&MysqlUserRepo`
  --> src/api.rs:31:48
   |
31 |                         .load::<Member>(&*self.connection)
   |                                                ^^^^^^^^^^

error: aborting due to 3 previous errors

#2

Check out this chapter on lifetimes which covers the main points of storing borrowed data in a struct.


#3

This doesn’t make a lot of sense, it isn’t valid syntax. You’d either want:

struct MysqlUserRepo<'a> {
    connection : &'a MysqlConnection
}

Which keels the connection on the stack and ensures the MysqlUserRepo has to be destroyed before the connection. Alternatively:

struct MysqlUserRepo {
    connection : Box<MysqlConnection>
}

This takes ownership of Connection though, but that’s probably not what you want, as it can’t be shared.