use core::cell::RefCell;
use crate::IpcBuffer;
pub trait InvocationContext {
    fn with_context<T>(&mut self, f: impl FnOnce(&mut IpcBuffer) -> T) -> T;
}
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct NoInvocationContext;
impl NoInvocationContext {
    pub const fn new() -> Self {
        Self
    }
}
impl InvocationContext for &mut IpcBuffer {
    fn with_context<T>(&mut self, f: impl FnOnce(&mut IpcBuffer) -> T) -> T {
        f(self)
    }
}
impl<U: InvocationContext> InvocationContext for &mut U {
    fn with_context<T>(&mut self, f: impl FnOnce(&mut IpcBuffer) -> T) -> T {
        U::with_context(self, f)
    }
}
impl<U: InvocationContext> InvocationContext for &RefCell<U> {
    fn with_context<T>(&mut self, f: impl FnOnce(&mut IpcBuffer) -> T) -> T {
        U::with_context(&mut self.borrow_mut(), f)
    }
}
cfg_if::cfg_if! {
    if #[cfg(feature = "state")] {
        type NoExplicitInvocationContextInternal = crate::ImplicitInvocationContext;
    } else {
        type NoExplicitInvocationContextInternal = NoInvocationContext;
    }
}
pub type NoExplicitInvocationContext = NoExplicitInvocationContextInternal;