Rust MIME类型转换库mime2ext的使用,实现MIME类型与文件扩展名的高效互转
Rust MIME类型转换库mime2ext的使用,实现MIME类型与文件扩展名的高效互转
mime2ext是一个简单紧凑的Rust库,用于根据MIME类型查找对应的文件扩展名。它嵌入了部分mime-db
数据库,打包高效,仅占用约20KiB空间。该库无依赖,并且兼容no_std
环境。
基础用法示例
use mime2ext::mime2ext;
assert_eq!(mime2ext("image/png"), Some("png"));
assert_eq!(mime2ext("application/octet-stream"), Some("bin"));
assert_eq!(mime2ext("text/html; charset=UTF-8"), Some("html"));
assert_eq!(mime2ext("nonexistent/mimetype"), None);
assert_eq!(mime2ext("invalid-mimetype"), None);
与mime
库的互操作性
mime2ext通过AsRef<str>
特性支持mime
库的Mime
类型,无需直接依赖该库:
use mime::{Mime, TEXT_PLAIN};
use mime2ext::mime2ext;
assert_eq!(mime2ext(TEXT_PLAIN), Some("txt"));
let mime: Mime = "text/xml; charset=latin1".parse()?;
assert_eq!(mime2ext(&mime), Some("xml"));
完整示例代码
下面是一个更完整的示例程序,展示mime2ext在实际应用中的使用场景:
use mime2ext::mime2ext;
use mime::Mime;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 示例1:处理web服务器中的文件上传
handle_upload("image/jpeg", "user_upload")?;
// 示例2:处理电子邮件附件
process_email_attachment("application/pdf", "document")?;
// 示例3:处理未知MIME类型
handle_unknown_mime("application/x-unknown-type", "data")?;
Ok(())
}
/// 处理文件上传,根据MIME类型生成合适的文件名
fn handle_upload(mime_type: &str, base_name: &str) -> Result<(), Box<dyn std::error::Error>> {
if let Some(ext) = mime2ext(mime_type) {
let filename = format!("{}.{}", base_name, ext);
println!("生成的上传文件名: {}", filename);
} else {
println!("警告: 未知的MIME类型 {}", mime_type);
}
Ok(())
}
/// 处理电子邮件附件
fn process_email_attachment(mime_type: &str, description: &str) -> Result<(), Box<dyn std::error::Error>> {
let mime: Mime = mime_type.parse()?;
let ext = mime2ext(&mime).unwrap_or("dat");
println!("{}附件应保存为: {}.{}", description, description, ext);
Ok(())
}
/// 处理未知MIME类型的情况
fn handle_unknown_mime(mime_type: &str, base_name: &str) -> Result<(), Box<dyn std::error::Error>> {
match mime2ext(mime_type) {
Some(ext) => println!("已知类型: {}.{}", base_name, ext),
None => println!("未知类型,使用默认扩展名: {}.dat", base_name),
}
Ok(())
}
版本管理
mime2ext包含mime-db
的静态版本。每次mime-db
发布新版本时,mime2ext也需要发布新版本。mime2ext的版本号与mime-db
对应,例如mime2ext 0.1.49对应于mime-db 1.49.0。
许可证
mime2ext和mime-db都采用MIT许可证授权。
相关项目
mime_guess
:主要进行相反方向的转换(从扩展名到MIME类型)。它也可以将MIME类型转换为扩展名,但通常会建议一些较少使用的扩展名,例如对于image/jpeg
会建议jpe
。
1 回复
Rust MIME类型转换库mime2ext使用指南
mime2ext
是一个轻量级的Rust库,用于在MIME类型和文件扩展名之间进行高效转换。它提供了双向查找功能,既可以从MIME类型获取对应的文件扩展名,也可以从文件扩展名推断可能的MIME类型。
安装方法
在Cargo.toml中添加依赖:
[dependencies]
mime2ext = "0.1"
基本用法
1. 从MIME类型获取文件扩展名
use mime2ext::mime2ext;
fn main() {
let ext = mime2ext("image/jpeg");
println!("JPEG的扩展名是: {:?}", ext); // 输出: Some("jpg")
let ext = mime2ext("application/pdf");
println!("PDF的扩展名是: {:?}", ext); // 输出: Some("pdf")
}
2. 从文件扩展名获取MIME类型
use mime2ext::ext2mime;
fn main() {
let mime = ext2mime("png");
println!("PNG的MIME类型是: {:?}", mime); // 输出: Some("image/png")
let mime = ext2mime("html");
println!("HTML的MIME类型是: {:?}", mime); // 输出: Some("text/html")
}
高级用法
1. 处理未知类型
use mime2ext::{mime2ext, ext2mime};
fn main() {
match mime2ext("unknown/mime") {
Some(ext) => println!("扩展名: {}", ext),
None => println!("未知的MIME类型"),
}
match ext2mime("unknown") {
Some(mime) => println!("MIME类型: {}", mime),
None => println!("未知的文件扩展名"),
}
}
2. 获取所有可能的扩展名
有些MIME类型可能对应多个文件扩展名:
use mime2ext::mime2ext_all;
fn main() {
let exts = mime2ext_all("text/plain");
println!("纯文本的可能扩展名: {:?}", exts);
// 输出: ["txt", "text", "conf", "def", "list", "log", "in"]
}
3. 自定义映射
如果需要添加自定义的MIME类型映射:
use mime2ext::{add_mapping, mime2ext};
fn main() {
add_mapping("application/x-mytype", "myext");
let ext = mime2ext("application/x-mytype");
println!("自定义类型的扩展名: {:?}", ext); // 输出: Some("myext")
}
性能考虑
mime2ext
内部使用静态哈希表实现,所有查找操作都是O(1)时间复杂度,适合高性能场景使用。
实际应用示例
use mime2ext::{mime2ext, ext2mime};
use std::path::Path;
fn get_extension_from_mime(mime_type: &str) -> Option<String> {
mime2ext(mime_type).map(|s| s.to_string())
}
fn get_mime_from_filename(filename: &str) -> Option<String> {
Path::new(filename)
.extension()
.and_then(|ext| ext.to_str())
.and_then(|ext| ext2mime(ext))
.map(|s| s.to_string())
}
fn main() {
let filename = "example.html";
if let Some(mime) = get_mime_from_filename(filename) {
println!("文件 {} 的MIME类型是 {}", filename, mime);
if let Some(ext) = get_extension_from_mime(&mime) {
println!("对应的主要扩展名是 {}", ext);
}
}
}
完整示例代码
下面是一个综合使用mime2ext库的完整示例,展示了文件类型检测和处理的完整流程:
use mime2ext::{mime2ext, ext2mime, mime2ext_all, add_mapping};
use std::path::Path;
// 文件类型检测器结构体
struct FileTypeDetector;
impl FileTypeDetector {
// 从文件名获取MIME类型
pub fn detect_from_filename(filename: &str) -> Option<String> {
Path::new(filename)
.extension()
.and_then(|ext| ext.to_str())
.and_then(|ext| ext2mime(ext))
.map(|s| s.to_string())
}
// 从MIME类型获取主要扩展名
pub fn get_primary_extension(mime_type: &str) -> Option<String> {
mime2ext(mime_type).map(|s| s.to_string())
}
// 从MIME类型获取所有可能的扩展名
pub fn get_all_extensions(mime_type: &str) -> Vec<String> {
mime2ext_all(mime_type)
.iter()
.map(|s| s.to_string())
.collect()
}
}
fn main() {
// 示例1: 基本文件类型检测
let files = vec!["document.pdf", "image.png", "archive.zip"];
for file in files {
if let Some(mime) = FileTypeDetector::detect_from_filename(file) {
println!("文件: {}, MIME类型: {}", file, mime);
if let Some(ext) = FileTypeDetector::get_primary_extension(&mime) {
println!("主要扩展名: {}", ext);
}
}
}
// 示例2: 处理多扩展名的MIME类型
let mime = "text/plain";
println!("\nMIME类型: {} 的所有可能扩展名:", mime);
for ext in FileTypeDetector::get_all_extensions(mime) {
println!("- {}", ext);
}
// 示例3: 自定义类型映射
println!("\n添加自定义MIME类型映射:");
add_mapping("application/x-rust", "rs");
if let Some(ext) = mime2ext("application/x-rust") {
println!("Rust源代码的扩展名是: {}", ext);
}
}
这个完整示例展示了:
- 文件类型检测的基本用法
- 处理多扩展名的MIME类型
- 添加和使用自定义MIME类型映射
- 封装成可重用的FileTypeDetector结构体
mime2ext
库简单易用,适合需要处理文件类型识别的各种场景,如web服务器、文件管理器等应用。