use std::any::type_name;
use std::fmt::{self, Debug, Formatter};
use std::panic::{RefUnwindSafe, UnwindSafe};
use std::sync::Arc;
pub use ::pastey::paste;
use crate::{Family, Object};
#[inline]
pub fn new<T>(instance_factory: impl Fn(Link<T>) -> T + Send + Sync + 'static) -> T {
Link::new(Arc::new(instance_factory)).into_instance()
}
#[inline]
pub fn clone<T>(value: &T) -> T
where
T: Object + From<Family<T>>,
{
value.family().into()
}
pub(crate) type InstanceFactory<T> = Arc<dyn Fn(Link<T>) -> T + Send + Sync + 'static>;
pub struct Link<T> {
pub(crate) instance_factory: InstanceFactory<T>,
}
impl<T> UnwindSafe for Link<T> {}
impl<T> RefUnwindSafe for Link<T> {}
#[cfg_attr(coverage_nightly, coverage(off))] impl<T> Debug for Link<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct(type_name::<Self>())
.field(
"instance_factory",
&format_args!("Arc<dyn Fn(Link<{t}>) -> {t}>", t = type_name::<T>()),
)
.finish()
}
}
impl<T> Link<T> {
#[must_use]
pub(crate) fn new(instance_factory: InstanceFactory<T>) -> Self {
Self { instance_factory }
}
#[must_use]
pub(crate) fn into_instance(self) -> T {
let instance_factory = Arc::clone(&self.instance_factory);
(instance_factory)(self)
}
#[must_use]
fn clone(&self) -> Self {
Self {
instance_factory: Arc::clone(&self.instance_factory),
}
}
#[inline]
#[must_use]
pub fn family(&self) -> Family<T> {
Family::new(self.clone())
}
}