#![deny(rust_2018_compatibility)]
#![deny(rust_2018_idioms)]
#![deny(warnings)]
#![no_std]
pub use stlog_macros::global_logger;
use void::Void;
#[cfg(feature = "spanned")]
pub mod spanned;
pub struct NullLogger;
impl GlobalLog for NullLogger {
fn log(&self, _: u8) {}
}
impl Log for NullLogger {
type Error = Void;
fn log(&mut self, _: u8) -> Result<(), Void> {
Ok(())
}
}
pub trait GlobalLog: Sync {
fn log(&self, address: u8);
}
pub trait Log {
type Error;
fn log(&mut self, address: u8) -> Result<(), Self::Error>;
}
#[macro_export]
macro_rules! error {
($logger:expr, $string:expr) => {{
if $crate::max_level() as u8 >= $crate::Level::Error as u8 {
#[export_name = $string]
#[link_section = ".stlog.error"]
static SYMBOL: u8 = 0;
$crate::Log::log(&mut $logger, &SYMBOL as *const u8 as usize as u8)
} else {
Ok(())
}
}};
($string:expr) => {
unsafe {
if $crate::max_level() as u8 >= $crate::Level::Error as u8 {
extern "Rust" {
#[link_name = "stlog::GLOBAL_LOGGER"]
static LOGGER: &'static $crate::GlobalLog;
}
#[export_name = $string]
#[link_section = ".stlog.error"]
static SYMBOL: u8 = 0;
$crate::GlobalLog::log(LOGGER, &SYMBOL as *const u8 as usize as u8)
}
}
};
}
#[macro_export]
macro_rules! warn {
($logger:expr, $string:expr) => {{
if $crate::max_level() as u8 >= $crate::Level::Warn as u8 {
#[export_name = $string]
#[link_section = ".stlog.warn"]
static SYMBOL: u8 = 0;
$crate::Log::log(&mut $logger, &SYMBOL as *const u8 as usize as u8)
} else {
Ok(())
}
}};
($string:expr) => {
unsafe {
if $crate::max_level() as u8 >= $crate::Level::Warn as u8 {
extern "Rust" {
#[link_name = "stlog::GLOBAL_LOGGER"]
static LOGGER: &'static $crate::GlobalLog;
}
#[export_name = $string]
#[link_section = ".stlog.warn"]
static SYMBOL: u8 = 0;
$crate::GlobalLog::log(LOGGER, &SYMBOL as *const u8 as usize as u8)
}
}
};
}
#[macro_export]
macro_rules! info {
($logger:expr, $string:expr) => {{
if $crate::max_level() as u8 >= $crate::Level::Info as u8 {
#[export_name = $string]
#[link_section = ".stlog.info"]
static SYMBOL: u8 = 0;
$crate::Log::log(&mut $logger, &SYMBOL as *const u8 as usize as u8)
} else {
Ok(())
}
}};
($string:expr) => {
unsafe {
if $crate::max_level() as u8 >= $crate::Level::Info as u8 {
extern "Rust" {
#[link_name = "stlog::GLOBAL_LOGGER"]
static LOGGER: &'static $crate::GlobalLog;
}
#[export_name = $string]
#[link_section = ".stlog.info"]
static SYMBOL: u8 = 0;
$crate::GlobalLog::log(LOGGER, &SYMBOL as *const u8 as usize as u8)
}
}
};
}
#[macro_export]
macro_rules! debug {
($log:expr, $string:expr) => {{
if $crate::max_level() as u8 >= $crate::Level::Debug as u8 {
#[export_name = $string]
#[link_section = ".stlog.debug"]
static SYMBOL: u8 = 0;
$crate::Log::log(&mut $log, &SYMBOL as *const u8 as usize as u8)
} else {
Ok(())
}
}};
($string:expr) => {
unsafe {
if $crate::max_level() as u8 >= $crate::Level::Debug as u8 {
extern "Rust" {
#[link_name = "stlog::GLOBAL_LOGGER"]
static LOGGER: &'static $crate::GlobalLog;
}
#[export_name = $string]
#[link_section = ".stlog.debug"]
static SYMBOL: u8 = 0;
$crate::GlobalLog::log(LOGGER, &SYMBOL as *const u8 as usize as u8)
}
}
};
}
#[macro_export]
macro_rules! trace {
($logger:expr, $string:expr) => {{
if $crate::max_level() as u8 >= $crate::Level::Trace as u8 {
#[export_name = $string]
#[link_section = ".stlog.trace"]
static SYMBOL: u8 = 0;
$crate::Log::log(&mut $logger, &SYMBOL as *const u8 as usize as u8)
} else {
Ok(())
}
}};
($string:expr) => {
unsafe {
if $crate::max_level() as u8 >= $crate::Level::Trace as u8 {
extern "Rust" {
#[link_name = "stlog::GLOBAL_LOGGER"]
static LOGGER: &'static $crate::GlobalLog;
}
#[export_name = $string]
#[link_section = ".stlog.trace"]
static SYMBOL: u8 = 0;
$crate::GlobalLog::log(LOGGER, &SYMBOL as *const u8 as usize as u8)
}
}
};
}
#[doc(hidden)]
pub enum Level {
Off = 0,
Error = 1,
Warn = 2,
Info = 3,
Debug = 4,
Trace = 5,
}
#[doc(hidden)]
#[inline(always)]
pub fn max_level() -> Level {
match () {
#[cfg(debug_assertions)]
() => {
#[cfg(feature = "max-level-off")]
return Level::Off;
#[cfg(feature = "max-level-error")]
return Level::Error;
#[cfg(feature = "max-level-warn")]
return Level::Warn;
#[cfg(feature = "max-level-info")]
return Level::Info;
#[cfg(feature = "max-level-debug")]
return Level::Debug;
#[cfg(feature = "max-level-trace")]
return Level::Trace;
#[allow(unreachable_code)]
Level::Debug
}
#[cfg(not(debug_assertions))]
() => {
#[cfg(feature = "release-max-level-off")]
return Level::Off;
#[cfg(feature = "release-max-level-error")]
return Level::Error;
#[cfg(feature = "release-max-level-warn")]
return Level::Warn;
#[cfg(feature = "release-max-level-info")]
return Level::Info;
#[cfg(feature = "release-max-level-debug")]
return Level::Debug;
#[cfg(feature = "release-max-level-trace")]
return Level::Trace;
#[allow(unreachable_code)]
Level::Info
}
}
}