use std::sync::atomic::{AtomicU8, Ordering::Relaxed};
#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Hash)]
#[repr(u8)]
pub enum Detail {
#[default]
Off = 0,
Stages = 1,
Diagnostic = 2,
}
impl Detail {
pub const fn as_str(self) -> &'static str {
match self {
Self::Off => "off",
Self::Stages => "stages",
Self::Diagnostic => "diagnostic",
}
}
#[inline]
pub const fn records_stages(self) -> bool {
(self as u8) >= (Self::Stages as u8)
}
#[inline]
pub const fn is_diagnostic(self) -> bool {
(self as u8) >= (Self::Diagnostic as u8)
}
}
static DETAIL: AtomicU8 = AtomicU8::new(Detail::Off as u8);
#[inline]
pub fn detail() -> Detail {
match DETAIL.load(Relaxed) {
1 => Detail::Stages,
2 => Detail::Diagnostic,
_ => Detail::Off,
}
}
pub fn set_detail(detail: Detail) {
DETAIL.store(detail as u8, Relaxed);
crate::runtime::set_enabled(detail.records_stages());
}
#[cfg(test)]
mod tests {
use super::{detail, set_detail, Detail};
#[test]
fn level_predicates_are_ordered() {
assert!(!Detail::Off.records_stages());
assert!(!Detail::Off.is_diagnostic());
assert!(Detail::Stages.records_stages());
assert!(!Detail::Stages.is_diagnostic());
assert!(Detail::Diagnostic.records_stages());
assert!(Detail::Diagnostic.is_diagnostic());
assert!(Detail::Off < Detail::Stages);
assert!(Detail::Stages < Detail::Diagnostic);
}
#[test]
fn setting_detail_arms_the_runtime() {
set_detail(Detail::Diagnostic);
assert_eq!(detail(), Detail::Diagnostic);
assert!(crate::enabled());
set_detail(Detail::Stages);
assert_eq!(detail(), Detail::Stages);
assert!(crate::enabled());
set_detail(Detail::Off);
assert_eq!(detail(), Detail::Off);
assert!(!crate::enabled());
}
}