use std::backtrace::Backtrace;
use std::borrow::Cow;
use std::fmt::Write;
use std::sync::Arc;
#[cfg(feature = "backtraces")]
pub type Dep = MutexDep<Arc<Backtrace>>;
#[cfg(not(feature = "backtraces"))]
pub type Dep = MutexDep<()>;
const BASE_MESSAGE: &str = "Found cycle in mutex dependency graph:";
pub trait Reportable: Clone {
fn capture() -> Self;
fn panic_message(trace: &[Self]) -> Cow<'static, str>;
}
#[derive(Clone)]
pub struct MutexDep<T>(T);
impl Reportable for MutexDep<()> {
fn capture() -> Self {
Self(())
}
fn panic_message(_trace: &[Self]) -> Cow<'static, str> {
Cow::Borrowed(BASE_MESSAGE)
}
}
impl Reportable for MutexDep<Arc<Backtrace>> {
fn capture() -> Self {
Self(Arc::new(Backtrace::capture()))
}
fn panic_message(trace: &[Self]) -> Cow<'static, str> {
let mut message = format!("{BASE_MESSAGE}\n");
for entry in trace {
let _ = writeln!(message, "{}", entry.0);
}
message.into()
}
}