Creating args for Command

Hey, i started to learn Rust few days ago and would like to get some feedback how to do things rusty. Right now, I want to form an array of args for Command, which depends on a function input. My current code looks like this and works as expected. I have a feeling that it is ugly. How can I improve this code?

fn start_process(&self) -> io::Result<impl Write> {
    let format = &format!("{0}/{1}", self.x, self.y);
    let background;
    let args = {
                let input = ["-w", format];
                if self.background.is_some() {
                    background = self.background.as_ref().unwrap();
                    [
                        &[&background],
                        &input[..],
                        &["/tmp/1.txt"],
                    ].concat()
                } else {
                    [&["-f"], &input[..], &["/tmp/1.txt"]].concat()
                }
             };

let child = Command::new("some_program")
        .args(&args)
        .stdin(Stdio::piped())
        .stdout(Stdio::null())
        .stderr(Stdio::null())
        .spawn()?;

    let stdin = child
        .stdin
        .ok_or_else(|| IoError::new(IoErrorKind::Other, "jkljkll"))?;

    Ok(stdin)
 }

A really good start is to run it through rustfmt, which will output the following:

fn start_process(&self) -> io::Result<impl Write> {
    let format = &format!("{0}/{1}", self.x, self.y);
    let background;
    let args = {
        let input = ["-w", format];
        if self.background.is_some() {
            background = self.background.as_ref().unwrap();
            [&[&background], &input[..], &["/tmp/1.txt"]].concat()
        } else {
            [&["-f"], &input[..], &["/tmp/1.txt"]].concat()
        }
    };

    let child = Command::new("some_program")
        .args(&args)
        .stdin(Stdio::piped())
        .stdout(Stdio::null())
        .stderr(Stdio::null())
        .spawn()?;

    let stdin = child
        .stdin
        .ok_or_else(|| IoError::new(IoErrorKind::Other, "jkljkll"))?;

    Ok(stdin)
}

It's already much better. Things are actually indented properly now. Beyond that, I think it is simpler to use vec! than concat like this:

let args = {
    if self.background.is_some() {
        background = self.background.as_ref().unwrap();
        vec![background, "-w", format, "/tmp/1.txt"]
    } else {
        vec!["-f", "-w", format, "/tmp/1.txt"]
    }
};

Beyond that, I think it is likely that you can avoid the extra let background variable.

1 Like