如何匹配以 OsStr 表示的文件扩展名?

问题描述 投票:0回答:2

我正在尝试

match
反对文件扩展名:

let file_path = std::path::Path::new("index.html");
let content_type = match file_path.extension() {
    None => "",
    Some(os_str) => match os_str {
        "html" => "text/html",
        "css" => "text/css",
        "js" => "application/javascript",
    },
};

编译器说:

error[E0308]: mismatched types
 --> src/main.rs:6:13
  |
6 |             "html" => "text/html",
  |             ^^^^^^ expected struct `std::ffi::OsStr`, found str
  |
  = note: expected type `&std::ffi::OsStr`
             found type `&'static str`
string rust
2个回答
36
投票

OsStr
OsString
的存在正是因为文件名不是 UTF-8。 Rust 字符串文字是 UTF-8。这意味着您必须处理两种表示形式之间的转换。

一种解决方案是放弃

match
并使用 if-else 语句。请参阅 Stargateur 的回答 作为示例。

您还可以将扩展名转换为字符串。由于扩展名可能不是 UTF-8,因此会返回另一个

Option
:

fn main() {
    let file_path = std::path::Path::new("index.html");
    let content_type = match file_path.extension() {
        None => "",
        Some(os_str) => match os_str.to_str() {
            Some("html") => "text/html",
            Some("css") => "text/css",
            Some("js") => "application/javascript",
            _ => panic!("You forgot to specify this case!"),
        },
    };
}

如果您希望所有情况都使用空字符串作为后备,您可以执行以下操作:

use std::ffi::OsStr;

fn main() {
    let file_path = std::path::Path::new("index.html");
    let content_type = match file_path.extension().and_then(OsStr::to_str) {
        Some("html") => "text/html",
        Some("css") => "text/css",
        Some("js") => "application/javascript",
        _ => "",
    };
}

或者如果您想使用

None
作为后备:

use std::ffi::OsStr;

fn main() {
    let file_path = std::path::Path::new("index.html");

    let content_type = file_path.extension().and_then(OsStr::to_str).and_then(|ext| {
        match ext {
            "html" => Some("text/html"),
            "css" => Some("text/css"),
            "js" => Some("application/javascript"),
            _ => None,
        }
    });
}

14
投票

您可以使用

PartialEq<str>
特征来表示
OsStr

fn main() {
    let file_path = std::path::Path::new("index.html");
    let content_type = match file_path.extension() {
        None => "",
        Some(os_str) => {
            if os_str == "html" {
                "text/html"
            } else if os_str == "css" {
                "text/css"
            } else if os_str == "js" {
                "application/javascript"
            } else {
                ""
            }
        }
    };
    println!("{:?}", content_type);
}
© www.soinside.com 2019 - 2024. All rights reserved.