macro_rules! impl_rc_conversions {
(
@method_into
$method_name:ident, // Method name: into_box, into_once
$rc_type:ident < $($generics:ident),* >, // Rc type with generics
$target_type:ident, // Target type: BoxType or OnceType
$call_mode:ident, // direct or borrow_mut
($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)? ) => {
#[inline]
fn $method_name(self) -> $target_type<$($generics),*>
where
Self: 'static,
{
$target_type::new_with_optional_name(
impl_rc_conversions!(@make_closure $call_mode, self.function, $($arg),*),
self.name
)
}
};
(
@method_to
$method_name:ident, $rc_type:ident < $($generics:ident),* >, $target_type:ident, $call_mode:ident, ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)? ) => {
#[inline]
fn $method_name(&self) -> $target_type<$($generics),*>
where
Self: 'static,
{
let self_fn = self.function.clone();
let self_name = self.name.clone();
$target_type::new_with_optional_name(
impl_rc_conversions!(@make_closure $call_mode, self_fn, $($arg),*),
self_name
)
}
};
(
@fn_method_into
direct,
($($arg:ident : $arg_ty:ty),*)
) => {
#[inline]
fn into_fn(self) -> impl Fn($($arg_ty),*)
{
move |$($arg),*| (self.function)($($arg),*)
}
};
(
@fn_method_into
direct,
($($arg:ident : $arg_ty:ty),*) -> $ret:ty
) => {
#[inline]
fn into_fn(self) -> impl Fn($($arg_ty),*) -> $ret
{
move |$($arg),*| (self.function)($($arg),*)
}
};
(
@fn_method_into
borrow_mut,
($($arg:ident : $arg_ty:ty),*)
) => {
#[inline]
fn into_fn(self) -> impl FnMut($($arg_ty),*)
{
move |$($arg),*| (self.function.borrow_mut())($($arg),*)
}
};
(
@fn_method_into
borrow_mut,
($($arg:ident : $arg_ty:ty),*) -> $ret:ty
) => {
#[inline]
fn into_fn(self) -> impl FnMut($($arg_ty),*) -> $ret
{
move |$($arg),*| (self.function.borrow_mut())($($arg),*)
}
};
(
@fn_method_to
direct,
($($arg:ident : $arg_ty:ty),*)
) => {
#[inline]
fn to_fn(&self) -> impl Fn($($arg_ty),*)
{
let self_fn = self.function.clone();
move |$($arg),*| (self_fn)($($arg),*)
}
};
(
@fn_method_to
direct,
($($arg:ident : $arg_ty:ty),*) -> $ret:ty
) => {
#[inline]
fn to_fn(&self) -> impl Fn($($arg_ty),*) -> $ret
{
let self_fn = self.function.clone();
move |$($arg),*| (self_fn)($($arg),*)
}
};
(
@fn_method_to
borrow_mut,
($($arg:ident : $arg_ty:ty),*)
) => {
#[inline]
fn to_fn(&self) -> impl FnMut($($arg_ty),*)
{
let self_fn = self.function.clone();
move |$($arg),*| (self_fn.borrow_mut())($($arg),*)
}
};
(
@fn_method_to
borrow_mut,
($($arg:ident : $arg_ty:ty),*) -> $ret:ty
) => {
#[inline]
fn to_fn(&self) -> impl FnMut($($arg_ty),*) -> $ret
{
let self_fn = self.function.clone();
move |$($arg),*| (self_fn.borrow_mut())($($arg),*)
}
};
(@make_closure direct, $fn_call:expr, $($arg:ident),*) => {
move |$($arg),*| ($fn_call)($($arg),*)
};
(@make_closure borrow_mut, $fn_call:expr, $($arg:ident),*) => {
move |$($arg),*| ($fn_call.borrow_mut())($($arg),*)
};
(
@impl_common
$rc_type:ident < $($generics:ident),* >,
$box_type:ident,
$call_mode:ident,
($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
) => {
impl_rc_conversions!(
@method_into into_box,
$rc_type<$($generics),*>, $box_type,
$call_mode,
($($arg : $arg_ty),*) $(-> $ret)?
);
#[inline]
fn into_rc(self) -> $rc_type<$($generics),*>
{
self
}
impl_rc_conversions!(
@fn_method_into
$call_mode,
($($arg : $arg_ty),*) $(-> $ret)?
);
impl_rc_conversions!(
@method_to to_box,
$rc_type<$($generics),*>, $box_type,
$call_mode,
($($arg : $arg_ty),*) $(-> $ret)?
);
#[inline]
fn to_rc(&self) -> $rc_type<$($generics),*>
{
self.clone()
}
impl_rc_conversions!(
@fn_method_to
$call_mode,
($($arg : $arg_ty),*) $(-> $ret)?
);
};
(
@impl
$rc_type:ident < $($generics:ident),* >,
$box_type:ident,
$once_type:ident,
$call_mode:ident,
($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
) => {
impl_rc_conversions!(
@impl_common
$rc_type<$($generics),*>,
$box_type,
$call_mode,
($($arg : $arg_ty),*) $(-> $ret)?
);
impl_rc_conversions!(
@method_into into_once,
$rc_type<$($generics),*>,
$once_type,
$call_mode,
($($arg : $arg_ty),*) $(-> $ret)?
);
impl_rc_conversions!(
@method_to to_once,
$rc_type<$($generics),*>,
$once_type,
$call_mode,
($($arg : $arg_ty),*) $(-> $ret)?
);
};
(
@impl_no_once
$rc_type:ident < $($generics:ident),* >,
$box_type:ident,
$call_mode:ident,
($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
) => {
impl_rc_conversions!(
@impl_common
$rc_type<$($generics),*>,
$box_type,
$call_mode,
($($arg : $arg_ty),*) $(-> $ret)?
);
};
(
$rc_type:ident < $($generics:ident),* >,
$box_type:ident,
Fn($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
) => {
impl_rc_conversions!(
@impl_no_once
$rc_type<$($generics),*>,
$box_type,
direct,
($($arg : $arg_ty),*) $(-> $ret)?
);
};
(
$rc_type:ident < $($generics:ident),* >,
$box_type:ident,
FnMut($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
) => {
impl_rc_conversions!(
@impl_no_once
$rc_type<$($generics),*>,
$box_type,
borrow_mut,
($($arg : $arg_ty),*) $(-> $ret)?
);
};
(
$rc_type:ident < $($generics:ident),* >,
$box_type:ident,
$once_type:ident,
Fn($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
) => {
impl_rc_conversions!(
@impl
$rc_type<$($generics),*>,
$box_type,
$once_type,
direct,
($($arg : $arg_ty),*) $(-> $ret)?
);
};
(
$rc_type:ident < $($generics:ident),* >,
$box_type:ident,
$once_type:ident,
FnMut($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
) => {
impl_rc_conversions!(
@impl
$rc_type<$($generics),*>,
$box_type,
$once_type,
borrow_mut,
($($arg : $arg_ty),*) $(-> $ret)?
);
};
}
pub(crate) use impl_rc_conversions;