imap_codec/lib.rs
1//! # IMAP protocol library
2//!
3//! imap-codec provides complete and detailed parsing and construction of [IMAP4rev1] commands and responses.
4//! It is based on [imap-types] and extends it with parsing support using [nom].
5//!
6//! The main codecs are
7//! [`GreetingCodec`] (to parse the first message from a server),
8//! [`CommandCodec`] (to parse commands from a client), and
9//! [`ResponseCodec`] (to parse responses or results from a server).
10//!
11//! Note that IMAP traces are not guaranteed to be UTF-8.
12//! Thus, be careful when using code like `from_utf8(...)`.
13//!
14//! ## Decoding
15//!
16//! Decoding is provided through the [`Decoder`](`crate::decode::Decoder`) trait.
17//! Every parser takes an input (`&[u8]`) and produces a remainder and a parsed value.
18//!
19//! **Note:** Decoding IMAP traces is more elaborate than it seems on a first glance.
20//! Please consult the [`decode`](`crate::decode`) module documentation to learn how to handle real-world decoding.
21//!
22//! ### Example
23//!
24//! ```rust
25//! use imap_codec::{
26//! GreetingCodec,
27//! decode::Decoder,
28//! imap_types::{
29//! core::Text,
30//! response::{Code, Greeting, GreetingKind},
31//! },
32//! };
33//!
34//! let (remaining, greeting) = GreetingCodec::default()
35//! .decode(b"* OK [ALERT] Hello, World!\r\n<remaining>")
36//! .unwrap();
37//!
38//! assert_eq!(
39//! greeting,
40//! Greeting {
41//! kind: GreetingKind::Ok,
42//! code: Some(Code::Alert),
43//! text: Text::try_from("Hello, World!").unwrap(),
44//! }
45//! );
46//! assert_eq!(remaining, &b"<remaining>"[..])
47//! ```
48//!
49//! ## Encoding
50//!
51//! Encoding is provided through the [`Encoder`](`crate::encode::Encoder`) trait.
52//!
53//! **Note:** Encoding IMAP traces is more elaborate than it seems on a first glance.
54//! Please consult the [`encode`](`crate::encode`) module documentation to learn how to handle real-world encoding.
55//!
56//! ### Example
57//!
58//! ```rust
59//! use imap_codec::{
60//! GreetingCodec,
61//! encode::Encoder,
62//! imap_types::{
63//! core::Text,
64//! response::{Code, Greeting, GreetingKind},
65//! },
66//! };
67//!
68//! let greeting = Greeting {
69//! kind: GreetingKind::Ok,
70//! code: Some(Code::Alert),
71//! text: Text::try_from("Hello, World!").unwrap(),
72//! };
73//!
74//! let bytes = GreetingCodec::default().encode(&greeting).dump();
75//!
76//! assert_eq!(bytes, &b"* OK [ALERT] Hello, World!\r\n"[..]);
77//! ```
78//!
79//! ## Features
80//!
81//! imap-codec forwards many features to imap-types. See [imap-types features] for a comprehensive list.
82//!
83//! In addition, imap-codec defines the following features:
84//!
85//! | Feature | Description | Enabled by default |
86//! |-----------------------|--------------------------------|--------------------|
87//! | quirk_crlf_relaxed | Make `\r` in `\r\n` optional. | No |
88//! | quirk_rectify_numbers | Rectify (invalid) numbers. | No |
89//! | quirk_missing_text | Rectify missing `text` element.| No |
90//!
91//! ## Quirks
92//!
93//! Features starting with `quirk_` are used to cope with existing interoperability issues.
94//! Unfortunately, we already observed some standard violations, such as, negative numbers, and missing syntax elements.
95//! Our policy is as follows: If we see an interoperability issue, we file an issue in the corresponding implementation.
96//! If, for any reason, the issue cannot be fixed, *and* the implementation is "important enough", e.g., because a user of
97//! imap-codec can't otherwise access their emails, we may add a `quirk_` feature to quickly resolve the problem.
98//! Of course, imap-codec should never violate the IMAP standard itself. So, we need to do this carefully.
99//!
100//! [imap-types]: https://docs.rs/imap-types/latest/imap_types
101//! [imap-types features]: https://docs.rs/imap-types/latest/imap_types/#features
102//! [IMAP4rev1]: https://tools.ietf.org/html/rfc3501
103//! [parse_command]: https://github.com/duesee/imap-codec/blob/main/examples/parse_command.rs
104
105// TODO(#660)
106#![allow(unknown_lints)]
107#![allow(mismatched_lifetime_syntaxes)]
108#![forbid(unsafe_code)]
109#![deny(missing_debug_implementations)]
110#![cfg_attr(docsrs, feature(doc_cfg))]
111
112// Test examples from repository root README.
113#[doc = include_str!("../../README.md")]
114#[cfg(doctest)]
115pub struct ReadmeDoctestsRoot;
116
117// Test examples from imap-codec's README.
118#[doc = include_str!("../README.md")]
119#[cfg(doctest)]
120pub struct ReadmeDoctests;
121
122mod auth;
123mod body;
124mod codec;
125mod command;
126mod core;
127mod datetime;
128mod envelope;
129mod extensions;
130mod fetch;
131mod flag;
132mod mailbox;
133mod response;
134mod search;
135mod sequence;
136mod status;
137#[cfg(test)]
138mod testing;
139
140pub mod fragmentizer;
141#[cfg(feature = "fuzz")]
142pub mod fuzz {
143 pub use crate::core::fuzz_tag_imap;
144}
145
146pub use codec::*;
147// Re-export.
148pub use imap_types;