Boden Garman
Boden Garman

Reputation: 2545

How do I pass a Path to Command::arg?

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

Answers (1)

Shepmaster
Shepmaster

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

Related Questions