Expose mailbox read-only flag
This commit is contained in:
parent
9b78550394
commit
18ca65dd3f
3 changed files with 25 additions and 14 deletions
|
|
@ -599,12 +599,8 @@ impl<T: Read + Write> Session<T> {
|
||||||
/// `EXISTS`, `FETCH`, and `EXPUNGE` responses. You can get them from the
|
/// `EXISTS`, `FETCH`, and `EXPUNGE` responses. You can get them from the
|
||||||
/// `unsolicited_responses` channel of the [`Session`](struct.Session.html).
|
/// `unsolicited_responses` channel of the [`Session`](struct.Session.html).
|
||||||
pub fn select<S: AsRef<str>>(&mut self, mailbox_name: S) -> Result<Mailbox> {
|
pub fn select<S: AsRef<str>>(&mut self, mailbox_name: S) -> Result<Mailbox> {
|
||||||
// TODO: also note READ/WRITE vs READ-only mode!
|
self.run(&format!("SELECT {}", validate_str(mailbox_name.as_ref())?))
|
||||||
self.run_command_and_read_response(&format!(
|
.and_then(|(lines, _)| parse_mailbox(&lines[..], &mut self.unsolicited_responses_tx))
|
||||||
"SELECT {}",
|
|
||||||
validate_str(mailbox_name.as_ref())?
|
|
||||||
))
|
|
||||||
.and_then(|lines| parse_mailbox(&lines[..], &mut self.unsolicited_responses_tx))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `EXAMINE` command is identical to [`Session::select`] and returns the same output;
|
/// The `EXAMINE` command is identical to [`Session::select`] and returns the same output;
|
||||||
|
|
@ -612,11 +608,8 @@ impl<T: Read + Write> Session<T> {
|
||||||
/// of the mailbox, including per-user state, will happen in a mailbox opened with `examine`;
|
/// of the mailbox, including per-user state, will happen in a mailbox opened with `examine`;
|
||||||
/// in particular, messagess cannot lose [`Flag::Recent`] in an examined mailbox.
|
/// in particular, messagess cannot lose [`Flag::Recent`] in an examined mailbox.
|
||||||
pub fn examine<S: AsRef<str>>(&mut self, mailbox_name: S) -> Result<Mailbox> {
|
pub fn examine<S: AsRef<str>>(&mut self, mailbox_name: S) -> Result<Mailbox> {
|
||||||
self.run_command_and_read_response(&format!(
|
self.run(&format!("EXAMINE {}", validate_str(mailbox_name.as_ref())?))
|
||||||
"EXAMINE {}",
|
.and_then(|(lines, _)| parse_mailbox(&lines[..], &mut self.unsolicited_responses_tx))
|
||||||
validate_str(mailbox_name.as_ref())?
|
|
||||||
))
|
|
||||||
.and_then(|lines| parse_mailbox(&lines[..], &mut self.unsolicited_responses_tx))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fetch retrieves data associated with a set of messages in the mailbox.
|
/// Fetch retrieves data associated with a set of messages in the mailbox.
|
||||||
|
|
@ -1756,6 +1749,7 @@ mod tests {
|
||||||
uid_next: Some(2),
|
uid_next: Some(2),
|
||||||
uid_validity: Some(1257842737),
|
uid_validity: Some(1257842737),
|
||||||
highest_mod_seq: None,
|
highest_mod_seq: None,
|
||||||
|
is_read_only: true,
|
||||||
};
|
};
|
||||||
let mailbox_name = "INBOX";
|
let mailbox_name = "INBOX";
|
||||||
let command = format!("a1 EXAMINE {}\r\n", quote!(mailbox_name));
|
let command = format!("a1 EXAMINE {}\r\n", quote!(mailbox_name));
|
||||||
|
|
@ -1803,6 +1797,7 @@ mod tests {
|
||||||
uid_next: Some(2),
|
uid_next: Some(2),
|
||||||
uid_validity: Some(1257842737),
|
uid_validity: Some(1257842737),
|
||||||
highest_mod_seq: None,
|
highest_mod_seq: None,
|
||||||
|
is_read_only: true,
|
||||||
};
|
};
|
||||||
let mailbox_name = "INBOX";
|
let mailbox_name = "INBOX";
|
||||||
let command = format!("a1 SELECT {}\r\n", quote!(mailbox_name));
|
let command = format!("a1 SELECT {}\r\n", quote!(mailbox_name));
|
||||||
|
|
|
||||||
14
src/parse.rs
14
src/parse.rs
|
|
@ -1,4 +1,4 @@
|
||||||
use imap_proto::{self, MailboxDatum, Response};
|
use imap_proto::{MailboxDatum, Response, ResponseCode};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
@ -236,6 +236,17 @@ pub fn parse_mailbox(
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match imap_proto::parser::parse_response(lines) {
|
match imap_proto::parser::parse_response(lines) {
|
||||||
|
Ok((rest, Response::Done { status, code, .. })) => {
|
||||||
|
assert!(rest.is_empty());
|
||||||
|
lines = rest;
|
||||||
|
|
||||||
|
// We wouldn't get to parsing if this wasn't an Ok response.
|
||||||
|
assert_eq!(status, imap_proto::Status::Ok);
|
||||||
|
|
||||||
|
if let Some(ResponseCode::ReadOnly) = code {
|
||||||
|
mailbox.is_read_only = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
Ok((rest, Response::Data { status, code, .. })) => {
|
Ok((rest, Response::Data { status, code, .. })) => {
|
||||||
lines = rest;
|
lines = rest;
|
||||||
|
|
||||||
|
|
@ -245,7 +256,6 @@ pub fn parse_mailbox(
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
|
|
||||||
use imap_proto::ResponseCode;
|
|
||||||
match code {
|
match code {
|
||||||
Some(ResponseCode::HighestModSeq(seq)) => {
|
Some(ResponseCode::HighestModSeq(seq)) => {
|
||||||
mailbox.highest_mod_seq = Some(seq);
|
mailbox.highest_mod_seq = Some(seq);
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,10 @@ pub struct Mailbox {
|
||||||
/// The highest mod sequence for this mailbox. Used with
|
/// The highest mod sequence for this mailbox. Used with
|
||||||
/// [Conditional STORE](https://tools.ietf.org/html/rfc4551#section-3.1.1).
|
/// [Conditional STORE](https://tools.ietf.org/html/rfc4551#section-3.1.1).
|
||||||
pub highest_mod_seq: Option<u64>,
|
pub highest_mod_seq: Option<u64>,
|
||||||
|
|
||||||
|
/// The mailbox is selected read-only, or its access while selected has changed from read-write
|
||||||
|
/// to read-only.
|
||||||
|
pub is_read_only: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Mailbox {
|
impl Default for Mailbox {
|
||||||
|
|
@ -53,6 +57,7 @@ impl Default for Mailbox {
|
||||||
uid_next: None,
|
uid_next: None,
|
||||||
uid_validity: None,
|
uid_validity: None,
|
||||||
highest_mod_seq: None,
|
highest_mod_seq: None,
|
||||||
|
is_read_only: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -62,7 +67,7 @@ impl fmt::Display for Mailbox {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"flags: {:?}, exists: {}, recent: {}, unseen: {:?}, permanent_flags: {:?},\
|
"flags: {:?}, exists: {}, recent: {}, unseen: {:?}, permanent_flags: {:?},\
|
||||||
uid_next: {:?}, uid_validity: {:?}, highest_mod_seq: {:?}",
|
uid_next: {:?}, uid_validity: {:?}, highest_mod_seq: {:?}, is_read_only: {:?}",
|
||||||
self.flags,
|
self.flags,
|
||||||
self.exists,
|
self.exists,
|
||||||
self.recent,
|
self.recent,
|
||||||
|
|
@ -71,6 +76,7 @@ impl fmt::Display for Mailbox {
|
||||||
self.uid_next,
|
self.uid_next,
|
||||||
self.uid_validity,
|
self.uid_validity,
|
||||||
self.highest_mod_seq,
|
self.highest_mod_seq,
|
||||||
|
self.is_read_only,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue