this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: make the input filename optional

This changes makes using it in a pipe more reasonable.

+37 -14
+36 -13
src/main.rs
··· 32 32 33 33 #[derive(Args, Debug)] 34 34 struct ExtractArgs { 35 - /// Input file 35 + /// Input/Output file/directory 36 36 #[arg(index = 1)] 37 - input: String, 37 + input: Option<String>, 38 38 39 39 /// Output file/directory 40 40 #[arg(index = 2)] ··· 49 49 50 50 #[derive(Args, Debug)] 51 51 struct CommonArgs { 52 - /// Input file 52 + /// Input/Output file/directory 53 53 #[arg(index = 1)] 54 - input: String, 54 + input: Option<String>, 55 55 56 56 /// Output file/directory 57 57 #[arg(index = 2)] ··· 91 91 compression: u32, 92 92 } 93 93 94 + /// Get the input filename or return an error 95 + fn get_input_filename(input: &Option<String>) -> Result<&String, io::Error> { 96 + match input { 97 + Some(filename) => Ok(filename), 98 + None => Err(io::Error::new( 99 + io::ErrorKind::Other, 100 + "error: no input specified", 101 + )), 102 + } 103 + } 104 + 105 + /// Get the default output filename or return error if the input isn't specified 106 + fn get_default_output<T: Compressor>( 107 + compressor: &T, 108 + input: &Option<String>, 109 + extract: bool, 110 + ) -> Result<String, io::Error> { 111 + match extract { 112 + true => Ok(compressor.default_extracted_filename(Path::new(get_input_filename(input)?))), 113 + false => Ok(compressor.default_compressed_filename(Path::new(get_input_filename(input)?))), 114 + } 115 + } 116 + 94 117 fn command<T: Compressor>(compressor: T) -> Result<(), io::Error> { 95 118 let args = compressor.common_args(); 119 + // Use to provide a longer lifetime for this value 120 + let default_output; 96 121 // Input prefers stdin if that is a pipe, and falls back to reading from a file. 97 122 let input = match std::io::stdin().is_terminal() { 98 - true => CmprssInput::Path(Path::new(&args.input)), 99 123 false => CmprssInput::Pipe(std::io::stdin()), 100 - }; 101 - // Define the default output filename for use if we need it later 102 - let default_output = match args.extract { 103 - true => compressor.default_extracted_filename(Path::new(&args.input)), 104 - false => compressor.default_compressed_filename(Path::new(&args.input)), 124 + true => { 125 + // stdin isn't a pipe, need to read from a file 126 + CmprssInput::Path(Path::new(get_input_filename(&args.input)?)) 127 + } 105 128 }; 106 129 // Output prefers the stdout if we're piping, and falls back to piping to a file. 107 130 // TODO: Not sure that this output logic is the right thing to do ··· 113 136 true => { 114 137 if args.output.is_none() { 115 138 if !std::io::stdin().is_terminal() { 116 - // Use the 'input' file as the output 117 - // TODO: make input file optional and test existence 118 - CmprssOutput::Path(Path::new(&args.input)) 139 + // Stdin is being used as the input, so use the 'input' file as the output 140 + CmprssOutput::Path(Path::new(get_input_filename(&args.input)?)) 119 141 } else { 142 + default_output = get_default_output(&compressor, &args.input, args.extract)?; 120 143 CmprssOutput::Path(Path::new(&default_output)) 121 144 } 122 145 } else {
+1 -1
src/utils.rs
··· 4 4 pub struct CmprssCommonArgs { 5 5 pub compress: bool, 6 6 pub extract: bool, 7 - pub input: String, 7 + pub input: Option<String>, 8 8 pub output: Option<String>, 9 9 } 10 10