use std::future::Future;
use crate::CallerContext;
#[cfg(doc)] use crate::{wrap, AsyncWrapContext};
pub trait SyncWrapContext<T> {
fn new() -> Self
where
Self: Sized;
#[allow(unused_variables)]
fn before(&self, caller_context: &CallerContext) {}
#[allow(unused_variables)]
fn after(self, caller_context: &CallerContext, result: &T)
where
Self: Sized,
{
}
fn run_sync(caller_context: CallerContext, block: impl FnOnce() -> T) -> T
where
Self: Sized,
{
let context = Self::new();
context.before(&caller_context);
let result = block();
context.after(&caller_context, &result);
result
}
#[allow(async_fn_in_trait)]
async fn run_async(caller_context: CallerContext, block: impl Future<Output = T>) -> T
where
Self: Sized,
{
let context = Self::new();
context.before(&caller_context);
let result = block.await;
context.after(&caller_context, &result);
result
}
}
#[cfg(test)]
mod tests {
use crate::CallerContext;
use super::SyncWrapContext;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;
#[test]
fn wrapper_usage_on_sync_function() {
static VALUE: AtomicUsize = AtomicUsize::new(100);
struct Sync;
impl SyncWrapContext<usize> for Sync {
fn new() -> Self {
Self
}
fn before(&self, _: &CallerContext) {
VALUE.store(0, Ordering::Relaxed);
}
fn after(self, _: &CallerContext, result: &usize) {
VALUE.store(2 * (*result), Ordering::Relaxed);
}
}
assert_eq!(
Sync::run_sync(CallerContext::new("test"), || {
assert_eq!(VALUE.load(Ordering::Relaxed), 0);
42
},),
42,
);
assert_eq!(VALUE.load(Ordering::Relaxed), 84);
}
#[tokio::test]
async fn wrapper_usage_on_async_function() {
static VALUE: AtomicUsize = AtomicUsize::new(100);
struct Sync;
impl SyncWrapContext<usize> for Sync {
fn new() -> Self {
Self
}
fn before(&self, _: &CallerContext) {
VALUE.store(0, Ordering::Relaxed);
}
fn after(self, _: &CallerContext, result: &usize) {
VALUE.store(2 * *result, Ordering::Relaxed);
}
}
assert_eq!(
Sync::run_async(CallerContext::new("test"), async {
assert_eq!(VALUE.load(Ordering::Relaxed), 0);
42
},)
.await,
42
);
assert_eq!(VALUE.load(Ordering::Relaxed), 84);
}
}