Add support for APPENDUID response data
If the `UIDPLUS` extension is supported, the server will reply to `APPEND` commands with the UID of the new message. This can even be a list of UIDs if the `MULTIAPPEND` extension is also supported. Make this information available to the user as the result of an `AppendCmd`. The added doc strings have links to the relevant RFCs. Related to #131.
This commit is contained in:
parent
f616ea992e
commit
75e5d7cf79
4 changed files with 81 additions and 2 deletions
|
|
@ -215,7 +215,7 @@ impl<'a, T: Read + Write> AppendCmd<'a, T> {
|
|||
///
|
||||
/// Note: be sure to set flags and optional date before you
|
||||
/// finish the command.
|
||||
pub fn finish(&mut self) -> Result<()> {
|
||||
pub fn finish(&mut self) -> Result<Appended> {
|
||||
let flagstr = self
|
||||
.flags
|
||||
.clone()
|
||||
|
|
@ -246,7 +246,9 @@ impl<'a, T: Read + Write> AppendCmd<'a, T> {
|
|||
self.session.stream.write_all(self.content)?;
|
||||
self.session.stream.write_all(b"\r\n")?;
|
||||
self.session.stream.flush()?;
|
||||
self.session.read_response().map(|_| ())
|
||||
self.session
|
||||
.read_response()
|
||||
.and_then(|(lines, _)| parse_append(&lines, &mut self.session.unsolicited_responses_tx))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
34
src/parse.rs
34
src/parse.rs
|
|
@ -124,6 +124,40 @@ pub fn parse_expunge(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn parse_append(
|
||||
mut lines: &[u8],
|
||||
unsolicited: &mut mpsc::Sender<UnsolicitedResponse>,
|
||||
) -> Result<Appended> {
|
||||
let mut appended = Appended::default();
|
||||
|
||||
loop {
|
||||
match imap_proto::parser::parse_response(lines) {
|
||||
Ok((rest, Response::Done { status, code, .. })) => {
|
||||
lines = rest;
|
||||
assert_eq!(status, imap_proto::Status::Ok);
|
||||
|
||||
if let Some(ResponseCode::AppendUid(validity, uids)) = code {
|
||||
appended.uid_validity = Some(validity);
|
||||
appended.uids = Some(uids);
|
||||
}
|
||||
}
|
||||
Ok((rest, data)) => {
|
||||
lines = rest;
|
||||
if let Some(resp) = try_handle_unilateral(data, unsolicited) {
|
||||
break Err(resp.into());
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::Parse(ParseError::Invalid(lines.to_vec())));
|
||||
}
|
||||
}
|
||||
|
||||
if lines.is_empty() {
|
||||
break Ok(appended);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_noop(
|
||||
lines: Vec<u8>,
|
||||
unsolicited: &mut mpsc::Sender<UnsolicitedResponse>,
|
||||
|
|
|
|||
40
src/types/appended.rs
Normal file
40
src/types/appended.rs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
use imap_proto::UidSetMember;
|
||||
use std::fmt;
|
||||
|
||||
/// Meta-information about a message, as returned by
|
||||
/// [`APPEND`](https://tools.ietf.org/html/rfc3501#section-6.3.11).
|
||||
/// Note that `APPEND` only returns any data if certain extensions are enabled,
|
||||
/// for example [`UIDPLUS`](https://tools.ietf.org/html/rfc4315).
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[non_exhaustive]
|
||||
pub struct Appended {
|
||||
/// The unique identifier validity value of the mailbox that the message was appended to.
|
||||
/// See [`Uid`] for more details. Only present if server supports [`UIDPLUS`](https://tools.ietf.org/html/rfc4315).
|
||||
pub uid_validity: Option<u32>,
|
||||
|
||||
/// The unique identifier value of the messages that were appended.
|
||||
/// Only present if server supports [`UIDPLUS`](https://tools.ietf.org/html/rfc4315).
|
||||
/// Contains only a single value unless the [`MULTIAPPEND`](https://tools.ietf.org/html/rfc3502) extension
|
||||
/// was used to upload multiple messages.
|
||||
pub uids: Option<Vec<UidSetMember>>,
|
||||
}
|
||||
|
||||
#[allow(clippy::derivable_impls)]
|
||||
impl Default for Appended {
|
||||
fn default() -> Appended {
|
||||
Appended {
|
||||
uid_validity: None,
|
||||
uids: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Appended {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"uid_validity: {:?}, uids: {:?}",
|
||||
self.uid_validity, self.uids,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -123,3 +123,6 @@ pub use self::deleted::Deleted;
|
|||
|
||||
mod unsolicited_response;
|
||||
pub use self::unsolicited_response::{AttributeValue, UnsolicitedResponse};
|
||||
|
||||
mod appended;
|
||||
pub use self::appended::Appended;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue