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

Fre*_*ios 4 string rust

我试图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",
    },
};
Run Code Online (Sandbox Code Playgroud)

编译器说:

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`
Run Code Online (Sandbox Code Playgroud)

She*_*ter 9

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!"),
            }
        }
    };
}
Run Code Online (Sandbox Code Playgroud)

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

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",
        _ => "",
    };
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您想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,
        }
    });
}
Run Code Online (Sandbox Code Playgroud)


Sta*_*eur 7

你可以使用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);
}
Run Code Online (Sandbox Code Playgroud)