stapix

Yet another static page generator for photo galleries

log.rs (4670B)

  1 //! Macros for logging.
  2 //!
  3 //! This implementation should be thread safe (unlink an implementation using
  4 //! `println!` and `eprintln!`) because access to the global stdout/stderr
  5 //! handle is syncronized using a lock.
  6 use crossterm::style::Stylize;
  7 use std::{io::{self, Write}, fmt::Arguments};
  8 
  9 #[derive(Clone, Copy, Debug)]
 10 pub(crate) enum Level {
 11     Error,
 12     Info,
 13     Warn,
 14 }
 15 
 16 pub(crate) fn log(level: Level, args: &Arguments<'_>, newline: bool) {
 17     match level {
 18         Level::Error => {
 19             let mut stderr = io::stderr();
 20             let _ = write!(stderr, "{} ", "[ERROR]".red().bold());
 21             let _ = if newline {
 22                 writeln!(stderr, "{}", args)
 23             } else {
 24                 write!(stderr, "{}", args)
 25             };
 26             if !newline { let _ = stderr.flush(); }
 27         }
 28         Level::Info => {
 29             let mut stdout = io::stdout().lock();
 30             let _ = write!(stdout, "{} ", "[INFO]".green().bold());
 31             let _ = if newline {
 32                 writeln!(stdout, "{}", args)
 33             } else {
 34                 write!(stdout, "{}", args)
 35             };
 36             if !newline { let _ = stdout.flush(); }
 37         }
 38         Level::Warn => {
 39             let mut stdout = io::stdout().lock();
 40             let _ = write!(stdout, "{} ", "[WARNING]".yellow().bold());
 41             let _ = if newline {
 42                 writeln!(stdout, "{}", args)
 43             } else {
 44                 write!(stdout, "{}", args)
 45             };
 46             if !newline { let _ = stdout.flush(); }
 47         }
 48     }
 49 }
 50 
 51 #[macro_export]
 52 macro_rules! info {
 53     // info!("a {} event", "log");
 54     ($($arg:tt)+) => ({
 55         $crate::log::log(
 56             $crate::log::Level::Info,
 57             &std::format_args!($($arg)+),
 58             false,
 59         );
 60     });
 61 }
 62 
 63 #[macro_export]
 64 macro_rules! infoln {
 65     // infoln!("a {} event", "log");
 66     ($($arg:tt)+) => ({
 67         $crate::log::log(
 68             $crate::log::Level::Info,
 69             &std::format_args!($($arg)+),
 70             true,
 71         );
 72     });
 73 }
 74 
 75 #[macro_export]
 76 macro_rules! info_done {
 77     () => ({
 78         let _ = writeln!(io::stdout().lock(), " Done!");
 79     });
 80 
 81     // infoln!("a {} event", "log");
 82     ($($arg:tt)+) => ({
 83         let _ = writeln!(
 84             io::stdout().lock(),
 85             " {}",
 86             &std::format_args!($($arg)+)
 87         );
 88     });
 89 }
 90 
 91 #[macro_export]
 92 macro_rules! error {
 93     // info!("a {} event", "log");
 94     ($($arg:tt)+) => ({
 95         $crate::log::log(
 96             $crate::log::Level::Error,
 97             &std::format_args!($($arg)+),
 98             false,
 99         );
100     });
101 }
102 
103 #[macro_export]
104 macro_rules! errorln {
105     // errorln!("a {} event", "log");
106     ($($arg:tt)+) => ({
107         $crate::log::log(
108             $crate::log::Level::Error,
109             &std::format_args!($($arg)+),
110             true,
111         );
112     });
113 }
114 
115 #[macro_export]
116 macro_rules! warnln {
117     // info!("a {} event", "log");
118     ($($arg:tt)+) => ({
119         $crate::log::log(
120             $crate::log::Level::Warn,
121             &std::format_args!($($arg)+),
122             true,
123         );
124     });
125 }
126 
127 #[macro_export]
128 macro_rules! usage {
129     ($program:expr) => {
130         let mut stderr = io::stderr();
131         let _ = writeln!(
132             stderr,
133             "{usage_header_msg} {} config.yml [--full-build]",
134             $program,
135             usage_header_msg = "[USAGE]".yellow().bold()
136         );
137     };
138 }
139 
140 #[macro_export]
141 macro_rules! usage_config {
142     () => {
143         let mut stderr = io::stderr();
144 
145         let _ = writeln!(
146             stderr,
147             "{usage_header_msg} The YAML configuration file should look like this:",
148             usage_header_msg = "[USAGE]".yellow().bold()
149         );
150         let _ = writeln!(
151             stderr,
152             "    - {path_attr} examples/photos/iss-trails.jpg
153       {alt_attr} \"A long exposure shot of star trails, framed by the ISS on the top and
154         by the surface of Earth on the bottom. Thunderstorms dot the landscape
155         while the orange glare of cities drifts across Earth and a faint a
156         green-yellow light hugs the horizon.\"
157       {license_attr} PD
158       {author_attr} Don Pettit
159 
160     - {path_attr} examples/photos/solar-eclipse.jpg
161       {alt_attr} \"A total solar eclipse. The moon blocks out the sun and creates a
162       stunning ring of colorful red light against the black background.\"
163       {license_attr} CC-BY-SA-3
164       {author_attr} Luc Viatour",
165             path_attr = "path:".green(),
166             alt_attr = "alt:".green(),
167             author_attr = "author:".green(),
168             license_attr = "license:".green()
169         );
170 
171         let _ = stderr.flush();
172     }
173 }