diff options
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 92 |
1 files changed, 81 insertions, 11 deletions
diff --git a/src/main.rs b/src/main.rs index de2ebb2..c68f26a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,8 @@ mod args; +mod zip; +use std::fs::File; +use std::io; use std::process::ExitCode; fn guess_parser(args: &mut dyn Iterator<Item = String>) -> Box<dyn args::Parser> { @@ -13,7 +16,14 @@ fn guess_parser(args: &mut dyn Iterator<Item = String>) -> Box<dyn args::Parser> Box::new(args::LongOnlyParser::new()) } -fn parse_args() -> Result<bool, String> { +struct Program { + classname: String, + args: Vec<String>, + classpath: String, + verbose: bool, +} + +fn parse_args() -> Result<Option<Program>, String> { let mut options = args::Options::new(); let help_idx = options.push( args::OptionBuilder::default() @@ -38,6 +48,22 @@ fn parse_args() -> Result<bool, String> { .build() .unwrap(), ); + let cp_idx = options.push( + args::OptionBuilder::default() + .long("cp") + .description("class search path of directories and zip/jar files") + .value(args::ValueRequirement::Required("CLASSPATH")) + .build() + .unwrap(), + ); + let classpath_idx = options.push( + args::OptionBuilder::default() + .long("classpath") + .description("class search path of directories and zip/jar files") + .value(args::ValueRequirement::Required("CLASSPATH")) + .build() + .unwrap(), + ); let parser = guess_parser(&mut std::env::args()); let maybe_args = parser.run(&mut options, &mut std::env::args()); @@ -46,33 +72,77 @@ fn parse_args() -> Result<bool, String> { let help = &options[help_idx]; if help.is_set() { parser.print_help(&options); - return Ok(true); + return Ok(None); } let args = maybe_args?; let version = &options[version_idx]; if version.is_set() { println!("Version is 0.0.1"); - return Ok(true); + return Ok(None); } let verbose = &options[verbose_idx]; - println!("verbose: {}", verbose.is_set()); - println!("args: {:?}", args.args); - Ok(false) + let cp = &options[cp_idx]; + let classpath = &options[classpath_idx]; + let actual_classpath: &str; + if cp.is_set() { + if classpath.is_set() { + return Err("Both -cp and -classpath set, pick one.".to_string()); + } + actual_classpath = cp.value().as_ref().unwrap(); + } else if classpath.is_set() { + actual_classpath = classpath.value().as_ref().unwrap(); + } else { + actual_classpath = ""; + } + + let mut run_args = args.args.iter(); + if let Some(classname) = run_args.next() { + Ok(Some(Program { + classname: classname.clone(), + args: run_args.map(|s| s.clone()).collect(), + classpath: actual_classpath.to_string(), + verbose: verbose.is_set(), + })) + } else { + Err("Missing class name".to_string()) + } +} + +fn run(program: Program) -> io::Result<ExitCode> { + let mut paths = program.classpath.split(':'); + let mut file = File::open(paths.next().unwrap())?; + let layout = zip::Layout::new(&mut file)?; + for (name, idx) in layout.names() { + let entry = &layout.entries()[*idx]; + println!( + "{name}: {} {}", + entry.compressed_size(), + entry.uncompressed_size() + ); + } + return Ok(ExitCode::SUCCESS); } fn main() -> ExitCode { match parse_args() { - Ok(exit) => { - if exit { + Ok(maybe_program) => match maybe_program { + Some(program) => match run(program) { + Ok(exit_code) => { + return exit_code; + } + Err(err) => { + eprintln!("{}", err); + return ExitCode::FAILURE; + } + }, + None => { return ExitCode::SUCCESS; } - } + }, Err(msg) => { eprintln!("{}", msg); return ExitCode::FAILURE; } } - - ExitCode::SUCCESS } |
