This library offers two wrapper types for clap Args that help
for cases where values may be passed in via stdin. When an Arg value is to be read
from stdin, the user will pass the commonly used stdin alias: -
MaybeStdin: Used when a value can be passed in via args ORstdinFileOrStdin: Used when a value can be read in from a file ORstdinFileOrStdout: Used to proxy as a writer for either a file ORstdout
Example usage with clap's derive feature for a positional argument:
use clap::Parser;
use clap_stdin::MaybeStdin;
#[derive(Debug, Parser)]
struct Args {
value: MaybeStdin<String>,
}
let args = Args::parse();
println!("value={}", args.value);Calling this CLI:
# using stdin for positional arg value
$ echo "testing" | cargo run -- -
value=testing[MaybeStdin] can wrap any type that matches the trait bounds for Arg: FromStr and Clone
use std::path::PathBuf;
use clap::Parser;
use clap_stdin::MaybeStdin;
#[derive(Debug, Parser)]
struct Args {
path: MaybeStdin<PathBuf>,
}$ pwd | ./example -Example usage with clap's derive feature for a positional argument:
use clap::Parser;
use clap_stdin::FileOrStdin;
#[derive(Debug, Parser)]
struct Args {
input: FileOrStdin,
}
# fn main() -> anyhow::Result<()> {
let args = Args::parse();
println!("input={}", args.input.contents()?);
# Ok(())
# }Calling this CLI:
# using stdin for positional arg value
$ echo "testing" | cargo run -- -
input=testing
# using filename for positional arg value
$ echo "testing" > input.txt
$ cargo run -- input.txt
input=testing[FileOrStdin] can wrap any type that matches the trait bounds for Arg: FromStr and Clone
use clap::Parser;
use clap_stdin::FileOrStdin;
#[derive(Debug, Parser)]
struct Args {
path: FileOrStdin<u32>,
}# Value from stdin
$ wc ~/myfile.txt -l | ./example -
# Value from file
$ cat myfile.txt
42
$ .example myfile.txtExample usage with clap's derive feature for a positional argument:
use std::io::Write;
use clap::Parser;
use clap_stdin::FileOrStdout;
#[derive(Debug, Parser)]
struct Args {
output: FileOrStdout,
}
# fn main() -> anyhow::Result<()> {
let args = Args::parse();
let mut writer = args.output.into_writer()?;
writeln!(&mut writer, "testing");
# Ok(())
# }Calling this CLI:
# using stdout for positional arg value
$ cargo run -- -
testing
# using filename for positional arg value
$ cargo run -- output.txt
$ cat output.txt
testingWhen using [MaybeStdin] or [FileOrStdin], you can allow your users to omit the "-" character to read from stdin by providing a default_value to clap.
NOTE: This only works with positional args, since clap requires optional args (E.g. using #[arg(long, short)]) to have a value to parse.
use clap::Parser;
use clap_stdin::FileOrStdin;
#[derive(Debug, Parser)]
struct Args {
#[arg(default_value = "-")]
input: FileOrStdin,
}
# fn main() -> anyhow::Result<()> {
let args = Args::parse();
println!("input={}", args.input.contents()?);
# Ok(())
# }Calling this CLI:
# using stdin for positional arg value
$ echo "testing" | cargo run
input=testing
# using filename for positional arg value
$ echo "testing" > input.txt
$ cargo run -- input.txt
input=testingFileOrStdin and FileOrStdout can also be used with tokio::io::AsyncRead and tokio::io::AsyncWrite respectively, using the tokio feature. See [FileOrStdin::contents_async], [FileOrStdin::into_async_reader], and [FileOrStdout::into_async_writer] for examples.
Both [MaybeStdin] and [FileOrStdin] will check at runtime if stdin is being read from multiple times. You can use this
as a feature if you have mutually exclusive args that should both be able to read from stdin, but know
that the user will receive an error if 2+ MaybeStdin args receive the "-" value.
For example, this compiles:
use clap_stdin::{FileOrStdin, MaybeStdin};
#[derive(Debug, clap::Parser)]
struct Args {
first: FileOrStdin,
second: MaybeStdin<u32>,
}and it will work fine if the stdin alias - is only passed for one of the arguments:
$ echo "2" | ./example FIRST -But if stdin is attempted to be used for both arguments, there will be no value for the second arg
$ echo "2" | ./example - -
error: invalid value '-' for '<SECOND>': stdin argument used more than onceclap-stdin is both MIT and Apache License, Version 2.0 licensed, as found
in the LICENSE-MIT and LICENSE-APACHE files.