| Crates.io | tokio-mime |
| lib.rs | tokio-mime |
| version | 0.1.0 |
| created_at | 2026-01-05 16:04:51.366104+00 |
| updated_at | 2026-01-05 16:04:51.366104+00 |
| description | Complete Rust port of Go's mime package with async-first design |
| homepage | |
| repository | https://github.com/async-php/tokio-mime |
| max_upload_size | |
| id | 2024104 |
| size | 172,967 |
Complete Rust port of Go's
mimepackage with async-first design
A comprehensive MIME handling library for Rust, providing full support for MIME type detection, media type parsing, multipart messages, quoted-printable encoding, and RFC 2047 encoded-words. Built with async/await and tokio for modern Rust applications.
Add this to your Cargo.toml:
[dependencies]
tokio-mime = "0.1.0"
tokio = { version = "1", features = ["full"] }
use tokio_mime::type_by_extension;
// Get MIME type by file extension
let mime_type = type_by_extension(".html");
assert_eq!(mime_type, Some("text/html; charset=utf-8".to_string()));
let mime_type = type_by_extension(".jpg");
assert_eq!(mime_type, Some("image/jpeg".to_string()));
use tokio_mime::parse_media_type;
let (media_type, params) = parse_media_type("text/html; charset=utf-8").unwrap();
assert_eq!(media_type, "text/html");
assert_eq!(params.get("charset"), Some(&"utf-8".to_string()));
use tokio_mime::multipart::Writer;
use tokio::io::AsyncWriteExt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut output = Vec::new();
let mut writer = Writer::new(&mut output);
// Add a text field
writer.write_field("username", "john_doe").await?;
// Add a file
let mut file_writer = writer.create_form_file("avatar", "photo.jpg").await?;
file_writer.write_all(b"image data here").await?;
writer.close().await?;
println!("Multipart data created: {} bytes", output.len());
Ok(())
}
use tokio_mime::multipart::Reader;
use tokio::io::AsyncReadExt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let data = b"--boundary\r\n\
Content-Disposition: form-data; name=\"field\"\r\n\
\r\n\
value\r\n\
--boundary--\r\n";
let mut reader = Reader::new(&data[..], "boundary");
while let Some(mut part) = reader.next_part().await? {
println!("Field name: {:?}", part.form_name());
let mut content = String::new();
part.read_to_string(&mut content).await?;
println!("Content: {}", content);
}
Ok(())
}
use tokio_mime::quotedprintable::Writer;
use tokio::io::AsyncWriteExt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut output = Vec::new();
let mut writer = Writer::new(&mut output);
writer.write_all(b"Hello, World! Special chars: =").await?;
writer.close().await?;
println!("Encoded: {}", String::from_utf8_lossy(&output));
// Output: "Hello, World! Special chars: =3D"
Ok(())
}
use tokio_mime::{WordEncoder, WordDecoder};
// Encoding
let encoder = WordEncoder::QEncoding;
let encoded = encoder.encode("UTF-8", "Hello, ไธ็!");
println!("Encoded: {}", encoded);
// Output: =?UTF-8?q?Hello,_=E4=B8=96=E7=95=8C!?=
// Decoding
let decoder = WordDecoder::new();
let decoded = decoder.decode(&encoded).unwrap();
assert_eq!(decoded, "Hello, ไธ็!");
mime_type - MIME type detection and extension mappingmedia_type - Media type parsing and formatting (RFC 2045/2616/2231)multipart - Multipart message handling (RFC 2046/2388)
Reader - Parse multipart messagesWriter - Create multipart messagesForm - Multipart form data supportquotedprintable - Quoted-printable encoding (RFC 2045)
Reader - Decode quoted-printableWriter - Encode quoted-printableencoded_word - RFC 2047 encoded-word support
WordEncoder - Encode headersWordDecoder - Decode headerserror - Error types and result definitionsThe library includes platform-specific MIME type loading:
/etc/mime.types and other standard locationsThe library includes comprehensive benchmarks using Criterion:
cargo bench
Example benchmark results:
# All tests (121+ tests)
cargo test
# Unit tests only
cargo test --lib
# Integration tests
cargo test --test integration_tests
# With coverage
cargo tarpaulin --out Html
Current test coverage: 73.78% (695/942 lines)
See TESTING_GUIDE.md for detailed testing documentation.
The project includes fuzz tests using cargo-fuzz:
# Install cargo-fuzz
cargo install cargo-fuzz
# Run fuzzing (examples)
cargo fuzz run fuzz_parse_media_type -- -max_total_time=60
cargo fuzz run fuzz_multipart_reader -- -max_total_time=60
cargo fuzz run fuzz_encoded_word -- -max_total_time=60
cargo fuzz run fuzz_quoted_printable -- -max_total_time=60
See the examples/ directory for more complete examples:
basic_mime_type.rs - MIME type detectionmultipart_form.rs - Creating multipart formsemail_headers.rs - Encoding email headersfile_upload.rs - Handling file uploadsRun examples:
cargo run --example basic_mime_type
| Feature | mime-rs | mime | mailparse |
|---|---|---|---|
| MIME type detection | โ | โ | โ |
| Media type parsing | โ | โ | โ |
| Multipart messages | โ | โ | โ |
| Quoted-printable | โ | โ | โ |
| Encoded words (RFC 2047) | โ | โ | โ |
| Async/await | โ | โ | โ |
| Form data | โ | โ | โ |
| Writing support | โ | โ | โ |
Contributions are welcome! Please feel free to submit a Pull Request.
# Clone the repository
git clone https://github.com/async-php/tokio-mime.git
cd tokio-mime
# Run tests
cargo test
# Run benchmarks
cargo bench
# Check formatting
cargo fmt --check
# Run clippy
cargo clippy -- -D warnings
cargo fmt before committingThis project is dual-licensed under:
at your option.
mime packageMade with โค๏ธ in Rust