use crate::log as glib_log;
use crate::translate::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GlibLoggerFormat {
Plain,
LineAndFile,
#[cfg(any(feature = "v2_56", feature = "dox"))]
Structured,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GlibLoggerDomain {
None,
CrateTarget,
CratePath,
}
#[derive(Debug)]
pub struct GlibLogger {
format: GlibLoggerFormat,
domain: GlibLoggerDomain,
}
impl GlibLogger {
pub const fn new(format: GlibLoggerFormat, domain: GlibLoggerDomain) -> Self {
Self { format, domain }
}
fn level_to_glib(level: rs_log::Level) -> crate::ffi::GLogLevelFlags {
match level {
rs_log::Level::Error => crate::ffi::G_LOG_LEVEL_CRITICAL,
rs_log::Level::Warn => crate::ffi::G_LOG_LEVEL_WARNING,
rs_log::Level::Info => crate::ffi::G_LOG_LEVEL_INFO,
rs_log::Level::Debug => crate::ffi::G_LOG_LEVEL_DEBUG,
rs_log::Level::Trace => crate::ffi::G_LOG_LEVEL_DEBUG,
}
}
#[doc(alias = "g_log")]
fn write_log(domain: Option<&str>, level: rs_log::Level, message: &str) {
unsafe {
crate::ffi::g_log(
domain.to_glib_none().0,
GlibLogger::level_to_glib(level),
message.replace("%", "%%").to_glib_none().0,
);
}
}
#[cfg(any(feature = "v2_56", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v2_56")))]
#[doc(alias = "g_log_structured_standard")]
fn write_log_structured(
domain: Option<&str>,
level: rs_log::Level,
file: Option<&str>,
line: Option<u32>,
func: Option<&str>,
message: &str,
) {
let line_str = line.map(|l| l.to_string());
unsafe {
crate::ffi::g_log_structured_standard(
domain.to_glib_none().0,
GlibLogger::level_to_glib(level),
file.to_glib_none().0,
line_str.to_glib_none().0,
func.to_glib_none().0,
message.replace("%", "%%").to_glib_none().0,
);
}
}
}
impl rs_log::Log for GlibLogger {
fn enabled(&self, _: &rs_log::Metadata) -> bool {
true
}
fn log(&self, record: &rs_log::Record) {
if !self.enabled(record.metadata()) {
return;
}
let domain = match &self.domain {
GlibLoggerDomain::None => None,
GlibLoggerDomain::CrateTarget => Some(record.metadata().target()),
GlibLoggerDomain::CratePath => record.module_path(),
};
match self.format {
GlibLoggerFormat::Plain => {
let s = format!("{}", record.args());
GlibLogger::write_log(domain, record.level(), &s)
}
GlibLoggerFormat::LineAndFile => {
let s = match (record.file(), record.line()) {
(Some(file), Some(line)) => format!("{}:{}: {}", file, line, record.args()),
(Some(file), None) => format!("{}: {}", file, record.args()),
_ => format!("{}", record.args()),
};
GlibLogger::write_log(domain, record.level(), &s);
}
#[cfg(any(feature = "v2_56", feature = "dox"))]
GlibLoggerFormat::Structured => {
GlibLogger::write_log_structured(
domain,
record.level(),
record.file(),
record.line(),
None,
&format!("{}", record.args()),
);
}
};
}
fn flush(&self) {}
}
pub fn rust_log_handler(domain: Option<&str>, level: glib_log::LogLevel, message: &str) {
let level = match level {
glib_log::LogLevel::Error | glib_log::LogLevel::Critical => rs_log::Level::Error,
glib_log::LogLevel::Warning => rs_log::Level::Warn,
glib_log::LogLevel::Message | glib_log::LogLevel::Info => rs_log::Level::Info,
glib_log::LogLevel::Debug => rs_log::Level::Debug,
};
rs_log::log!(target: domain.unwrap_or("<null>"), level, "{}", message);
}
#[macro_export]
#[cfg(any(feature = "dox", feature = "log_macros"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "log_macros")))]
macro_rules! error {
(target: $target:expr, $($arg:tt)+) => (
$crate::rs_log::log!(target: $target, $crate::rs_log::Level::Error, $($arg)+);
);
($($arg:tt)+) => (
$crate::rs_log::log!(target: G_LOG_DOMAIN, $crate::rs_log::Level::Error, $($arg)+);
)
}
#[macro_export]
#[cfg(any(feature = "dox", feature = "log_macros"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "log_macros")))]
macro_rules! warn {
(target: $target:expr, $($arg:tt)+) => (
$crate::rs_log::log!(target: $target, $crate::rs_log::Level::Warn, $($arg)+);
);
($($arg:tt)+) => (
$crate::rs_log::log!(target: G_LOG_DOMAIN, $crate::rs_log::Level::Warn, $($arg)+);
)
}
#[macro_export]
#[cfg(any(feature = "dox", feature = "log_macros"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "log_macros")))]
macro_rules! info {
(target: $target:expr, $($arg:tt)+) => (
$crate::rs_log::log!(target: $target, $crate::rs_log::Level::Info, $($arg)+);
);
($($arg:tt)+) => (
$crate::rs_log::log!(target: G_LOG_DOMAIN, $crate::rs_log::Level::Info, $($arg)+);
)
}
#[macro_export]
#[cfg(any(feature = "dox", feature = "log_macros"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "log_macros")))]
macro_rules! debug {
(target: $target:expr, $($arg:tt)+) => (
$crate::rs_log::log!(target: $target, $crate::rs_log::Level::Debug, $($arg)+);
);
($($arg:tt)+) => (
$crate::rs_log::log!(target: G_LOG_DOMAIN, $crate::rs_log::Level::Debug, $($arg)+);
)
}
#[macro_export]
#[cfg(any(feature = "dox", feature = "log_macros"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "log_macros")))]
macro_rules! trace {
(target: $target:expr, $($arg:tt)+) => (
$crate::rs_log::log!(target: $target, $crate::rs_log::Level::Trace, $($arg)+);
);
($($arg:tt)+) => (
$crate::rs_log::log!(target: G_LOG_DOMAIN, $crate::rs_log::Level::Trace, $($arg)+);
)
}