Reputation: 2545
I'm getting back into Rust after a long break. I'm trying to do the following:
use std::fs;
use std::path::Path;
use std::process::Command;
fn main() {
let paths = fs::read_dir("SOME_DIRECTORY").unwrap();
for path in paths {
let full_path = path.unwrap().path();
process(full_path);
}
}
fn process<P: AsRef<Path>>(path: P) {
let output = Command::new("gunzip")
.arg("--stdout")
.arg(path.as_os_str())
.output()
.expect("failed to execute process");
}
error[E0599]: no method named `as_os_str` found for type `P` in the current scope
--> src/main.rs:50:23
|
50 | .arg(path.as_os_str())
| ^^^^^^^^^
Command::Arg
is expecting an OsStr, but I am not able to convert the Path into an OsStr for some reason (something to do with the AsRef?)
Upvotes: 0
Views: 1397
Reputation: 430673
If you read the signature for Command::arg
, you can see what types it accepts. It is any type that can be referenced as an OsStr
:
pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command
If you look at the implementors of AsRef
, you will see that Path
is one:
impl AsRef<OsStr> for PathBuf {}
impl AsRef<OsStr> for Path {}
Circling back to your question:
How do I pass a Path to Command::arg?
By passing a Path
to arg
:
fn process(path: &Path) {
let output = Command::new("gunzip")
.arg("--stdout")
.arg(path)
.output()
.expect("failed to execute process");
}
Your issue is that you have accepted a generic P
that is only guaranteed to have one trait implemented: P: AsRef<Path>
. It's not a Path
. That's why the error message tells you there's no method as_os_str
error[E0599]: no method named `as_os_str` found for type `P` in the current scope
The only thing you can do for this type is to call as_ref
. This will return a &Path
:
let output = Command::new("gunzip")
.arg("--stdout")
.arg(path.as_ref())
.output()
.expect("failed to execute process");
Upvotes: 2