rust-imap icon indicating copy to clipboard operation
rust-imap copied to clipboard

Does rust-imap parse things twice?

Open jonhoo opened this issue 5 years ago • 2 comments

It seems like a common pattern in the codebase is to use run_command_and_read_response, and then parse its output. However, read_response already fully parses the response, its just that the results of the parsing seems to be discarded https://github.com/mattnenterprise/rust-imap/blob/master/src/client.rs#L521.

Assuming my reading of the code is correct, is there a reason it's laid out like this, as opposed to read_response returning a Vec of the parsed responses or similar?

See the original issue here: https://github.com/mattnenterprise/rust-imap/issues/78

jonhoo avatar Nov 23 '18 01:11 jonhoo

This seems like an interesting thing to look into, but first what are we looking into?

We can see every time run_command_and_read_response is called we are generally executing another parsing function on the returned response.

rg -i -A3 run_command_and_read_response

https://github.com/jonhoo/rust-imap/blob/5d0d2f9723b626770ffeab7e334ded67ae94fd7e/src/client.rs#L353-L358

read_response parses the response once to assess if there were any errors (all the way to the end), and then Capabilities::parse parses the entire response again to identify the capabilities therein. (I believe)

The ideal situation would be able to compose different parsers together and iterate over the stream just once. That's just my current understanding, but I haven't written too much Rust yet so still getting my bearings.

read_response_onto being the one responsible for reading through the whole response once. After which subsequent parsers will iterate through the whole response again. https://github.com/jonhoo/rust-imap/blob/5d0d2f9723b626770ffeab7e334ded67ae94fd7e/src/client.rs#L1521-L1525

Freyert avatar Oct 14 '23 15:10 Freyert

imap-proto makes heavy use of nom and streaming parsing to handle parsing the streams.

It's likely that we can get rid of readline by building on nom as well:

https://github.com/jonhoo/rust-imap/blob/5d0d2f9723b626770ffeab7e334ded67ae94fd7e/src/client.rs#L1606-L1621

Theoretically there's a part of the stream that is "general control", some that's "specific control for the request", and then finally the data we want to parse. We would want to be able to compose these parsers as so: general_control(specific_control(data)) and that should do parsing in one pass.

Freyert avatar Oct 18 '23 02:10 Freyert