Skip to main content

yog_logging/
lib.rs

1//! Yog logging — lightweight logging macros with a consistent `[yog]` format.
2//!
3//! The macros forward to [`log`], which does the formatting. Because they expand
4//! to a single call that only formats its arguments when actually invoked, there
5//! is no cost at a call site that is compiled out or behind a disabled level.
6//!
7//! ```
8//! yog_logging::info!("loaded {} mods", 3);
9//! yog_logging::warn!("slow tick: {}ms", 51);
10//! yog_logging::error!("failed: {}", "boom");
11//! ```
12
13use std::io::Write;
14
15/// Severity of a log record.
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17pub enum Level {
18    Info,
19    Warn,
20    Error,
21}
22
23impl Level {
24    #[inline]
25    const fn tag(self) -> &'static str {
26        match self {
27            Level::Info => "INFO",
28            Level::Warn => "WARN",
29            Level::Error => "ERROR",
30        }
31    }
32}
33
34/// Write one formatted record. INFO/WARN go to stdout, ERROR to stderr so it
35/// interleaves with the host (Minecraft) console the way operators expect.
36#[doc(hidden)]
37#[inline]
38pub fn log(level: Level, args: std::fmt::Arguments<'_>) {
39    if matches!(level, Level::Error) {
40        let mut out = std::io::stderr().lock();
41        let _ = writeln!(out, "[yog] [{}] {}", level.tag(), args);
42    } else {
43        let mut out = std::io::stdout().lock();
44        let _ = writeln!(out, "[yog] [{}] {}", level.tag(), args);
45    }
46}
47
48/// Log at INFO level.
49#[macro_export]
50macro_rules! info {
51    ($($arg:tt)*) => {
52        $crate::log($crate::Level::Info, ::core::format_args!($($arg)*))
53    };
54}
55
56/// Log at WARN level.
57#[macro_export]
58macro_rules! warn {
59    ($($arg:tt)*) => {
60        $crate::log($crate::Level::Warn, ::core::format_args!($($arg)*))
61    };
62}
63
64/// Log at ERROR level.
65#[macro_export]
66macro_rules! error {
67    ($($arg:tt)*) => {
68        $crate::log($crate::Level::Error, ::core::format_args!($($arg)*))
69    };
70}