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);
    }
}

这个完整示例展示了:

  1. 文件类型检测的基本用法
  2. 处理多扩展名的MIME类型
  3. 添加和使用自定义MIME类型映射
  4. 封装成可重用的FileTypeDetector结构体

mime2ext库简单易用,适合需要处理文件类型识别的各种场景,如web服务器、文件管理器等应用。

回到顶部