qsym2/io/
format.rs

1//! Nice QSym² output formatting.
2
3use std::fmt;
4
5use log;
6
7const QSYM2_BANNER_LENGTH: usize = 103;
8
9/// Logs an error to the `qsym2-output` logger.
10macro_rules! qsym2_error {
11    ($fmt:expr $(, $($arg:tt)*)?) => {
12        log::error!($fmt, $($($arg)*)?);
13        log::error!(target: "qsym2-output", $fmt, $($($arg)*)?);
14    }
15}
16
17/// Logs a warning to the `qsym2-output` logger.
18macro_rules! qsym2_warn {
19    ($fmt:expr $(, $($arg:tt)*)?) => { log::warn!(target: "qsym2-output", $fmt, $($($arg)*)?); }
20}
21
22/// Logs a main output line to the `qsym2-output` logger.
23macro_rules! qsym2_output {
24    ($fmt:expr $(, $($arg:tt)*)?) => { log::info!(target: "qsym2-output", $fmt, $($($arg)*)?); }
25}
26
27pub(crate) use {qsym2_error, qsym2_output, qsym2_warn};
28
29/// Writes a nicely formatted section title.
30pub(crate) fn write_title(f: &mut fmt::Formatter<'_>, title: &str) -> fmt::Result {
31    let length = title.chars().count().max(QSYM2_BANNER_LENGTH - 6);
32    let bar = "─".repeat(length);
33    writeln!(f, "┌──{bar}──┐")?;
34    writeln!(f, "│§ {title:^length$} §│")?;
35    writeln!(f, "└──{bar}──┘")?;
36    Ok(())
37}
38
39/// Logs a nicely formatted section title to the `qsym2-output` logger.
40pub(crate) fn log_title(title: &str) {
41    let length = title.chars().count().max(QSYM2_BANNER_LENGTH - 6);
42    let bar = "─".repeat(length);
43    qsym2_output!("┌──{bar}──┐");
44    qsym2_output!("│§ {title:^length$} §│");
45    qsym2_output!("└──{bar}──┘");
46}
47
48/// Writes a nicely formatted subtitle.
49pub(crate) fn write_subtitle(f: &mut fmt::Formatter<'_>, subtitle: &str) -> fmt::Result {
50    let length = subtitle.chars().count();
51    let bar = "═".repeat(length);
52    writeln!(f, "{subtitle}")?;
53    writeln!(f, "{bar}")?;
54    Ok(())
55}
56
57/// Logs a nicely formatted subtitle to the `qsym2-output` logger.
58pub(crate) fn log_subtitle(subtitle: &str) {
59    let length = subtitle.chars().count();
60    let bar = "═".repeat(length);
61    qsym2_output!("{}", subtitle);
62    qsym2_output!("{}", bar);
63}
64
65/// Logs a nicely formatted macro-section beginning to the `qsym2-output` logger.
66pub(crate) fn log_macsec_begin(sectitle: &str) {
67    let width = QSYM2_BANNER_LENGTH - 14;
68    let sectitle_space = sectitle.to_string() + " ";
69    qsym2_output!("❬❬❬❬❬ [Begin] {sectitle_space:❬<width$}");
70}
71
72/// Logs a nicely formatted macro-section ending to the `qsym2-output` logger.
73pub(crate) fn log_macsec_end(sectitle: &str) {
74    let width = QSYM2_BANNER_LENGTH - 14;
75    let sectitle_space = sectitle.to_string() + " ";
76    qsym2_output!("❭❭❭❭❭ [ End ] {sectitle_space:❭<width$}");
77}
78
79/// Logs a nicely formatted micro-section beginning to the `qsym2-output` logger.
80pub(crate) fn log_micsec_begin(sectitle: &str) {
81    let width = QSYM2_BANNER_LENGTH - 14;
82    let sectitle_space = sectitle.to_string() + " ";
83    qsym2_output!("‹‹‹‹‹ [Begin] {sectitle_space:‹<width$}");
84}
85
86/// Logs a nicely formatted micro-section ending to the `qsym2-output` logger.
87pub(crate) fn log_micsec_end(sectitle: &str) {
88    let width = QSYM2_BANNER_LENGTH - 14;
89    let sectitle_space = sectitle.to_string() + " ";
90    qsym2_output!("››››› [ End ] {sectitle_space:›<width$}");
91}
92
93/// Turns a boolean into a string of `yes` or `no`.
94pub(crate) fn nice_bool(b: bool) -> String {
95    if b {
96        "yes".to_string()
97    } else {
98        "no".to_string()
99    }
100}
101
102/// A trait for logging `QSym2` outputs nicely.
103pub(crate) trait QSym2Output: fmt::Debug + fmt::Display {
104    /// Logs display output nicely.
105    fn log_output_display(&self) {
106        let lines = self.to_string();
107        lines.lines().for_each(|line| {
108            qsym2_output!("{line}");
109        })
110    }
111
112    /// Logs debug output nicely.
113    fn log_output_debug(&self) {
114        let lines = format!("{self:?}");
115        lines.lines().for_each(|line| {
116            qsym2_output!("{line}");
117        })
118    }
119}
120
121// Blanket implementation
122impl<T> QSym2Output for T where T: fmt::Debug + fmt::Display {}