melib/imap: refactor early error exit

async
Manos Pitsidianakis 2020-01-15 12:33:05 +02:00
parent 7f8c638361
commit 56e3ea1548
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
1 changed files with 99 additions and 112 deletions

View File

@ -152,16 +152,6 @@ impl MailBackend for ImapType {
}
fn get(&mut self, folder: &Folder) -> Async<Result<Vec<Envelope>>> {
macro_rules! exit_on_error {
($tx:expr,$($result:expr)+) => {
$(if let Err(e) = $result {
$tx.send(AsyncStatus::Payload(Err(e.into()))).unwrap();
$tx.send(AsyncStatus::Finished).unwrap();
return;
})+
};
};
let mut w = AsyncBuilder::new();
let handle = {
let tx = w.tx();
@ -186,21 +176,18 @@ impl MailBackend for ImapType {
tx.send(AsyncStatus::Finished).unwrap();
return;
}
let _tx = tx.clone();
if let Err(err) = (move || {
let tx = _tx;
let mut response = String::with_capacity(8 * 1024);
let conn = connection.lock();
exit_on_error!(&tx, conn);
let mut conn = conn.unwrap();
let mut conn = connection.lock()?;
debug!("locked for get {}", folder_path);
/* first SELECT the mailbox to get READ/WRITE permissions (because EXAMINE only
* returns READ-ONLY for both cases) */
exit_on_error!(&tx,
conn.send_command(format!("SELECT \"{}\"", folder_path).as_bytes())
conn.read_response(&mut response)
);
let examine_response = protocol_parser::select_response(&response);
exit_on_error!(&tx, examine_response);
let examine_response = examine_response.unwrap();
conn.send_command(format!("SELECT \"{}\"", folder_path).as_bytes())?;
conn.read_response(&mut response)?;
let examine_response = protocol_parser::select_response(&response)?;
*can_create_flags.lock().unwrap() = examine_response.can_create_flags;
debug!(
"folder: {} examine_response: {:?}",
@ -226,26 +213,28 @@ impl MailBackend for ImapType {
*folder_exists = exists;
}
/* reselecting the same mailbox with EXAMINE prevents expunging it */
exit_on_error!(&tx,
conn.send_command(format!("EXAMINE \"{}\"", folder_path).as_bytes())
conn.read_response(&mut response)
);
conn.send_command(format!("EXAMINE \"{}\"", folder_path).as_bytes())?;
conn.read_response(&mut response)?;
let mut tag_lck = tag_index.write().unwrap();
let mut our_unseen = 0;
while exists > 1 {
let mut envelopes = vec![];
exit_on_error!(&tx,
conn.send_command(format!("UID FETCH {}:{} (UID FLAGS ENVELOPE BODYSTRUCTURE)", std::cmp::max(exists.saturating_sub(500), 1), exists).as_bytes())
conn.read_response(&mut response)
);
conn.send_command(
format!(
"UID FETCH {}:{} (UID FLAGS ENVELOPE BODYSTRUCTURE)",
std::cmp::max(exists.saturating_sub(500), 1),
exists
)
.as_bytes(),
)?;
conn.read_response(&mut response)?;
debug!(
"fetch response is {} bytes and {} lines",
response.len(),
response.lines().collect::<Vec<&str>>().len()
);
match protocol_parser::uid_fetch_responses(&response) {
Ok((_, v, _)) => {
let (_, v, _) = protocol_parser::uid_fetch_responses(&response)?;
debug!("responses len is {}", v.len());
for UidFetchResponse {
uid,
@ -280,12 +269,6 @@ impl MailBackend for ImapType {
uid_store.uid_index.lock().unwrap().insert(uid, env.hash());
envelopes.push(env);
}
}
Err(e) => {
debug!(&e);
tx.send(AsyncStatus::Payload(Err(e))).unwrap();
}
}
exists = std::cmp::max(exists.saturating_sub(500), 1);
debug!("sending payload");
@ -293,6 +276,10 @@ impl MailBackend for ImapType {
tx.send(AsyncStatus::Payload(Ok(envelopes))).unwrap();
}
drop(conn);
Ok(())
})() {
tx.send(AsyncStatus::Payload(Err(err))).unwrap();
}
tx.send(AsyncStatus::Finished).unwrap();
};
Box::new(closure)