use async_imap::error::{Error, Result};
use async_std::prelude::*;
use async_imap::extensions::idle::IdleResponse::*;
use async_std::task;
use std::env;
use std::time::Duration;
fn main() -> Result<()> {
task::block_on(async {
let args: Vec<String> = env::args().collect();
if args.len() != 4 {
eprintln!("need three arguments: imap-server login password");
Err(Error::Bad("need three arguments".into()))
} else {
fetch_and_idle(&args[1], &args[2], &args[3]).await?;
Ok(())
}
})
}
async fn fetch_and_idle(imap_server: &str, login: &str, password: &str) -> Result<()> {
let tls = async_native_tls::TlsConnector::new();
let client = async_imap::connect((imap_server, 993), imap_server, tls).await?;
println!("-- connected to {}:{}", imap_server, 993);
let mut session = client.login(login, password).await.map_err(|e| e.0)?;
println!("-- logged in a {}", login);
session.select("INBOX").await?;
println!("-- INBOX selected");
let msg_stream = session.fetch("1:*", "(FLAGS )").await?;
let msgs = msg_stream.collect::<Vec<_>>().await;
println!("-- number of fetched msgs: {:?}", msgs.len());
println!("-- initializing idle");
let mut idle = session.idle();
idle.init().await?;
println!("-- idle async wait");
let (idle_wait, interrupt) = idle.wait();
task::spawn(async move {
println!("-- thread: waiting for 30s");
task::sleep(Duration::from_secs(30)).await;
println!("-- thread: waited 30 secs, now interrupting idle");
drop(interrupt);
});
let idle_result = idle_wait.await?;
match idle_result {
ManualInterrupt => {
println!("-- IDLE manually interrupted");
}
Timeout => {
println!("-- IDLE timed out");
}
NewData(data) => {
let s = String::from_utf8(data.head().to_vec()).unwrap();
println!("-- IDLE data:\n{}", s);
}
}
println!("-- sending DONE");
let mut session = idle.done().await?;
println!("-- logging out");
session.logout().await?;
Ok(())
}