Hi all,
I'm very new to rust and of course, I'm stuck with an ownership issue, what I want to achieve is very simple, I have a function which waits on an IMAP inbox using the IDLE command and when something changes it shows a desktop notification.
My issue is that sometimes the IDLE fails because of the server resetting the connection and I of course try to reconnect to handle this error.
fn notify_idle(config: Arc<Box<Config>>, mbox: &str) -> Result<(), String> {
let mut imap_session = connect(&config)?;
imap_session.select(&mbox).map_err(|err| err.to_string())?;
list_unseen(&mut imap_session, mbox);
if !config.wait_idle {
imap_session.logout().map_err(|err| err.to_string())?;
Ok(())
} else {
loop {
info!("Waiting for new messages on maibox {}", mbox);
let mut idle = match imap_session.idle() {
Ok(i) => i,
Err(e) => {
error!("{}", e);
let mut idle;
loop {
imap_session = connect(&config)?;
imap_session.select(&mbox).map_err(|err| err.to_string())?;
idle = imap_session.idle();
if idle.is_ok() {
break;
}
}
idle.unwrap()
}
};
idle.set_keepalive(Duration::from_secs(60) * 15);
idle.wait_keepalive().map_err(|err| err.to_string())?;
list_unseen(&mut imap_session, mbox);
thread::sleep(Duration::from_secs(1));
}
}
}
rustc complains because I'm obviously violating the ownership rules but I really don't know how to solve this in a idiomatic way. Any help please?
error[E0506]: cannot assign to `imap_session` because it is borrowed
--> src/main.rs:117:25
|
110 | let mut idle = match imap_session.idle() {
| -------------------
| |
| borrow of `imap_session` occurs here
| a temporary with access to the borrow is created here ...
...
117 | imap_session = connect(&config)?;
| ^^^^^^^^^^^^ assignment to borrowed `imap_session` occurs here
...
126 | };
| - ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `std::result::Result<imap::extensions::idle::Handle<'_, native_tls::TlsStream<std::net::TcpStream>>, imap::error::Error>`
error[E0499]: cannot borrow `imap_session` as mutable more than once at a time
--> src/main.rs:118:25
|
110 | let mut idle = match imap_session.idle() {
| -------------------
| |
| first mutable borrow occurs here
| a temporary with access to the first borrow is created here ...
...
118 | imap_session.select(&mbox).map_err(|err| err.to_string())?;
| ^^^^^^^^^^^^ second mutable borrow occurs here
...
126 | };
| - ... and the first borrow might be used here, when that temporary is dropped and runs the destructor for type `std::result::Result<imap::extensions::idle::Handle<'_, native_tls::TlsStream<std::net::TcpStream>>, imap::error::Error>`