1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
use std::{ops::Deref, sync::Arc};

pub type Callback<T, Ret = ()> = Cb<dyn Fn(T) -> Ret + Sync + Send>;

#[derive(Default)]
#[repr(transparent)]
pub struct CbDebuggable<T: ?Sized>(pub T);
impl<T: ?Sized> std::fmt::Debug for CbDebuggable<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_tuple("Cb").finish()
    }
}
impl<T: ?Sized> Deref for CbDebuggable<T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

/// A helper type for callbacks that wraps around a function type with an `Arc` that implements `Debug`.
///
/// This is used to allow for shared ownership of a function, and to make it easy to embed
/// a callback in a struct that implements `Debug`.
pub type Cb<T> = Arc<CbDebuggable<T>>;

/// Helper for constructing a [Cb].
///
/// This is just wrapping an `Arc`, and it only exists because `Arc<dyn Fn..>` doesn't implement Debug, so
/// we're wrapping it with a `Cb` to avoid having to handle that in all structs that implement Debug
pub fn cb<T>(f: T) -> Cb<T> {
    Arc::new(CbDebuggable(f))
}

pub type CallbackFn<T, U = ()> = Cb<dyn Fn(T) -> U + Sync + Send + 'static>;
pub type CallbackBox<T, U = ()> = Box<dyn Fn(T) -> U + Sync + Send + 'static>;

pub type CellFn<T, U = ()> = dyn Fn(&mut T) -> U + Send + Sync;
pub type CellFnOnce<T, U = ()> = dyn Fn(&mut T) -> U + Send + Sync;