Implement LIST X Y RETURN (STATUS (UIDNEXT ...))
#75
3 changed files with 87 additions and 4 deletions
|
@ -18,6 +18,10 @@ fn capability_uidplus() -> Capability<'static> {
|
|||
Capability::try_from("UIDPLUS").unwrap()
|
||||
}
|
||||
|
||||
fn capability_liststatus() -> Capability<'static> {
|
||||
Capability::try_from("LIST-STATUS").unwrap()
|
||||
}
|
||||
|
||||
/*
|
||||
fn capability_qresync() -> Capability<'static> {
|
||||
Capability::try_from("QRESYNC").unwrap()
|
||||
|
@ -38,6 +42,7 @@ impl Default for ServerCapability {
|
|||
capability_unselect(),
|
||||
capability_condstore(),
|
||||
capability_uidplus(),
|
||||
capability_liststatus(),
|
||||
//capability_qresync(),
|
||||
]))
|
||||
}
|
||||
|
|
|
@ -6,13 +6,14 @@ use crate::common::fragments::*;
|
|||
|
||||
fn main() {
|
||||
rfc3501_imap4rev1_base();
|
||||
rfc3691_imapext_unselect();
|
||||
rfc5161_imapext_enable();
|
||||
rfc6851_imapext_move();
|
||||
rfc7888_imapext_literal();
|
||||
rfc4551_imapext_condstore();
|
||||
rfc2177_imapext_idle();
|
||||
rfc4315_imapext_uidplus();
|
||||
rfc5161_imapext_enable(); // 1
|
||||
rfc3691_imapext_unselect(); // 2
|
||||
rfc7888_imapext_literal(); // 3
|
||||
rfc4315_imapext_uidplus(); // 4
|
||||
rfc5819_imapext_liststatus(); // 5
|
||||
println!("✅ SUCCESS 🌟🚀🥳🙏🥹");
|
||||
}
|
||||
|
||||
|
@ -307,3 +308,50 @@ fn rfc4315_imapext_uidplus() {
|
|||
})
|
||||
.expect("test fully run");
|
||||
}
|
||||
|
||||
///
|
||||
/// Example
|
||||
///
|
||||
/// ```text
|
||||
/// 30 list "" "*" RETURN (STATUS (MESSAGES UNSEEN))
|
||||
/// * LIST (\Subscribed) "." INBOX
|
||||
/// * STATUS INBOX (MESSAGES 2 UNSEEN 1)
|
||||
/// 30 OK LIST completed
|
||||
/// ```
|
||||
fn rfc5819_imapext_liststatus() {
|
||||
println!("🧪 rfc5819_imapext_liststatus");
|
||||
common::aerogramme_provider_daemon_dev(|imap_socket, lmtp_socket| {
|
||||
// Test setup, check capability, add 2 emails, read 1
|
||||
connect(imap_socket).context("server says hello")?;
|
||||
capability(imap_socket, Extension::ListStatus).context("check server capabilities")?;
|
||||
login(imap_socket, Account::Alice).context("login test")?;
|
||||
select(imap_socket, Mailbox::Inbox, SelectMod::None).context("select inbox")?;
|
||||
lmtp_handshake(lmtp_socket).context("handshake lmtp done")?;
|
||||
lmtp_deliver_email(lmtp_socket, Email::Basic).context("mail delivered successfully")?;
|
||||
lmtp_deliver_email(lmtp_socket, Email::Multipart).context("mail delivered successfully")?;
|
||||
noop_exists(imap_socket, 2).context("noop loop must detect a new email")?;
|
||||
fetch(
|
||||
imap_socket,
|
||||
Selection::FirstId,
|
||||
FetchKind::Rfc822,
|
||||
FetchMod::None,
|
||||
)
|
||||
.context("read one message")?;
|
||||
close(imap_socket).context("close inbox")?;
|
||||
|
||||
// Test return status MESSAGES UNSEEN
|
||||
let ret = list(
|
||||
imap_socket,
|
||||
MbxSelect::All,
|
||||
ListReturn::StatusMessagesUnseen,
|
||||
)?;
|
||||
assert!(ret.contains("* STATUS INBOX (MESSAGES 2 UNSEEN 1)"));
|
||||
|
||||
// Test that without RETURN, no status is sent
|
||||
let ret = list(imap_socket, MbxSelect::All, ListReturn::None)?;
|
||||
assert!(!ret.contains("* STATUS"));
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.expect("test fully run");
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ pub enum Extension {
|
|||
LiteralPlus,
|
||||
Idle,
|
||||
UidPlus,
|
||||
ListStatus,
|
||||
}
|
||||
|
||||
pub enum Enable {
|
||||
|
@ -107,6 +108,15 @@ pub enum StatusKind {
|
|||
HighestModSeq,
|
||||
}
|
||||
|
||||
pub enum MbxSelect {
|
||||
All,
|
||||
}
|
||||
|
||||
pub enum ListReturn {
|
||||
None,
|
||||
StatusMessagesUnseen,
|
||||
}
|
||||
|
||||
pub fn capability(imap: &mut TcpStream, ext: Extension) -> Result<()> {
|
||||
imap.write(&b"5 capability\r\n"[..])?;
|
||||
|
||||
|
@ -118,6 +128,7 @@ pub fn capability(imap: &mut TcpStream, ext: Extension) -> Result<()> {
|
|||
Extension::LiteralPlus => Some("LITERAL+"),
|
||||
Extension::Idle => Some("IDLE"),
|
||||
Extension::UidPlus => Some("UIDPLUS"),
|
||||
Extension::ListStatus => Some("LIST-STATUS"),
|
||||
};
|
||||
|
||||
let mut buffer: [u8; 6000] = [0; 6000];
|
||||
|
@ -169,6 +180,25 @@ pub fn create_mailbox(imap: &mut TcpStream, mbx: Mailbox) -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn list(imap: &mut TcpStream, select: MbxSelect, mod_return: ListReturn) -> Result<String> {
|
||||
let mut buffer: [u8; 6000] = [0; 6000];
|
||||
|
||||
let select_str = match select {
|
||||
MbxSelect::All => "%",
|
||||
};
|
||||
|
||||
let mod_return_str = match mod_return {
|
||||
ListReturn::None => "",
|
||||
ListReturn::StatusMessagesUnseen => " RETURN (STATUS (MESSAGES UNSEEN))",
|
||||
};
|
||||
|
||||
imap.write(format!("19 LIST \"\" \"{}\"{}\r\n", select_str, mod_return_str).as_bytes())?;
|
||||
|
||||
let read = read_lines(imap, &mut buffer, Some(&b"19 OK"[..]))?;
|
||||
let srv_msg = std::str::from_utf8(read)?;
|
||||
Ok(srv_msg.to_string())
|
||||
}
|
||||
|
||||
pub fn select(imap: &mut TcpStream, mbx: Mailbox, modifier: SelectMod) -> Result<String> {
|
||||
let mut buffer: [u8; 6000] = [0; 6000];
|
||||
|
||||
|
|
Loading…
Reference in a new issue