Crates.io | imap-types |
lib.rs | imap-types |
version | 2.0.0-alpha.4 |
source | src |
created_at | 2022-06-08 14:36:53.417864 |
updated_at | 2024-09-08 15:06:01.651064 |
description | Misuse-resistant data structures for IMAP |
homepage | |
repository | https://github.com/duesee/imap-codec |
max_upload_size | |
id | 602117 |
size | 415,999 |
%%{init: {'theme': 'neutral' } }%%
flowchart LR
imap-types -.-> imap-codec
imap-codec -.-> imap-next
imap-next -.-> imap-proxy
imap-next -.-> imap-client
style imap-types stroke-width:4px
click imap-types href "https://github.com/duesee/imap-codec/tree/main/imap-types"
click imap-codec href "https://github.com/duesee/imap-codec"
click imap-next href "https://github.com/duesee/imap-next"
click imap-proxy href "https://github.com/duesee/imap-proxy"
click imap-client href "https://github.com/soywod/imap-client"
This crate provides a complete set of well-designed, misuse-resistant types for the IMAP4rev1 protocol and various extensions. Notably, it does not provide parsers, nor serializers, but tries to become the "standard library" for IMAP in Rust that is useful for a broad range of crates.
If you are looking for parsers, and serializers, head over to imap-codec
.
To ensure correctness, imap-types makes use of types such as
AString
,
Atom
,
IString
,
Quoted
, and
Literal
.
When constructing messages, imap-types can automatically choose the best representation.
However, it's always possible to manually choose a specific representation.
This ...
use imap_types::command::{Command, CommandBody};
let cmd = Command::new(
"A1",
CommandBody::login("alice", "password").unwrap()
).unwrap();
... will produce ...
A1 LOGIN alice password
However, ...
use imap_types::command::{Command, CommandBody};
let cmd = Command::new(
"A1",
CommandBody::login("alice\"", b"\xCA\xFE".as_ref()).unwrap(),
).unwrap();
... will produce ...
A1 LOGIN "alice\"" {2}
\xCA\xFE
Also, the construction ...
use imap_types::command::{Command, CommandBody};
let cmd = Command::new(
"A1",
CommandBody::login("alice\x00", "password").unwrap(),
).unwrap();
... will fail because IMAP doesn't allow NULL bytes in the username (nor password).
You can also use ...
use imap_types::{
command::{Command, CommandBody},
core::Literal,
};
let cmd = Command::new(
"A1",
CommandBody::login(Literal::try_from("alice").unwrap(), "password").unwrap(),
).unwrap();
... to produce ...
A1 LOGIN {5}
alice password
... even though "alice" could be encoded more simply with an atom or quoted string.
Also, you can use Rust literals and resort to unvalidated
constructors when you are certain that your input is correct:
use imap_types::{
command::{Command, CommandBody},
core::{AString, Atom, Tag},
secret::Secret,
};
// This could be provided by the email application.
struct TagGenerator;
impl TagGenerator {
fn random() -> Tag<'static> {
// Make this random :-)
Tag::unvalidated("A1")
}
}
let tag = TagGenerator::random();
let cmd = Command {
tag,
body: CommandBody::Login {
username: AString::from(Atom::unvalidated("alice")),
password: Secret::new(AString::from(Atom::unvalidated("password"))),
},
};
In this case, imap-codec won't stand in your way. However, it won't guarantee that you produce correct messages, either.
This crate is dual-licensed under Apache 2.0 and MIT terms.