I am trying to extract the extension of a file from a given String path.
The following piece of code works, but I was wondering if there is a cleaner and more idiomatic Rust way to achieve this:
use std::path::Path;
fn main() {
fn get_extension_from_filename(filename: String) -> String {
//Change it to a canonical file path.
let path = Path::new(&filename).canonicalize().expect(
"Expecting an existing filename",
);
let filepath = path.to_str();
let name = filepath.unwrap().split('/');
let names: Vec<&str> = name.collect();
let extension = names.last().expect("File extension can not be read.");
let extens: Vec<&str> = extension.split(".").collect();
extens[1..(extens.len())].join(".").to_string()
}
assert_eq!(get_extension_from_filename("abc.tar.gz".to_string()) ,"tar.gz" );
assert_eq!(get_extension_from_filename("abc..gz".to_string()) ,".gz" );
assert_eq!(get_extension_from_filename("abc.gz".to_string()) , "gz");
}
use std::path::PathBuf; let path = PathBuf::from("/path/to/file. txt"); let dir = path. parent(). unwrap(); assert_eq!
Developer file written in Rust, a programming language used for developing large-scale, high-performance applications; uses language constructs that help developers avoid common programming errors, such as buffer overflows or lack of type safety.
To get the extension of a file in R, use the file_ext() method. The file_ext() is not a built-in R method. To use the file_ext() method, you need to import the tools library. Now, you can use the file_ext() method.
In idiomatic Rust the return type of a function that can fail should be an Option
or a Result
. In general, functions should also accept slices instead of String
s and only create a new String
where necessary. This reduces excessive copying and heap allocations.
You can use the provided extension()
method and then convert the resulting OsStr
to a &str
:
use std::path::Path;
use std::ffi::OsStr;
fn get_extension_from_filename(filename: &str) -> Option<&str> {
Path::new(filename)
.extension()
.and_then(OsStr::to_str)
}
assert_eq!(get_extension_from_filename("abc.gz"), Some("gz"));
Using and_then
is convenient here because it means you don't have to unwrap the Option<&OsStr>
returned by extension()
and deal with the possibility of it being None
before calling to_str
. I also could have used a lambda |s| s.to_str()
instead of OsStr::to_str
- it might be a matter of preference or opinion as to which is more idiomatic.
Notice that both the argument &str
and the return value are references to the original string slice created for the assertion. The returned slice cannot outlive the original slice that it is referencing, so you may need to create an owned String
from this result if you need it to last longer.
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