mod assert_send;
mod caller;
mod consts;
mod fixed_vec;
mod gen;
pub(crate) use self::assert_send::AssertSend;
pub(crate) use self::caller::Caller;
pub(crate) use self::consts::Consts;
pub(crate) use self::fixed_vec::FixedVec;
pub(crate) use self::gen::Gen;
#[cfg(all(debug_assertions, feature = "std"))]
mod r#impl {
use core::fmt::{self, Write};
use core::sync::atomic::{AtomicU8, Ordering};
use std::env;
use std::thread::panicking;
pub(crate) use std::backtrace::Backtrace;
pub(crate) enum RuneAssert {
Panic,
Trace,
Error,
}
impl RuneAssert {
#[allow(unused)]
pub(crate) fn is_panic(&self) -> bool {
matches!(self, Self::Panic)
}
#[allow(unused)]
pub(crate) fn is_trace(&self) -> bool {
matches!(self, Self::Trace)
}
}
const VAR: &str = "RUNE_ASSERT";
static ENABLED: AtomicU8 = AtomicU8::new(0);
pub(crate) fn rune_assert() -> RuneAssert {
let mut value = ENABLED.load(Ordering::Relaxed);
if value == 0 {
value = match env::var(VAR).as_deref() {
Ok("panic") => 1,
Ok("trace") => 2,
_ => 3,
};
ENABLED.store(value, Ordering::Relaxed);
}
match value {
1 if !panicking() => RuneAssert::Panic,
2 if !panicking() => RuneAssert::Trace,
_ => RuneAssert::Error,
}
}
pub(crate) struct CaptureAt {
at: &'static str,
done: usize,
string: rust_alloc::string::String,
}
impl CaptureAt {
pub(crate) fn new(at: &'static str) -> Self {
Self {
at,
done: 0,
string: rust_alloc::string::String::default(),
}
}
pub(crate) fn as_str(&self) -> Option<&str> {
if self.done > 0 {
Some(&self.string[self.done..])
} else {
None
}
}
}
impl Write for CaptureAt {
#[inline]
fn write_str(&mut self, mut s: &str) -> fmt::Result {
if self.done > 0 {
return Ok(());
}
while let Some(n) = s.find('\n') {
self.string.push_str(&s[..n]);
if let Some(n) = self.string.find("at ") {
let at = &self.string[n + 3..];
if at.contains(self.at) {
self.done = n + 3;
return Ok(());
}
}
self.string.clear();
s = &s[n + 1..];
}
self.string.push_str(s);
Ok(())
}
}
macro_rules! _rune_diagnose {
($($tt:tt)*) => {
if $crate::shared::rune_assert().is_panic() {
panic!($($tt)*);
} else {
tracing::trace!($($tt)*);
}
};
}
macro_rules! _rune_trace {
($at:expr, $tok:expr) => {{
if $crate::shared::rune_assert().is_trace() {
use std::backtrace::Backtrace;
use std::fmt::Write as _;
let bt = Backtrace::force_capture();
let mut at = $crate::shared::CaptureAt::new($at);
write!(at, "{bt}").with_span($tok.span)?;
if let Some(_line) = at.as_str() {
tracing::trace!("{_line}: {:?}", $tok);
}
}
}};
}
#[doc(inline)]
pub(crate) use _rune_diagnose as rune_diagnose;
#[doc(inline)]
pub(crate) use _rune_trace as rune_trace;
}
#[cfg(not(all(debug_assertions, feature = "std")))]
mod r#impl {
use core::fmt;
macro_rules! _rune_diagnose {
($($tt:tt)*) => {
tracing::trace!($($tt)*);
};
}
macro_rules! _rune_trace {
($at:expr, $tok:expr) => {{
_ = $at;
_ = $tok;
}};
}
pub(crate) struct Backtrace;
impl Backtrace {
#[inline(always)]
pub(crate) fn capture() -> Self {
Self
}
}
impl fmt::Display for Backtrace {
#[inline(always)]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"backtrace not available, missing cfg(all(debug_assertions, feature = \"std\"))"
)
}
}
#[doc(inline)]
pub(crate) use _rune_diagnose as rune_diagnose;
#[doc(inline)]
pub(crate) use _rune_trace as rune_trace;
}
pub(crate) use self::r#impl::*;