#[cfg(feature = "tracing")]
use tracing::debug;
#[derive(Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "debug", derive(Debug))]
pub enum Scope {
Root,
Module,
Scoped,
Transient,
}
impl std::fmt::Display for Scope {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Scope::Root => write!(f, "Root"),
Scope::Module => write!(f, "Module"),
Scope::Scoped => write!(f, "Scoped"),
Scope::Transient => write!(f, "Transient"),
}
}
}
impl Scope {
pub fn is_singleton(self) -> bool {
let result = matches!(self, Scope::Root | Scope::Module | Scope::Scoped);
#[cfg(feature = "tracing")]
debug!(
"Checking scope lifecycle: scope={}, is_singleton={}",
self, result
);
result
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_root_is_singleton() {
let scope = Scope::Root;
assert!(scope.is_singleton(), "Scope::Root should be singleton");
}
#[test]
fn test_module_is_singleton() {
let scope = Scope::Module;
assert!(scope.is_singleton(), "Scope::Module should be singleton");
}
#[test]
fn test_transient_is_not_singleton() {
let scope = Scope::Transient;
assert!(
!scope.is_singleton(),
"Scope::Transient should not be singleton"
);
}
#[test]
fn test_scoped_is_singleton() {
let scope = Scope::Scoped;
assert!(scope.is_singleton(), "Scope::Scoped should be singleton");
}
#[test]
fn test_scope_is_copy() {
let scope1 = Scope::Root;
let scope2 = scope1;
assert!(scope1.is_singleton());
assert!(scope2.is_singleton());
}
#[test]
fn test_scope_is_clone() {
let scope1 = Scope::Module;
let scope2 = scope1;
assert!(scope1.is_singleton());
assert!(scope2.is_singleton());
}
#[test]
fn test_all_scopes_are_covered() {
let scopes = [Scope::Root, Scope::Module, Scope::Scoped, Scope::Transient];
let singleton_count = scopes.iter().filter(|s| s.is_singleton()).count();
assert_eq!(
singleton_count, 3,
"There should be exactly 3 singleton scopes"
);
}
}