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()
|
Capability::try_from("UIDPLUS").unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn capability_liststatus() -> Capability<'static> {
|
||||||
|
Capability::try_from("LIST-STATUS").unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
fn capability_qresync() -> Capability<'static> {
|
fn capability_qresync() -> Capability<'static> {
|
||||||
Capability::try_from("QRESYNC").unwrap()
|
Capability::try_from("QRESYNC").unwrap()
|
||||||
|
@ -38,6 +42,7 @@ impl Default for ServerCapability {
|
||||||
capability_unselect(),
|
capability_unselect(),
|
||||||
capability_condstore(),
|
capability_condstore(),
|
||||||
capability_uidplus(),
|
capability_uidplus(),
|
||||||
|
capability_liststatus(),
|
||||||
//capability_qresync(),
|
//capability_qresync(),
|
||||||
]))
|
]))
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,14 @@ use crate::common::fragments::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
rfc3501_imap4rev1_base();
|
rfc3501_imap4rev1_base();
|
||||||
rfc3691_imapext_unselect();
|
|
||||||
rfc5161_imapext_enable();
|
|
||||||
rfc6851_imapext_move();
|
rfc6851_imapext_move();
|
||||||
rfc7888_imapext_literal();
|
|
||||||
rfc4551_imapext_condstore();
|
rfc4551_imapext_condstore();
|
||||||
rfc2177_imapext_idle();
|
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 🌟🚀🥳🙏🥹");
|
println!("✅ SUCCESS 🌟🚀🥳🙏🥹");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,3 +308,50 @@ fn rfc4315_imapext_uidplus() {
|
||||||
})
|
})
|
||||||
.expect("test fully run");
|
.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,
|
LiteralPlus,
|
||||||
Idle,
|
Idle,
|
||||||
UidPlus,
|
UidPlus,
|
||||||
|
ListStatus,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Enable {
|
pub enum Enable {
|
||||||
|
@ -107,6 +108,15 @@ pub enum StatusKind {
|
||||||
HighestModSeq,
|
HighestModSeq,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum MbxSelect {
|
||||||
|
All,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum ListReturn {
|
||||||
|
None,
|
||||||
|
StatusMessagesUnseen,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn capability(imap: &mut TcpStream, ext: Extension) -> Result<()> {
|
pub fn capability(imap: &mut TcpStream, ext: Extension) -> Result<()> {
|
||||||
imap.write(&b"5 capability\r\n"[..])?;
|
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::LiteralPlus => Some("LITERAL+"),
|
||||||
Extension::Idle => Some("IDLE"),
|
Extension::Idle => Some("IDLE"),
|
||||||
Extension::UidPlus => Some("UIDPLUS"),
|
Extension::UidPlus => Some("UIDPLUS"),
|
||||||
|
Extension::ListStatus => Some("LIST-STATUS"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut buffer: [u8; 6000] = [0; 6000];
|
let mut buffer: [u8; 6000] = [0; 6000];
|
||||||
|
@ -169,6 +180,25 @@ pub fn create_mailbox(imap: &mut TcpStream, mbx: Mailbox) -> Result<()> {
|
||||||
Ok(())
|
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> {
|
pub fn select(imap: &mut TcpStream, mbx: Mailbox, modifier: SelectMod) -> Result<String> {
|
||||||
let mut buffer: [u8; 6000] = [0; 6000];
|
let mut buffer: [u8; 6000] = [0; 6000];
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue