diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bt.rs | 12 | ||||
-rw-r--r-- | src/main.rs | 44 | ||||
-rw-r--r-- | src/output.rs | 87 |
3 files changed, 118 insertions, 25 deletions
@@ -86,6 +86,18 @@ impl FromStr for TraitChoice { } } +impl fmt::Display for TraitChoice { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let result = match *self { + TraitChoice::None => "none", + TraitChoice::Top => "top", + TraitChoice::Middle => "mid", + TraitChoice::Bottom => "bot", + }; + write!(f, "{}", result) + } +} + /// Represents a revenenant legend. #[repr(u8)] #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, IntoPrimitive, TryFromPrimitive)] diff --git a/src/main.rs b/src/main.rs index 6c8c723..397171c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,15 +15,14 @@ extern crate quick_error; use std::error::Error as StdError; use std::fmt; -use std::io::Write; mod api; mod bt; mod cache; +mod output; mod render; use clap::{App, Arg, ArgMatches}; -use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; use api::{Api, Profession, Skill}; use bt::{BuildTemplate, ExtraData, Legend, TraitChoice, Traitline}; @@ -273,6 +272,13 @@ fn run() -> MainResult<()> { .conflicts_with_all(&["profession", "skill"]), ) .arg( + Arg::with_name("quiet") + .help("Surpress console output except for the chat code.") + .short("q") + .long("quiet") + .takes_value(false), + ) + .arg( Arg::with_name("outfile") .help("Specifies the output filename") .short("o") @@ -289,40 +295,28 @@ fn run() -> MainResult<()> { run_searching(&mut api, &matches)? }; - println!("Chat code: {}", build.chatlink()); + if !matches.is_present("quiet") { + output::show_build_template(&build)?; + } else { + println!("{}", build.chatlink()); + } let mut renderer = render::Renderer::new(&mut api, Default::default()); let img = renderer.render_buildtemplate(&build).unwrap(); let filename = matches.value_of("outfile").unwrap(); img.save(filename)?; + if !matches.is_present("quiet") { + println!("Image saved in {}", filename); + } + Ok(()) } fn main() { let result = run(); if let Err(e) = result { - let mut error_color = ColorSpec::new(); - error_color.set_fg(Some(Color::Red)); - let mut stderr = StandardStream::stderr(ColorChoice::Auto); - stderr.set_color(&error_color).unwrap(); - write!(stderr, "[Error]").unwrap(); - stderr.reset().unwrap(); - writeln!(stderr, " {}", e).unwrap(); - - let mut source = e.source(); - if source.is_none() { - source = e.cause(); - } - while let Some(s) = source { - stderr.set_color(&error_color).unwrap(); - write!(stderr, " [caused by]").unwrap(); - stderr.reset().unwrap(); - writeln!(stderr, " {}", s).unwrap(); - source = s.source(); - if source.is_none() { - source = s.cause(); - } - } + output::show_error(e.as_ref()).expect("Error while displaying error"); + std::process::exit(1); } } diff --git a/src/output.rs b/src/output.rs new file mode 100644 index 0000000..2a2546f --- /dev/null +++ b/src/output.rs @@ -0,0 +1,87 @@ +use super::{ + api, + bt::{BuildTemplate, Traitline}, +}; +use std::{error::Error, io, io::Write}; +use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; + +const HEADER_COLOR: Color = Color::Cyan; + +fn format_skill(skill: &Option<api::Skill>) -> String { + match *skill { + None => "none".to_owned(), + Some(ref skill) => skill.name.to_owned(), + } +} + +fn format_traitline(traitline: &Option<Traitline>) -> String { + match *traitline { + None => "none".to_owned(), + Some((ref spec, choices)) => format!( + "{} - {} - {} - {}", + spec.name, choices[0], choices[1], choices[2], + ), + } +} + +pub fn show_build_template(build: &BuildTemplate) -> io::Result<()> { + let mut stdout = StandardStream::stdout(ColorChoice::Auto); + let mut color_spec = ColorSpec::new(); + color_spec.set_fg(Some(HEADER_COLOR)); + color_spec.set_bold(true); + + let mut fields = vec![("Profession:", build.profession().to_string())]; + + fields.push(("Skills:", format_skill(&build.skills()[0]))); + for skill in build.skills().iter().skip(1) { + 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))); + } + + for (header, field) in &fields { + stdout.set_color(&color_spec)?; + write!(stdout, "{:15}", header)?; + stdout.reset()?; + writeln!(stdout, "{}", field)?; + } + + writeln!(stdout)?; + stdout.set_color(&color_spec)?; + write!(stdout, "{:15}", "Chat code:")?; + stdout.reset()?; + writeln!(stdout, "{}", build.chatlink())?; + + Ok(()) +} + +pub fn show_error<E: Error + ?Sized>(error: &E) -> io::Result<()> { + let mut error_color = ColorSpec::new(); + error_color.set_fg(Some(Color::Red)); + let mut stderr = StandardStream::stderr(ColorChoice::Auto); + + stderr.set_color(&error_color)?; + write!(stderr, "[Error]")?; + stderr.reset()?; + writeln!(stderr, " {}", error)?; + + let mut source = error.source(); + if source.is_none() { + source = error.cause(); + } + while let Some(s) = source { + stderr.set_color(&error_color)?; + write!(stderr, " [caused by]")?; + stderr.reset()?; + writeln!(stderr, " {}", s)?; + + source = s.source(); + if source.is_none() { + source = s.cause(); + } + } + Ok(()) +} |