Readme
clap-stdin
This library offers two wrapper types for clap Arg s 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 OR stdin
FileOrStdin : Used when a value can be read in from a file OR stdin
FileOrStdout : Used to proxy as a writer for either a file OR stdout
MaybeStdin
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
Compatible Types
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 -
FileOrStdin
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
Compatible Types
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.txt
FileOrStdout
Example 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
testing
Reading from Stdin without special characters
When 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=testing
Async Support
FileOrStdin 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.
Using MaybeStdin or FileOrStdin multiple times
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 once
License
clap-stdin is both MIT and Apache License, Version 2.0 licensed, as found
in the LICENSE-MIT and LICENSE-APACHE files.