I am trying to match
against a file extension:
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",
},
};
The compiler says:
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`
Returns the length of this OsStr. Note that this does not return the number of bytes in the string in OS string form. The length returned is that of the underlying storage used by OsStr .
&OsStr is to OsString as & str is to String: the former in each pair are borrowed references; the latter are owned strings. See the module’s toplevel documentation about conversions for a discussion on the traits which OsStr implements for conversions from/to native representations. pub fn new <S: AsRef < OsStr > + ? Sized > (s: & S) -> & OsStr
The ‘File Format and Extension of Don’t Match’ error appear when the user tries to open certain files in Excel. Even if the user clicks on Yes to open it, all previously saved information on that file will be gone.
Common file name extensions in Windows. 1 In the search box on the taskbar, type file explorer, and in the search results, select File Explorer. 2 In File Explorer under View, in the Show/hide group, select the File name extensions check box.
OsStr
and OsString
exist precisely because filenames are not UTF-8. A Rust string literal is UTF-8. That means you must deal with converting between the two representations.
One solution is to give up the match
and use if-else statements. See Stargateur's answer for an example.
You can also convert the extension to a string. Since the extension might not be UTF-8, this returns another 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!"),
}
}
};
}
If you want all cases to use an empty string as the fallback, you can do something like:
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",
_ => "",
};
}
Or if you want to use None
as the fallback:
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,
}
});
}
You could use PartialEq<str>
trait for 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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With