# mime-type
A Rust library for working with MIME types and file extensions. This crate provides a simple, ergonomic API for converting between file extensions and their corresponding MIME type strings.
## Features
- Type-safe MIME type handling with enums for different categories
- Bidirectional conversion between file extensions and MIME type strings
- Multiple categories including images, videos, audio, documents, archives, fonts, books, and applications
- Zero dependencies and lightweight
- Display trait implementation for easy MIME type string output
## Usage
### Getting MIME type from file extension
```rust
use mime_type::{MimeType, MimeFormat};
// Get MIME type from extension
let mime = MimeType::from_ext("png");
assert_eq!(mime.unwrap().to_string(), "image/png");
// Works with multiple extensions for the same format
let jpeg1 = MimeType::from_ext("jpg");
let jpeg2 = MimeType::from_ext("jpeg");
assert_eq!(jpeg1.unwrap().to_string(), jpeg2.unwrap().to_string());
// Returns None for unknown extensions
let unknown = MimeType::from_ext("unknown");
assert!(unknown.is_none());
```
### Getting MIME type from MIME string
```rust
use mime_type::{MimeType, MimeFormat};
let mime = MimeType::from_mime("video/mp4");
match mime {
Some(MimeType::Video(video)) => println!("It's a video: {}", video),
_ => println!("Not a video"),
}
```
### Working with specific categories
```rust
use mime_type::{Image, Video, Audio, Document, MimeFormat};
// Directly use category enums
let png = Image::Png;
println!("{}", png); // Outputs: image/png
// Check extensions for specific categories
if let Some(mime) = Image::from_ext("webp") {
println!("Found image: {}", mime);
}
```
### Pattern matching on MIME types
```rust
use mime_type::{MimeType, MimeFormat};
let mime = MimeType::from_ext("mp3").unwrap();
match mime {
MimeType::Audio(audio) => println!("Audio file: {}", audio),
MimeType::Video(video) => println!("Video file: {}", video),
MimeType::Image(image) => println!("Image file: {}", image),
_ => println!("Other file type"),
}
```
## Supported Categories
### Image Formats
JPEG, PNG, GIF, WebP, CR2, TIFF, BMP, HEIF, AVIF, JXR, PSD, ICO, ORA, DjVu
### Video Formats
MP4, M4V, MKV, WebM, MOV, AVI, WMV, MPG, FLV
### Audio Formats
MIDI, MP3, M4A, OGG, FLAC, WAV, AMR, AAC, AIFF, DSF, APE
### Document Formats
DOC, DOCX, XLS, XLSX, PPT, PPTX, ODT, ODS, ODP
### Archive Formats
ZIP, TAR, RAR, GZ, BZ2, 7Z, XZ, PDF, and many more
### Font Formats
TTF, OTF, WOFF, WOFF2
### Book Formats
EPUB, MOBI
### Application Formats
WASM, EXE, DLL, ELF, and various executable formats
## Edge Cases and Known Limitations
### Duplicate MIME Types
Some file formats share the same MIME type but have different extensions:
**EXE and DLL**: Both map to `application/vnd.microsoft.portable-executable`
- When converting from MIME type to extension, only `EXE` variant is returned
- This is by design as they share the same PE (Portable Executable) format
**ELF and OBJ**: Both map to `application/x-executable`
- When converting from MIME type, only `ELF` variant is returned
- These represent different executable object formats but share a MIME type
### EPUB Duplication
EPUB files appear in both `Archive` and `Book` categories:
- `Archive::Epub` maps to `application/epub+zip`
- `Book::Epub` also maps to `application/epub+zip`
**Behavior**:
- `MimeType::from_ext("epub")` returns `MimeType::Archive(Archive::Epub)` (Archive is checked first)
- `MimeType::from_mime("application/epub+zip")` returns `MimeType::Archive(Archive::Epub)`
- The `Book::Epub` variant is **effectively unreachable** through the standard API
**Recommendation**: Use `Archive::Epub` for EPUB files, or access `Book::Epub` directly if you need the Book variant specifically.
### Font MIME Type Ambiguity
Font formats have some MIME type overlap:
**TTF and OTF**: Both return `application/font-sfnt`
- When converting from this MIME type, only `TTF` is returned
- Both use the SFNT (Spline Font) container format
**WOFF and WOFF2**: Both currently return `application/font-woff`
- This is likely a bug; WOFF2 should use `font/woff2`
- When converting from MIME type, only `WOFF` is returned
### One-Way Mappings
Some conversions are not perfectly reversible:
```rust
// Extension -> MIME -> Extension may not round-trip
let mime = MimeType::from_ext("dll").unwrap();
// mime.to_string() == "application/vnd.microsoft.portable-executable"
// But from_mime() would return Application::Exe, not Dll
```
### Case Sensitivity
- File extensions are **case-sensitive** in the current implementation
- `.JPG` (uppercase) will not match, only `.jpg` (lowercase) will
- Always normalize extensions to lowercase before using this library
## Publishing
To publish a new version of the crate to crates.io, use the `publish.sh` script:
```bash
./publish.sh <version>
```
For example:
```bash
./publish.sh 0.2.0
```
The script will:
1. Validate the version format (must be X.Y.Z)
2. Check that you're on the `main` branch
3. Verify the version isn't already in `Cargo.toml`
4. Update the version in `Cargo.toml`
5. Commit the changes with message "Release version to X.Y.Z"
6. Create a git tag with the version number
7. Push the tag and changes to the remote repository
Note: The actual publishing to crates.io is done by the GitHub Actions workflow.