1mod formatter;
2mod progress;
3
4pub use formatter::OutputFormatter;
5pub use progress::ProgressReporter;
6
7use crate::cli::Args;
8use crate::openssl::ParsedPfx;
9use colored::*;
10use console::Term;
11use std::io::{self, Write};
12
13#[derive(Debug, Clone)]
15pub struct OutputConfig {
16 pub use_colors: bool,
17 pub verbose: bool,
18 pub interactive: bool,
19}
20
21impl OutputConfig {
22 pub fn from_args(args: &Args) -> Self {
23 let term = Term::stdout();
24 Self {
25 use_colors: term.features().colors_supported(),
26 verbose: args.verbose,
27 interactive: term.features().is_attended(),
28 }
29 }
30}
31
32pub struct OutputHandler {
34 config: OutputConfig,
35 term: Term,
36}
37
38impl OutputHandler {
39 pub fn new(config: OutputConfig) -> Self {
40 Self {
41 config,
42 term: Term::stdout(),
43 }
44 }
45
46 pub fn status(&mut self, message: &str) -> io::Result<()> {
48 if self.config.use_colors {
49 writeln!(self.term, "{} {}", "⚡".bright_yellow(), message.bold())?;
50 } else {
51 writeln!(self.term, "=> {}", message)?;
52 }
53 Ok(())
54 }
55
56 pub fn success(&mut self, message: &str) -> io::Result<()> {
58 if self.config.use_colors {
59 writeln!(self.term, "{} {}", "✓".bright_green(), message)?;
60 } else {
61 writeln!(self.term, "✓ {}", message)?;
62 }
63 Ok(())
64 }
65
66 pub fn info(&mut self, message: &str) -> io::Result<()> {
68 if self.config.verbose {
69 if self.config.use_colors {
70 writeln!(self.term, "{} {}", "ℹ".bright_blue(), message.dimmed())?;
71 } else {
72 writeln!(self.term, "i {}", message)?;
73 }
74 }
75 Ok(())
76 }
77
78 pub fn print_summary(&mut self, args: &Args, parsed: &ParsedPfx) -> io::Result<()> {
80 let formatter = OutputFormatter::new(&self.config);
81 formatter.print_summary(args, parsed, &mut self.term)
82 }
83
84 pub fn print_cert_info(&mut self, parsed: &ParsedPfx) -> io::Result<()> {
86 if self.config.verbose {
87 let formatter = OutputFormatter::new(&self.config);
88 formatter.print_cert_info(parsed, &mut self.term)?;
89 }
90 Ok(())
91 }
92}