jonhoo / rust-imap

IMAP client library for Rust

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Question] Way to readline from underlying stream

qsdgy opened this issue · comments

commented

I'm trying to perform an IMAP4 ID extension command manually.

command and response sequence would be like this:

C: a2 ID NIL
S: * ID ("name" "Coremail Imap" "vendor" "Mailtech" "TransID" "I186cXsAACfQ+GDj71IA")
S: a2 OK ID completed

code like this:

// by Client::login()
type ImapSession = imap::Session<native_tls::TlsStream<std::net::TcpStream>>;

pub fn id(s: &mut ImapSession) -> Result<(), Box<dyn std::error::Error>> {
    let id = "ID NIL";

    // Err(Parse(Invalid([...])))
    // [...] is [u8] of * ID ("name" "Coremail Imap" "vendor" "Mailtech" "TransID" "I186cXsAACfQ+GDj71IA")
    let res = s.run(id); 

    // panicked at 'assertion failed: `(left == right)` src\client.rs:1335:25
    let res2 = s.run("NOOP");

    Ok(())
}

failing to parse * ID ("name" "Coremail Imap" "vendor" "Mailtech" "TransID" "I186cXsAACfQ+GDj71IA") can be ignored,
but tagged a2 OK ID completed is left in the stream, and following commands will panic immediately as assertion failed.

sequence of crate's view:

C: a2 ID NIL
S: * ID ("name" "Coremail Imap" "vendor" "Mailtech" "TransID" "I186cXsAACfQ+GDj71IA")
C: a3 NOOP
S: a2 OK ID completed

So am I missing anything to get workaround to this?

Ah, no, there isn't currently a way to get at the raw connection. Client and Session do both deref to the public (but #[doc(hidden)]) [Connection type](https://github.com/jonhoo/rust-imap/blob/b656618987ccd2843cf0090fcfa5d498b07d991c/src/client.rs#L130], which does have a readline method, though it's currently pub(crate). I think there's a decent argument for exposing a decent low-level interface for manually implementing commands the way you want to do here, so if you want to take a stab at contributing that, that'd be awesome! The main thing to keep an eye out for is to get tagging right, so that if you manually run a command, it'll get a distinct tag from any other commands (see self.tag). @mordak may also be able to point you in the right direction.