#[cfg(feature = "enable")]
mod imp;
use std::{fmt, marker::PhantomData};
#[derive(Debug, Clone, PartialEq, Eq, Default)]
#[non_exhaustive]
pub struct Counts {
pub total: usize,
pub max_live: usize,
pub live: usize,
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Count<T: 'static> {
ghost: PhantomData<fn(T)>,
}
impl<T: 'static> Default for Count<T> {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl<T: 'static> Clone for Count<T> {
#[inline]
fn clone(&self) -> Self {
Self::new()
}
}
impl<T: 'static> Count<T> {
#[inline]
pub fn new() -> Count<T> {
#[cfg(feature = "enable")]
imp::inc::<T>();
Count { ghost: PhantomData }
}
}
impl<T: 'static> Drop for Count<T> {
#[inline]
fn drop(&mut self) {
#[cfg(feature = "enable")]
imp::dec::<T>();
}
}
pub fn enable(_yes: bool) {
#[cfg(feature = "enable")]
imp::enable(_yes);
}
#[inline]
pub fn get<T: 'static>() -> Counts {
#[cfg(feature = "enable")]
{
return imp::get::<T>();
}
#[cfg(not(feature = "enable"))]
{
return Counts::default();
}
}
pub fn get_all() -> AllCounts {
#[cfg(feature = "enable")]
{
return imp::get_all();
}
#[cfg(not(feature = "enable"))]
{
return AllCounts::default();
}
}
#[derive(Default, Clone, Debug)]
pub struct AllCounts {
entries: Vec<(&'static str, Counts)>,
}
impl fmt::Display for AllCounts {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fn sep(mut n: usize) -> String {
let mut groups = Vec::new();
while n >= 1000 {
groups.push(format!("{:03}", n % 1000));
n /= 1000;
}
groups.push(n.to_string());
groups.reverse();
groups.join("_")
}
if self.entries.is_empty() {
return if cfg!(feature = "enable") {
writeln!(f, "all counts are zero")
} else {
writeln!(f, "counts are disabled")
};
}
let max_width =
self.entries.iter().map(|(name, _count)| name.chars().count()).max().unwrap_or(0);
for (name, counts) in &self.entries {
writeln!(
f,
"{:<max_width$} {:>12} {:>12} {:>12}",
name,
sep(counts.total),
sep(counts.max_live),
sep(counts.live),
max_width = max_width
)?;
}
writeln!(
f,
"{:<max_width$} {:>12} {:>12} {:>12}",
"",
"total",
"max_live",
"live",
max_width = max_width
)?;
Ok(())
}
}