#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(
feature = "for-nightly-try-support",
feature(try_trait_v2),
feature(try_trait_v2_residual)
)]
#![cfg_attr(feature = "for-nightly-likely-optimization", feature(likely_unlikely))]
#![cfg_attr(feature = "for-nightly-allocator-api-support", feature(allocator_api))]
#![cfg_attr(
feature = "for-nightly-error-generic-member-access",
feature(error_generic_member_access)
)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![doc = include_str!("../doc/modules/lib.md")]
extern crate alloc;
extern crate core;
#[macro_use]
mod utils;
pub mod events;
mod iart_impl;
#[cfg(test)]
mod tests;
mod types;
pub use types::*;
#[cfg(all(feature = "core_error-support", feature = "std"))]
compile_error!(
"Feature 'core_error-support' cannot be used with 'std'. \
Please disable 'core_error-support' when building for std targets."
);
#[cfg(all(feature = "std", feature = "enable-default-handler"))]
use crate::events::IartEvent;
use crate::utils::{const_str_to_usize, str_eq};
use core::sync::atomic::{AtomicPtr, Ordering};
#[allow(unused)]
pub const BACK_TRACE_MAX: usize = {
if let Some(val) = option_env!("IART_TRACE_MAX") {
const_str_to_usize(val)
} else {
32
}
};
#[allow(unused)]
#[doc = include_str!("../doc/variable/TRACE_REMOVE_TYPE.md")]
pub const TRACE_REMOVE_TYPE: &str = {
if let Some(s) = option_env!("IART_TRACE_TYPE") {
if str_eq(s, "good") || str_eq(s, "first") || str_eq(s, "last") {
s
} else {
panic!("Invalid IART_TRACE_TYPE!");
}
} else {
"good"
}
};
#[allow(unused)]
#[doc = include_str!("../doc/variable/TRACE_UNIQUE.md")]
pub const TRACE_UNIQUE: bool = !cfg!(feature = "no-trace-dedup");
#[doc = include_str!("../doc/variable/HANDLER.md")]
static HANDLER: AtomicPtr<()> = AtomicPtr::new(
#[cfg(all(
feature = "std",
feature = "enable-default-handler",
feature = "for-nightly-allocator-api-support"
))]
{
default_handler::<std::alloc::Global> as *mut ()
},
#[cfg(all(
feature = "std",
feature = "enable-default-handler",
not(feature = "for-nightly-allocator-api-support")
))]
{
default_handler as *mut ()
},
#[cfg(not(all(feature = "std", feature = "enable-default-handler")))]
core::ptr::null_mut(),
);
#[inline]
#[doc = include_str!("../doc/fn/set_handler.md")]
pub fn set_handler(f: IartLogger) {
HANDLER.store(f as *mut (), Ordering::SeqCst);
}
#[inline]
#[doc = include_str!("../doc/fn/is_initialized_handler.md")]
pub fn is_initialized_handler() -> bool {
!HANDLER.load(Ordering::Acquire).is_null()
}
#[doc = include_str!("../doc/fn/default_handler.md")]
#[cfg(all(
feature = "std",
feature = "enable-default-handler",
not(feature = "for-nightly-allocator-api-support")
))]
pub fn default_handler(event: IartEvent, iart: IartHandleDetails) -> std::fmt::Result {
match event {
IartEvent::DroppedWithoutCheck => {
eprintln!("IART dropped without check! {:?}", iart);
}
_ => {}
}
Ok(())
}
#[doc = include_str!("../doc/fn/default_handler.md")]
#[cfg(all(
feature = "std",
feature = "enable-default-handler",
feature = "for-nightly-allocator-api-support"
))]
pub fn default_handler<A: alloc::alloc::Allocator + Clone + core::fmt::Debug>(
event: IartEvent,
iart: IartHandleDetails<A>,
) -> std::fmt::Result {
match event {
IartEvent::DroppedWithoutCheck => {
eprintln!("IART dropped without check! {:?}", iart);
}
_ => {}
}
Ok(())
}