djc / tokio-imap

Tokio-based IMAP implementation
Apache License 2.0
122 stars 42 forks source link

support IMAP4 ID extension (rfc2971) #130

Closed qsdgy closed 1 year ago

qsdgy commented 3 years ago

IMAP4 ID extension

example from here

use imap_proto::Response;

fn main() {
    // https://datatracker.ietf.org/doc/html/rfc2971#section-3.2
    let line = r#"* ID ("name" "Cyrus" "version" "1.5" "os" "sunos" "os-version" "5.5" "support-url" "mailto:cyrus-bugs+@andrew.cmu.edu")\r\n"#;
    match Response::from_bytes(line.as_bytes()) {
        Ok((remaining, command)) => {
            println!("{:#?}", command);

            if !remaining.is_empty() {
                println!("Remaining data in buffer: {:?}", remaining);
            }
        }
        Err(e) => {
            println!("Error parsing the response. Is it correct? Exiting.");
            println!("{:?}", e);
        }
    }
}

Error parsing the response. Is it correct? Exiting. Error(Error { input: [42, 32, 73, 68, 32, 40, 34, 110, 97, 109, 101, 34, 32, 34, 67, 121, 114, 117, 115, 34, 32, 34, 118, 101, 114, 115, 105, 111, 110, 34, 32, 34, 49, 46, 53, 34, 32, 34, 111, 115, 34, 32, 34, 115, 117, 110, 111, 115, 34, 32, 34, 111, 115, 45, 118, 101, 114, 115, 105, 111, 110, 34, 32, 34, 53, 46, 53, 34, 32, 34, 115, 117, 112, 112, 111, 114, 116, 45, 117, 114, 108, 34, 32, 34, 109, 97, 105, 108, 116, 111, 58, 99, 121, 114, 117, 115, 45, 98, 117, 103, 115, 43, 64, 97, 110, 100, 114, 101, 119, 46, 99, 109, 117, 46, 101, 100, 117, 34, 41, 92, 114, 92, 110], code: TakeWhile1 })

Some mail service provider enforce clients provide ID info, it's useful to deal with that (e.g. jonhoo/rust-imap#211 ).

djc commented 3 years ago

I'd be happy to review a PR!

qsdgy commented 3 years ago

nom seems cool, I will try it if have the chance.

kavan-mevada commented 1 year ago

All Okay, @qsdgy

    let mut values = HashMap::new();
    values.insert("name".into(), "Cyrus".into());
    values.insert("version".into(), "1.5".into());
    values.insert("os".into(), "sunos".into());
    values.insert("os-version".into(), "5.5".into());
    values.insert("support-url".into(), "mailto:cyrus-bugs+@andrew.cmu.edu".into());

    match imap_proto::parser::parse_response(b"* ID (\"name\" \"Cyrus\" \"version\" \"1.5\" \"os\" \"sunos\" \"os-version\" \"5.5\" \"support-url\" \"mailto:cyrus-bugs+@andrew.cmu.edu\")\r\n") {
        Ok((_, Response::Id(Some(mapped)))) if mapped.eq(&values) => {}
        rsp => panic!("unexpected response {rsp:?}"),
    }
    let line = b"* ID (\"name\" \"Cyrus\" \"version\" \"1.5\" \"os\" \"sunos\" \"os-version\" \"5.5\" \"support-url\" \"mailto:cyrus-bugs+@andrew.cmu.edu\")\r\n";
    match Response::from_bytes(line) {
        Ok((remaining, command)) => {
            println!("{:#?}", command);

            if !remaining.is_empty() {
                println!("Remaining data in buffer: {:?}", remaining);
            }
        }
        Err(e) => {
            println!("Error parsing the response. Is it correct? Exiting.");
            println!("{:?}", e);
        }
    }