this repo has no description
0
fork

Configure Feed

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

feat(cli): use subcommands

+63 -15
+61 -11
src/main.rs
··· 1 1 mod tar; 2 2 3 - use clap::Parser; 3 + use clap::{Args, Parser, Subcommand}; 4 4 use std::path::Path; 5 5 6 6 /// A compression multi-tool 7 7 #[derive(Parser, Debug)] 8 8 #[command(author, version, about, long_about = None)] 9 - struct Args { 9 + struct CmprssArgs { 10 + /// Format 11 + #[command(subcommand)] 12 + format: Option<Format>, 13 + } 14 + 15 + #[derive(Subcommand, Debug)] 16 + enum Format { 17 + /// tar archive format 18 + Tar(TarArgs), 19 + 20 + /// extract by guessing the format 21 + Extract(ExtractArgs), 22 + } 23 + 24 + #[derive(Args, Debug)] 25 + struct ExtractArgs { 26 + /// Input file 27 + #[arg(index = 1)] 28 + input: String, 29 + 30 + /// Output file/directory 31 + #[arg(index = 2)] 32 + output: Option<String>, 33 + } 34 + 35 + #[derive(Args, Debug)] 36 + struct TarArgs { 10 37 /// Input file 11 38 #[arg(index = 1)] 12 39 input: String, ··· 17 44 #[arg(index = 2)] 18 45 output: Option<String>, 19 46 20 - /// Compress the input 47 + /// Compress the input (default) 21 48 #[arg(short, long)] 22 49 compress: bool, 23 50 24 - /// Extract the input 51 + /// Extract the input file 25 52 #[arg(short, long)] 26 53 extract: bool, 27 54 } ··· 41 68 } 42 69 } 43 70 44 - fn main() { 45 - let args = Args::parse(); 71 + /// Execute a tar command 72 + fn command_tar(args: TarArgs) { 46 73 let input_path = Path::new(&args.input); 47 74 if args.compress { 48 - let out = output_filename(input_path, args.output, tar::extension()); 75 + let out = output_filename(input_path, args.output, tar::EXT); 49 76 tar::compress(input_path, out); 50 77 } else if args.extract { 51 78 tar::extract(input_path, args.output.unwrap_or(".".to_string())); 52 79 } else { 53 - // Neither set, so infer based on filename 54 - if input_path.extension().unwrap() == tar::extension() { 55 - tar::extract(input_path, args.output.unwrap_or(".".to_string())); 80 + // Neither is set. 81 + // Compress by default, warn if if looks like an archive. 82 + if input_path.extension().unwrap() == tar::EXT { 83 + println!( 84 + "error: input appears to be a tar archive, exiting. Use '--compress' if needed." 85 + ) 56 86 } else { 57 - let out = output_filename(input_path, args.output, tar::extension()); 87 + let out = output_filename(input_path, args.output, tar::EXT); 58 88 tar::compress(input_path, out); 59 89 } 60 90 } 61 91 } 92 + 93 + /// Execute an extract command. 94 + /// 95 + /// Attempts to extract based on the file extension. 96 + fn command_extract(args: ExtractArgs) { 97 + let input_path = Path::new(&args.input); 98 + match input_path.extension().unwrap().to_str().unwrap() { 99 + tar::EXT => tar::extract(input_path, args.output.unwrap_or(".".to_string())), 100 + _ => println!("error: unknown format "), 101 + } 102 + } 103 + 104 + fn main() { 105 + let args = CmprssArgs::parse(); 106 + match args.format { 107 + Some(Format::Tar(a)) => command_tar(a), 108 + Some(Format::Extract(a)) => command_extract(a), 109 + None => println!("none"), 110 + }; 111 + }
+2 -4
src/tar.rs
··· 4 4 use std::path::Path; 5 5 use tar::{Archive, Builder}; 6 6 7 - /// Return the standard extension for the tar format. 8 - pub fn extension() -> &'static str { 9 - "tar" 10 - } 7 + /// The standard extension for the tar format. 8 + pub const EXT: &str = "tar"; 11 9 12 10 /// Compress an input file or directory into a tar archive. 13 11 pub fn compress<I: AsRef<Path>, O: AsRef<Path>>(in_file: I, out_file: O) {