diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/api/mod.rs | 2 | ||||
-rw-r--r-- | src/bt.rs | 4 | ||||
-rw-r--r-- | src/main.rs | 107 | ||||
-rw-r--r-- | src/output.rs | 4 | ||||
-rw-r--r-- | src/render.rs | 18 |
5 files changed, 63 insertions, 72 deletions
diff --git a/src/api/mod.rs b/src/api/mod.rs index 7cec4e6..0b823ae 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -241,7 +241,7 @@ impl Api { fn sanitize_id(input: &str) -> String { input.replace( |c: char| { - let is_valid = c.is_ascii() && (c.is_digit(10) || c.is_alphabetic()); + let is_valid = c.is_ascii() && (c.is_ascii_digit() || c.is_alphabetic()); !is_valid }, "", @@ -276,9 +276,7 @@ impl BuildTemplate { // utilities (the active ones are saved in the normal skill slots). // The order is terrestric 1/2/3 and then aquatic 1/2/3, with 2 bytes per skill. // We don't care about that, so just do whatever. - for _ in 0..12 { - bytes.push(0); - } + bytes.resize(bytes.len() + 12, 0); format!("[&{}]", base64::encode(&bytes)) } diff --git a/src/main.rs b/src/main.rs index 1d7376c..9d0e62f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ mod render; mod useropts; use anyhow::{Context, Result}; -use clap::{App, Arg, ArgMatches}; +use clap::{Arg, ArgAction, ArgMatches, Command}; use thiserror::Error; use api::{Api, Profession, Skill}; @@ -127,17 +127,17 @@ fn resolve_traitline(api: &mut Api, profession: &Profession, text: &str) -> Resu /// Create the build template by manually combining the given skills/traitlines from the CLI. fn run_searching(api: &mut Api, matches: &ArgMatches) -> Result<BuildTemplate> { let requested_profession = matches - .value_of("profession") + .get_one::<String>("profession") .expect("clap handles missing argument"); let profession = find_profession(api, requested_profession)?; let legends = matches - .values_of("legend") - .map(Iterator::collect::<Vec<_>>) + .get_many::<String>("legend") + .map(Iterator::collect::<Vec<&String>>) .unwrap_or_default() .into_iter() - .map(str::parse) + .map(|s| s.parse()) .map(Result::unwrap) .collect::<Vec<_>>(); @@ -153,7 +153,7 @@ fn run_searching(api: &mut Api, matches: &ArgMatches) -> Result<BuildTemplate> { let skills = if profession.code != CODE_REVENANT { matches - .values_of("skill") + .get_many::<String>("skill") .map(Iterator::collect::<Vec<_>>) .unwrap_or_default() .into_iter() @@ -162,7 +162,7 @@ fn run_searching(api: &mut Api, matches: &ArgMatches) -> Result<BuildTemplate> { } else if let Some(l) = legends.first() { let l = api.get_legends(&[l.api_id().unwrap()])?.single(); let mut result = Vec::new(); - for skill_id in (&[l.heal]).iter().chain(&l.utilities).chain(&[l.elite]) { + for skill_id in [l.heal].iter().chain(&l.utilities).chain(&[l.elite]) { let skill = api.get_skills(&[*skill_id])?.single(); result.push(skill); } @@ -172,7 +172,7 @@ fn run_searching(api: &mut Api, matches: &ArgMatches) -> Result<BuildTemplate> { }; let traitlines = matches - .values_of("traitline") + .get_many::<String>("traitline") .map(Iterator::collect::<Vec<_>>) .unwrap_or_default() .into_iter() @@ -193,12 +193,12 @@ fn run_searching(api: &mut Api, matches: &ArgMatches) -> Result<BuildTemplate> { /// Create the build template by parsing a chat link. fn run_chatlink(api: &mut Api, matches: &ArgMatches) -> Result<BuildTemplate> { - let link = matches.value_of("chatlink").unwrap(); + let link = matches.get_one::<String>("chatlink").unwrap(); Ok(BuildTemplate::from_chatlink(api, link)?) } /// Make sure a traitline is in the `"traitline:choice1:choice2:choice3"` format. -fn validate_traitline_format(input: String) -> Result<(), String> { +fn validate_traitline_format(input: &str) -> Result<String, String> { let parts = input.split(':').collect::<Vec<_>>(); if parts.len() != 4 { return Err("traitline format is line:trait_1:trait_2:trait_3".to_owned()); @@ -214,114 +214,107 @@ fn validate_traitline_format(input: String) -> Result<(), String> { } } - Ok(()) + Ok(input.into()) } /// Make sure a legend is valid. -fn validate_legend(input: String) -> Result<(), String> { +fn validate_legend(input: &str) -> Result<Legend, String> { input .parse::<Legend>() - .map(|_| ()) .map_err(|_| "invalid legend name".to_owned()) } fn run() -> Result<()> { - let matches = App::new(APP_NAME) + let matches = Command::new(APP_NAME) .version("0.1") .author("Peter Parker IV") .about("Renders Guild Wars 2 skills and traits.") .arg( - Arg::with_name("profession") + Arg::new("profession") .help("Selects which profession to use.") - .required_unless("chatlink"), + .required_unless_present("chatlink"), ) .arg( - Arg::with_name("skill") + Arg::new("skill") .help("Selects a skill based on either the name or the ID.") - .takes_value(true) - .number_of_values(1) + .num_args(1) .long("skill") - .short("s") - .multiple(true) - .max_values(bt::SKILL_COUNT as u64), + .short('s') + .action(ArgAction::Append), ) .arg( - Arg::with_name("traitline") + Arg::new("traitline") .help("Selects a traitline.") - .takes_value(true) - .number_of_values(1) + .num_args(1) .long("traitline") - .short("t") - .multiple(true) - .validator(validate_traitline_format) - .max_values(bt::TRAITLINE_COUNT as u64), + .short('t') + .action(ArgAction::Append) + .value_parser(validate_traitline_format), ) .arg( - Arg::with_name("legend") + Arg::new("legend") .help("Selects a revenant legend.") - .takes_value(true) - .number_of_values(1) + .num_args(1) .long("legend") - .short("l") - .multiple(true) - .max_values(bt::LEGEND_COUNT as u64) - .validator(validate_legend), + .short('l') + .action(ArgAction::Append) + .value_parser(validate_legend), ) .arg( - Arg::with_name("chatlink") + Arg::new("chatlink") .help("Specifies a chat link to parse.") - .short("c") + .short('c') .long("chatlink") - .takes_value(true) - .conflicts_with_all(&["profession", "skill"]), + .num_args(1) + .conflicts_with_all(["profession", "skill"]), ) .arg( - Arg::with_name("quiet") + Arg::new("quiet") .help("Surpress console output except for the chat code.") - .short("q") + .short('q') .long("quiet") - .takes_value(false), + .action(ArgAction::SetTrue), ) .arg( - Arg::with_name("outfile") + Arg::new("outfile") .help("Specifies the output filename") - .short("o") + .short('o') .long("outfile") .default_value("buildtemplate.png") - .takes_value(true), + .num_args(1), ) .arg( - Arg::with_name("no-cache") + Arg::new("no-cache") .help("Disables the cache") .long("no-cache") - .takes_value(false), + .action(ArgAction::SetTrue), ) .arg( - Arg::with_name("config") + Arg::new("config") .help("Specifies the render option file.") .long("config") - .takes_value(true), + .num_args(1), ) .get_matches(); - let mut api = if matches.is_present("no-cache") { + let mut api = if *matches.get_one::<bool>("no-cache").unwrap() { Api::new(cache::NoopCache::new()) } else { Api::new(cache::FileCache::new()) }; - let build = if matches.is_present("chatlink") { + let build = if matches.contains_id("chatlink") { run_chatlink(&mut api, &matches)? } else { run_searching(&mut api, &matches)? }; - if !matches.is_present("quiet") { + if !matches.get_one::<bool>("quiet").unwrap() { output::show_build_template(&build)?; } else { println!("{}", build.chatlink()); } - let render_options = if let Some(config_path) = matches.value_of("config") { + let render_options = if let Some(config_path) = matches.get_one::<String>("config") { useropts::load_file(config_path)? } else { Default::default() @@ -330,10 +323,10 @@ fn run() -> Result<()> { let mut renderer = render::Renderer::new(&mut api, render_options); match renderer.render_buildtemplate(&build) { Ok(img) => { - let filename = matches.value_of("outfile").unwrap(); + let filename = matches.get_one::<String>("outfile").unwrap(); img.save(filename)?; - if !matches.is_present("quiet") { - println!("Image saved in {}", filename); + if !matches.get_one::<bool>("quiet").unwrap() { + println!("Image saved in {:?}", filename); } } Err(RenderError::EmptyBuild) => (), diff --git a/src/output.rs b/src/output.rs index 8186a61..da4143f 100644 --- a/src/output.rs +++ b/src/output.rs @@ -41,12 +41,12 @@ pub fn show_build_template(build: &BuildTemplate) -> io::Result<()> { fields.push(("Skills:", format_skill(&build.skills()[0]))); for skill in build.skills().iter().skip(1) { - fields.push(("", format_skill(&skill))); + fields.push(("", format_skill(skill))); } fields.push(("Traitlines:", format_traitline(&build.traitlines()[0]))); for traitline in build.traitlines().iter().skip(1) { - fields.push(("", format_traitline(&traitline))); + fields.push(("", format_traitline(traitline))); } for (header, field) in &fields { diff --git a/src/render.rs b/src/render.rs index b971426..5c091d1 100644 --- a/src/render.rs +++ b/src/render.rs @@ -165,8 +165,8 @@ impl<'r> Renderer<'r> { imageops::overlay( buffer, &minor_img, - x - half(trait_size), - y - half(trait_size), + (x - half(trait_size)).into(), + (y - half(trait_size)).into(), ); Ok(()) } @@ -193,8 +193,8 @@ impl<'r> Renderer<'r> { imageops::overlay( buffer, &major_img, - x - half(trait_size), - y - half(trait_size), + (x - half(trait_size)).into(), + (y - half(trait_size)).into(), ); Ok(()) } @@ -269,7 +269,7 @@ impl<'r> Renderer<'r> { let minor_traits = self.api.get_traits(&spec.minor_traits)?; for minor in &minor_traits { - self.render_minor_trait(&mut buffer, &minor)?; + self.render_minor_trait(&mut buffer, minor)?; } let major_traits = self.api.get_traits(&spec.major_traits)?; @@ -277,7 +277,7 @@ impl<'r> Renderer<'r> { let choice = choices[major.tier as usize - 1]; let vert_pos = (i as u32 % TRAITS_PER_TIER) as u8; let chosen = choice as u8 == vert_pos + 1; - self.render_major_trait(&mut buffer, &major, vert_pos, chosen)?; + self.render_major_trait(&mut buffer, major, vert_pos, chosen)?; } for (tier, choice) in choices.iter().enumerate() { @@ -333,7 +333,7 @@ impl<'r> Renderer<'r> { let header = self.render_specialization_name(&traitline.0)?; images.push((self.options.specialization_name_alignment, header)); } - let inner = self.render_traitline(&traitline)?; + let inner = self.render_traitline(traitline)?; images.push((Alignment::Left, inner)); } @@ -478,8 +478,8 @@ fn draw_thick_line<I>( imageops::overlay( image, &line_buffer, - half_x - half(line_length), - half_y - half(line_length), + (half_x - half(line_length)).into(), + (half_y - half(line_length)).into(), ); } |