//! Functions for console output. 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; /// Format a skill for displaying. /// /// This is just the skill name (if given). fn format_skill(skill: &Option) -> String { match *skill { None => "none".to_owned(), Some(ref skill) => skill.name.to_owned(), } } /// Format a traitline for displaying. fn format_traitline(traitline: &Option) -> String { match *traitline { None => "none".to_owned(), Some((ref spec, choices)) => format!( "{} - {} - {} - {}", spec.name, choices[0], choices[1], choices[2], ), } } /// Show a build template to the standard output stream. 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().name.clone())]; 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(()) } /// Show an error to the standard error stream. /// /// This will also show the chain of errors that lead up to this error, if available. pub fn show_error(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(); while let Some(s) = source { stderr.set_color(&error_color)?; write!(stderr, " [caused by]")?; stderr.reset()?; writeln!(stderr, " {}", s)?; source = s.source(); } Ok(()) }