Structopt: PathBuf w/ default of stdin?

Created on 18 Apr 2018  路  2Comments  路  Source: TeXitoi/structopt

How does one specify a PathBuf parameter that defaults to stdin? The example in the docs say that it defaults to stdout.

question

Most helpful comment

PathBuf represent a path to a file. stdin and stdout can't be modeled this way. The example saying that default to stdout is purely talking about what the application will do. For example, for your case, just use a Option, and do something like that:

#[macro_use]
extern crate structopt;

use structopt::StructOpt;
use std::io::{self, Read, Write};
use std::fs;
use std::path::PathBuf;

#[derive(StructOpt, Debug)]
struct Opt {
    /// Input file, default to stdin.
    #[structopt(short = "i", parse(from_os_str))]
    input: Option<PathBuf>,
    /// Output file, default to stdout.
    #[structopt(short = "o", parse(from_os_str))]
    output: Option<PathBuf>,
}

fn main() {
    run(Opt::from_args()).unwrap();
}

fn run(opt: Opt) -> io::Result<()> {
    match (opt.input, opt.output) {
        (None, None) => cat(io::stdin(), io::stdout())?,
        (Some(i), Some(o)) => cat(fs::File::open(i)?, fs::File::create(o)?)?,
        (None, Some(o)) => cat(io::stdin(), fs::File::create(o)?)?,
        (Some(i), None) => cat(fs::File::open(i)?, io::stdout())?,
    }
    Ok(())
}

fn cat<R: Read, W: Write>(reader: R, mut writer: W) -> io::Result<()> {
    for b in reader.bytes() {
        writer.write(&[b?])?;
    }
    Ok(())
}

All 2 comments

PathBuf represent a path to a file. stdin and stdout can't be modeled this way. The example saying that default to stdout is purely talking about what the application will do. For example, for your case, just use a Option, and do something like that:

#[macro_use]
extern crate structopt;

use structopt::StructOpt;
use std::io::{self, Read, Write};
use std::fs;
use std::path::PathBuf;

#[derive(StructOpt, Debug)]
struct Opt {
    /// Input file, default to stdin.
    #[structopt(short = "i", parse(from_os_str))]
    input: Option<PathBuf>,
    /// Output file, default to stdout.
    #[structopt(short = "o", parse(from_os_str))]
    output: Option<PathBuf>,
}

fn main() {
    run(Opt::from_args()).unwrap();
}

fn run(opt: Opt) -> io::Result<()> {
    match (opt.input, opt.output) {
        (None, None) => cat(io::stdin(), io::stdout())?,
        (Some(i), Some(o)) => cat(fs::File::open(i)?, fs::File::create(o)?)?,
        (None, Some(o)) => cat(io::stdin(), fs::File::create(o)?)?,
        (Some(i), None) => cat(fs::File::open(i)?, io::stdout())?,
    }
    Ok(())
}

fn cat<R: Read, W: Write>(reader: R, mut writer: W) -> io::Result<()> {
    for b in reader.bytes() {
        writer.write(&[b?])?;
    }
    Ok(())
}

Does it answer your question?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bestouff picture bestouff  路  6Comments

tathanhdinh picture tathanhdinh  路  3Comments

gnzlbg picture gnzlbg  路  5Comments

swfsql picture swfsql  路  3Comments

lucab picture lucab  路  9Comments