pub mod context;
pub mod raii;
pub mod resource;
pub mod scoped;
pub use context::{ContextManager, ThreadLocalContext};
pub use raii::{Guard, ScopedGuard};
pub use resource::{ResourceGuard, ResourcePool};
pub use scoped::{ScopedBuilder, ScopedCallback, with_context};
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn guard<T, F>(resource: T, cleanup: F) -> Guard<T, F>
where
F: FnOnce(T),
{
Guard::new(resource, cleanup)
}
pub fn with_scoped<S, W, C, T, R>(setup: S, work: W, cleanup: C) -> R
where
S: FnOnce() -> T,
W: FnOnce(&T) -> R,
C: FnOnce(T),
{
let resource = setup();
let _guard = guard(resource, cleanup);
work(_guard.resource())
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::{Arc, Mutex};
#[test]
fn test_basic_guard() {
let cleanup_called = Arc::new(Mutex::new(false));
let cleanup_called_clone = cleanup_called.clone();
{
let _guard = guard("test_resource", move |_| {
*cleanup_called_clone.lock().unwrap() = true;
});
assert!(!*cleanup_called.lock().unwrap());
}
assert!(*cleanup_called.lock().unwrap());
}
#[test]
fn test_with_scoped() {
let cleanup_called = Arc::new(Mutex::new(false));
let cleanup_called_clone = cleanup_called.clone();
let result = with_scoped(
|| "test_resource",
|resource| format!("processed: {}", resource),
move |_| {
*cleanup_called_clone.lock().unwrap() = true;
},
);
assert_eq!(result, "processed: test_resource");
assert!(*cleanup_called.lock().unwrap());
}
}