Search code examples
rustrust-dieselgtk-rs

How to use Diesel connection and Gtk-rs events?


I am trying to do a get a object from a database with Diesel when the Enter key is pressed in a gtk Entry. My idea is to create a Diesel SQLite connection in main function and then borrow it every time that I need it.

To do that, I am trying to use a very simple MVC. The idea is to pass the connection to all the controllers and reuse it. I know that lifetime is necessary here.

pub struct Controller<'a> {
    pub connection: &'a SQLiteConnection,
    pub search_entry: SearchEntry,
    ....
}

impl<'a> Controller<'a> {

    pub fn new(conn: &'a SQLiteConnection) -> Self {
        Self {
            search_entry: SearchEntry::new(),
            connection: conn,
            ....
        }
    }

    pub fn init(&self) {
        self.search_entry.connect_activate(|x| {
            let need_it = diesel_table
            .filter(column_id.eq(&x.get_text().unwrap()))
            .first(self.connection)
            .unwrap();
        });
    }
}

When compile I get this:

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
  --> src/lib.rs:44:44
   |
44 |           self.search_entry.connect_activate(|x| {
   |  ____________________________________________^
45 | |             let need_it = diesel_table
46 | |                 .filter(column_id.eq(&x.get_text().unwrap()))
47 | |                 .first(self.connection)
48 | |                 .unwrap();
49 | |         });
   | |_________^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 43:5...
  --> src/lib.rs:43:5
   |
43 | /     pub fn init(&self) {
44 | |         let need_it = diesel_table
46 | |                 .filter(column_id.eq(&x.get_text().unwrap()))
47 | |                 .first(self.connection)
48 | |                 .unwrap();
49 | |         });
50 | |     }
   | |_____^
note: ...so that the types are compatible
  --> src/lib.rs:44:44
   |
44 |           self.search_entry.connect_activate(|x| {
   |  ____________________________________________^
45 | |             let need_it = diesel_table
46 | |                 .filter(column_id.eq(&x.get_text().unwrap()))
47 | |                 .first(self.connection)
48 | |                 .unwrap();
49 | |         });
   | |_________^
   = note: expected  `&&Controller<'_>`
              found  `&&Controller<'a>`
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `[closure@src/lib.rs:44:44: 49:10 self:&&Controller<'_>]` will meet its required lifetime bounds
  --> src/lib.rs:44:27
   |
44 |         self.search_entry.connect_activate(|x| {
   |                           ^^^^^^^^^^^^^^^^

This error is because the function connect_activate has a static parameter: fn connect_activate<F: Fn(&Self) + 'static>.

I would not like to initialize the connection every time that the user press the Intro key by using a function that returns a connection. Instead I would like to borrow that connection.

What would be the most efficient way to do that?

Thanks you very much. I hope you understand everything.


Solution

  • I think you need a Rc<SQLiteConnection>