From 2874bfd93387e7b14a1050830dc533b3823e8d52 Mon Sep 17 00:00:00 2001 From: Todd Mortimer Date: Sat, 27 Mar 2021 21:10:27 -0400 Subject: [PATCH] Add IDLE example. --- Cargo.toml | 5 ++++ examples/idle.rs | 77 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 examples/idle.rs diff --git a/Cargo.toml b/Cargo.toml index aeabd5e..8c8af38 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,7 @@ lazy_static = "1.4" lettre = "0.9" lettre_email = "0.9" rustls-connector = "0.13.0" +structopt = "0.3" [[example]] name = "basic" @@ -40,6 +41,10 @@ required-features = ["default"] name = "gmail_oauth2" required-features = ["default"] +[[example]] +name = "idle" +required-features = ["default"] + [[test]] name = "imap_integration" required-features = ["default"] diff --git a/examples/idle.rs b/examples/idle.rs new file mode 100644 index 0000000..a374388 --- /dev/null +++ b/examples/idle.rs @@ -0,0 +1,77 @@ +use imap::extensions::idle; +use native_tls::TlsConnector; +use structopt::StructOpt; + +#[derive(StructOpt, Debug)] +#[structopt(name = "idle")] +struct Opt { + // The server name to connect to + #[structopt(short, long)] + server: String, + + // The port to use + #[structopt(short, long, default_value = "993")] + port: u16, + + // The account username + #[structopt(short, long)] + username: String, + + // The account password. In a production system passwords + // would normally be in a config or fetched at runtime from + // a password manager or user prompt and not passed on the + // command line. + #[structopt(short = "w", long)] + password: String, + + // The mailbox to IDLE on + #[structopt(short, long, default_value = "INBOX")] + mailbox: String, + + #[structopt( + short = "x", + long, + help = "The number of responses to receive before exiting", + default_value = "5" + )] + max_responses: usize, +} + +fn main() { + let opt = Opt::from_args(); + + let ssl_conn = TlsConnector::builder().build().unwrap(); + let client = imap::connect((opt.server.clone(), opt.port), opt.server, &ssl_conn) + .expect("Could not connect to imap server"); + let mut imap = client + .login(opt.username, opt.password) + .expect("Could not authenticate"); + imap.debug = true; + imap.select(opt.mailbox).expect("Could not select mailbox"); + + let idle = imap.idle().expect("Could not IDLE"); + + // Implement a trivial counter that causes the IDLE callback to end the IDLE + // after a fixed number of responses. + // + // A threaded client could use channels or shared data to interact with the + // rest of the program and update mailbox state, decide to exit the IDLE, etc. + let mut num_responses = 0; + let max_responses = opt.max_responses; + let idle_result = idle.wait_keepalive(|response| { + num_responses += 1; + println!("IDLE response #{}: {:?}", num_responses, response); + if num_responses >= max_responses { + idle::CallbackAction::Stop + } else { + idle::CallbackAction::Continue + } + }); + + match idle_result { + Ok(()) => println!("IDLE finished normally"), + Err(e) => println!("IDLE finished with error {:?}", e), + } + + imap.logout().expect("Could not log out"); +}