Skip to content

Commit 6021160

Browse files
committed
client: extend APPEND to support optional flags
According to RFC3501[1], the APPEND command supports optional flags for the datetime of the message receipt, and a set of flags to be applied to the message. Implement this in imap-rust, using the same formatting as the Python imaplib equivalent code. [1]: https://tools.ietf.org/html/rfc3501#section-6.3.11 Signed-off-by: Aleksa Sarai <[email protected]>
1 parent 4332d09 commit 6021160

File tree

3 files changed

+44
-3
lines changed

3 files changed

+44
-3
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ path = "src/lib.rs"
2828
native-tls = "0.1"
2929
regex = "0.2"
3030
bufstream = "0.1"
31+
chrono = "0.4"
3132

3233
[dev-dependencies]
3334
base64 = "0.7"

src/client.rs

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
use std::fmt;
12
use std::net::{TcpStream, ToSocketAddrs};
23
use native_tls::{TlsConnector, TlsStream};
34
use std::io::{self, Read, Write};
45
use std::time::Duration;
56
use bufstream::BufStream;
7+
use chrono::prelude::*;
68

79
use super::mailbox::Mailbox;
810
use super::authenticator::Authenticator;
@@ -448,9 +450,46 @@ impl<T: Read + Write> Client<T> {
448450
IdleHandle::new(self)
449451
}
450452

451-
/// The APPEND command adds a mail to a mailbox.
452-
pub fn append(&mut self, folder: &str, content: &[u8]) -> Result<Vec<String>> {
453-
try!(self.run_command(&format!("APPEND \"{}\" {{{}}}", folder, content.len())));
453+
/// The APPEND command adds a mail to a mailbox. If the datetime or flags are unspecified they
454+
/// are not included in the request.
455+
pub fn append<Tz: TimeZone>(
456+
&mut self,
457+
folder: &str,
458+
flags: Option<Vec<String>>,
459+
datetime: Option<DateTime<Tz>>,
460+
content: &[u8],
461+
) -> Result<Vec<String>>
462+
where
463+
Tz::Offset: fmt::Display,
464+
{
465+
// Set up optional flags.
466+
let mut optionals = String::new();
467+
match flags {
468+
None => (),
469+
Some(flags) => {
470+
optionals.push_str(&format!(
471+
"({})",
472+
flags
473+
.iter()
474+
.fold(String::new(), |acc, ref flag| acc + &flag)
475+
.trim()
476+
));
477+
}
478+
}
479+
optionals.push(' ');
480+
match datetime {
481+
None => (),
482+
Some(datetime) => {
483+
optionals.push_str(&format!("\"{}\"", datetime.format("%d-%b-%Y %H:%M:%S %z")))
484+
}
485+
}
486+
487+
try!(self.run_command(&format!(
488+
"APPEND \"{}\" {} {{{}}}",
489+
folder,
490+
optionals,
491+
content.len()
492+
)));
454493
let line = try!(self.readline());
455494
if !line.starts_with(b"+") {
456495
return Err(Error::Append);

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//! imap is a IMAP client for Rust.
55
66
extern crate bufstream;
7+
extern crate chrono;
78
extern crate native_tls;
89
extern crate regex;
910

0 commit comments

Comments
 (0)