use std::sync::atomic::{AtomicU8, Ordering};
pub const QUIET: u8 = 0;
pub const NORMAL: u8 = 1;
pub const VERBOSE: u8 = 2;
static LEVEL: AtomicU8 = AtomicU8::new(NORMAL);
pub fn init(verbose: bool, quiet: bool) {
let level = if verbose {
VERBOSE
} else if quiet {
QUIET
} else {
NORMAL
};
LEVEL.store(level, Ordering::Relaxed);
#[cfg(feature = "_semantic")]
init_log_backend(level);
}
pub fn level() -> u8 {
LEVEL.load(Ordering::Relaxed)
}
pub fn is_quiet() -> bool {
level() == QUIET
}
pub fn is_verbose() -> bool {
level() >= VERBOSE
}
#[macro_export]
macro_rules! status {
($($arg:tt)*) => {
if $crate::logging::level() >= $crate::logging::NORMAL {
eprintln!("gqls: {}", format_args!($($arg)*));
}
};
}
#[macro_export]
macro_rules! detail {
($($arg:tt)*) => {
if $crate::logging::is_verbose() {
eprintln!("gqls: {}", format_args!($($arg)*));
}
};
}
#[cfg(feature = "_semantic")]
fn init_log_backend(level: u8) {
use log::LevelFilter;
static LOGGER: StderrLogger = StderrLogger;
let filter = match level {
QUIET => LevelFilter::Off,
VERBOSE => LevelFilter::Debug,
_ => LevelFilter::Warn,
};
let _ = log::set_logger(&LOGGER);
log::set_max_level(filter);
}
#[cfg(feature = "_semantic")]
struct StderrLogger;
#[cfg(feature = "_semantic")]
impl log::Log for StderrLogger {
fn enabled(&self, meta: &log::Metadata) -> bool {
let t = meta.target();
t == "gqls" || t.starts_with("gqls::")
}
fn log(&self, record: &log::Record) {
if self.enabled(record.metadata()) {
eprintln!(
"gqls: [{}] {}",
record.level().as_str().to_ascii_lowercase(),
record.args()
);
}
}
fn flush(&self) {}
}