Closed link2xt closed 1 year ago
Hey @link2xt! Thanks for the suggestion! There should really be something in the README.
The most significant differences are server-support, the split into imap-codec and imap-types (that should facilitate interoperability), and imap-types' core types (that should provide misuse resistance).
I'll compile a more thorough answer next week!
Btw: I applied for another round of funding and would love to help out with a correct, async, higher-level IMAP library. When things go well, we should definitely talk!
A first attempt: If there is anything specific you want to know (or would like to see mentioned), feel free to ask (or tell me)!
imap-codec
provides low-level parsing and serialization support for IMAP4rev1, similar to imap-proto
. The most significant differences are server support, the split into imap-codec
and imap-types
, misuse resistance (affecting API design), and (real world) test coverage.
To a certain extent, server-side support is always required because a client must create and serialize Command
s. Full server support not only means that you can write IMAP servers with imap-codec but also that we can share data structures, e.g., to send a Command
and wait for a command completion Response
using the same Tag
.
The imap-codec
/imap-types
split should allow the Rust community to maintain a well-designed set of "pure" IMAP types (free of e.g. "helper types" for parsing) but leave room for custom crates (based on imap-types
).[^1] However, the maintenance costs could be higher compared to imap-proto
.
Generally, imap-codec
has a more extensive API surface than imap-proto
and -- depending on personal preference -- may be more challenging to use. However, it guarantees that you never construct invalid messages and aims to make IMAP usable even for people who are no IMAP experts. For example, imap-codec
has build-in support for IMAP literals.
imap-codec
has a high test coverage and is fuzz-tested to ensure properties such as invertibility, misuse-resistance, etc. Generally, you should be unable to crash the library or generate messages that imap-codec (or another party) can't parse. However, imap-proto
has already succeeded in production. For example, it could implement real-world quirks that imap-codec
doesn't (yet). Despite extensive testing (against real servers and clients), imap-proto
might have a more mature interoperability story. Also, it might implement more of the features that really matter in practice.
[^1]: E.g., an IMF/MIME to BodyStructure
crate, a proxy that doesn't do parsing, security tools, etc.
To a certain extent, server-side support is always required because a client must create and serialize Commands.
This is not clear to me, how generating commands is a server-side feature?
Inability to create invalid commands is certainly a distinguishing feature compared to imap-proto where search queries are just injected into the stream as-is and can be invalid.
This is not clear to me, how generating commands is a server-side feature?
This was not phrased very well...
What I wanted to say:
No matter if implementing a client- or a server, you need the full spectrum of IMAP type definitions. When you send a command with a specific Tag
, you expect a command completion response with the same Tag
. Thus, commands and responses must work well together (and are best provided by a single crate). imap-types
provides this complete set of IMAP type definitions that should be reusable across the Rust ecosystem.
Parsing and serialization are different: As a client developer, you will never parse commands nor serialize responses. As a server developer, you will never serialize commands nor parse responses. Thus, you only need "half of" the spectrum of parsers and serializers. Therefore, this functionality could be provided by separate crates (as long as both use imap-types
, of course). imap-codec
provides a complete set of serializers and parsers for commands and responses (and might also offer a feature gate to exclude unneeded functionality in the future).
Inability to create invalid commands is certainly a distinguishing feature compared to imap-proto where search queries are just injected into the stream as-is and can be invalid.
It has been a while since I've used imap-proto, but I remember that literal handling wasn't well-supported. (A search query can contain an indefinite amount of literals :-/) The last time I tried, it didn't generate a literal for a non-quotable password. However, I have not seen a server that would choke on this. It's not standard-conforming, but it may be fine. Hard to tell without extensive real-world deployment.
I've added a FAQ to the README. Thanks!
There is an existing crate
imap-proto
and it is already used in production in Delta Chat viaasync-imap
crate. How doesimap-codec
compare toimap-proto
?Would be nice to clarify this in the README.
It is not trivial to switch
async-imap
toimap-proto
because it reexports some types, but can still be considered if there are some advantages.