Skip to content

Commit

Permalink
Improve macro documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
MrGVSV committed Jun 29, 2024
1 parent 184af80 commit 1f49747
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 24 deletions.
21 changes: 14 additions & 7 deletions crates/bevy_reflect/src/func/args/from_arg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,16 @@ pub trait FromArg {
fn from_arg<'a>(arg: Arg<'a>, info: &ArgInfo) -> Result<Self::Item<'a>, ArgError>;
}

/// Implements the [`FromArg`] trait for the given type.
///
/// This will implement it for `$ty`, `&$ty`, and `&mut $ty`.
///
/// See [`impl_function_traits`] for details on syntax.
///
/// [`impl_function_traits`]: crate::func::macros::impl_function_traits
macro_rules! impl_from_arg {
(
$name: ty
$ty: ty
$(;
<
$($T: ident $(: $T1: tt $(+ $T2: tt)*)?),*
Expand All @@ -41,13 +48,13 @@ macro_rules! impl_from_arg {
impl <
$($($T $(: $T1 $(+ $T2)*)?),*)?
$(, $(const $N : $size),*)?
> $crate::func::args::FromArg for $name
> $crate::func::args::FromArg for $ty
$(
where
$($U $(: $U1 $(+ $U2)*)?),*
)?
{
type Item<'from_arg> = $name;
type Item<'from_arg> = $ty;
fn from_arg<'from_arg>(
arg: $crate::func::args::Arg<'from_arg>,
info: &$crate::func::args::ArgInfo,
Expand All @@ -59,13 +66,13 @@ macro_rules! impl_from_arg {
impl <
$($($T $(: $T1 $(+ $T2)*)?),*)?
$(, $(const $N : $size),*)?
> $crate::func::args::FromArg for &'static $name
> $crate::func::args::FromArg for &'static $ty
$(
where
$($U $(: $U1 $(+ $U2)*)?),*
)?
{
type Item<'from_arg> = &'from_arg $name;
type Item<'from_arg> = &'from_arg $ty;
fn from_arg<'from_arg>(
arg: $crate::func::args::Arg<'from_arg>,
info: &$crate::func::args::ArgInfo,
Expand All @@ -77,13 +84,13 @@ macro_rules! impl_from_arg {
impl <
$($($T $(: $T1 $(+ $T2)*)?),*)?
$(, $(const $N : $size),*)?
> $crate::func::args::FromArg for &'static mut $name
> $crate::func::args::FromArg for &'static mut $ty
$(
where
$($U $(: $U1 $(+ $U2)*)?),*
)?
{
type Item<'from_arg> = &'from_arg mut $name;
type Item<'from_arg> = &'from_arg mut $ty;
fn from_arg<'from_arg>(
arg: $crate::func::args::Arg<'from_arg>,
info: &$crate::func::args::ArgInfo,
Expand Down
15 changes: 11 additions & 4 deletions crates/bevy_reflect/src/func/args/ownership.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,16 @@ impl Display for Ownership {
}
}

/// Implements the [`GetOwnership`] trait for the given type.
///
/// This will implement it for `$ty`, `&$ty`, and `&mut $ty`.
///
/// See [`impl_function_traits`] for details on syntax.
///
/// [`impl_function_traits`]: crate::func::macros::impl_function_traits
macro_rules! impl_get_ownership {
(
$name: ty
$ty: ty
$(;
<
$($T: ident $(: $T1: tt $(+ $T2: tt)*)?),*
Expand All @@ -52,7 +59,7 @@ macro_rules! impl_get_ownership {
impl <
$($($T $(: $T1 $(+ $T2)*)?),*)?
$(, $(const $N : $size),*)?
> $crate::func::args::GetOwnership for $name
> $crate::func::args::GetOwnership for $ty
$(
where
$($U $(: $U1 $(+ $U2)*)?),*
Expand All @@ -66,7 +73,7 @@ macro_rules! impl_get_ownership {
impl <
$($($T $(: $T1 $(+ $T2)*)?),*)?
$(, $(const $N : $size),*)?
> $crate::func::args::GetOwnership for &'_ $name
> $crate::func::args::GetOwnership for &'_ $ty
$(
where
$($U $(: $U1 $(+ $U2)*)?),*
Expand All @@ -80,7 +87,7 @@ macro_rules! impl_get_ownership {
impl <
$($($T $(: $T1 $(+ $T2)*)?),*)?
$(, $(const $N : $size),*)?
> $crate::func::args::GetOwnership for &'_ mut $name
> $crate::func::args::GetOwnership for &'_ mut $ty
$(
where
$($U $(: $U1 $(+ $U2)*)?),*
Expand Down
21 changes: 16 additions & 5 deletions crates/bevy_reflect/src/func/into_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,24 @@ pub trait IntoFunction<'env, T> {
fn into_function(self) -> DynamicFunction<'env>;
}

// https://veykril.github.io/tlborm/decl-macros/building-blocks/counting.html#bit-twiddling
/// Helper macro that returns the number of tokens it receives.
///
/// This is used to get the argument count.
///
/// See: https://veykril.github.io/tlborm/decl-macros/building-blocks/counting.html#bit-twiddling
macro_rules! count_tts {
() => { 0 };
($odd:tt $($a:tt $b:tt)*) => { (count_tts!($($a)*) << 1) | 1 };
($($a:tt $even:tt)*) => { count_tts!($($a)*) << 1 };
}

/// Helper macro for implementing [`IntoFunction`] on Rust functions.
///
/// This currently implements it for the following signatures (where `argX` may be any of `T`, `&T`, or `&mut T`):
/// - `fn(arg0, arg1, ..., argN) -> R`
/// - `fn(&Receiver, arg0, arg1, ..., argN) -> &R`
/// - `fn(&mut Receiver, arg0, arg1, ..., argN) -> &mut R`
/// - `fn(&mut Receiver, arg0, arg1, ..., argN) -> &R`
macro_rules! impl_into_function {
($(($Arg:ident, $arg:ident)),*) => {
// === Owned Return === //
Expand Down Expand Up @@ -130,7 +141,7 @@ macro_rules! impl_into_function {
});
}

let [$($arg,)*] = args.take().try_into().ok().expect("invalid number of arguments");
let [$($arg,)*] = args.take().try_into().expect("invalid number of arguments");

#[allow(unused_mut)]
let mut _index = 0;
Expand Down Expand Up @@ -179,7 +190,7 @@ macro_rules! impl_into_function {
});
}

let [receiver, $($arg,)*] = args.take().try_into().ok().expect("invalid number of arguments");
let [receiver, $($arg,)*] = args.take().try_into().expect("invalid number of arguments");

let receiver = receiver.take_ref::<Receiver>(_info.args().get(0).expect("argument index out of bounds"))?;

Expand Down Expand Up @@ -230,7 +241,7 @@ macro_rules! impl_into_function {
});
}

let [receiver, $($arg,)*] = args.take().try_into().ok().expect("invalid number of arguments");
let [receiver, $($arg,)*] = args.take().try_into().expect("invalid number of arguments");

let receiver = receiver.take_mut::<Receiver>(_info.args().get(0).expect("argument index out of bounds"))?;

Expand Down Expand Up @@ -281,7 +292,7 @@ macro_rules! impl_into_function {
});
}

let [receiver, $($arg,)*] = args.take().try_into().ok().expect("invalid number of arguments");
let [receiver, $($arg,)*] = args.take().try_into().expect("invalid number of arguments");

let receiver = receiver.take_mut::<Receiver>(_info.args().get(0).expect("argument index out of bounds"))?;

Expand Down
34 changes: 30 additions & 4 deletions crates/bevy_reflect/src/func/macros.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,32 @@
/// Helper macro to implement the necessary traits for function reflection.
///
/// This macro calls the following macros:
/// - [`impl_get_ownership`](crate::func::args::impl_get_ownership)
/// - [`impl_from_arg`](crate::func::args::impl_from_arg)
/// - [`impl_into_return`](crate::func::impl_into_return)
///
/// # Syntax
///
/// For non-generic types, the macro simply expects the type:
///
/// ```ignore
/// impl_function_traits!(foo::bar::Baz);
/// ```
///
/// For generic types, however, the generic type parameters must also be given in angle brackets (`<` and `>`):
///
/// ```ignore
/// impl_function_traits!(foo::bar::Baz<T, U>; <T: Clone, U>);
/// ```
///
/// For generic const parameters, they must be given in square brackets (`[` and `]`):
///
/// ```ignore
/// impl_function_traits!(foo::bar::Baz<T, N>; <T> [const N: usize]);
/// ```
macro_rules! impl_function_traits {
(
$name: ty
$ty: ty
$(;
<
$($T: ident $(: $T1: tt $(+ $T2: tt)*)?),*
Expand All @@ -17,7 +43,7 @@ macro_rules! impl_function_traits {
)?
) => {
$crate::func::args::impl_get_ownership!(
$name
$ty
$(;
<
$($T $(: $T1 $(+ $T2)*)?),*
Expand All @@ -34,7 +60,7 @@ macro_rules! impl_function_traits {
)?
);
$crate::func::args::impl_from_arg!(
$name
$ty
$(;
<
$($T $(: $T1 $(+ $T2)*)?),*
Expand All @@ -51,7 +77,7 @@ macro_rules! impl_function_traits {
)?
);
$crate::func::impl_into_return!(
$name
$ty
$(;
<
$($T $(: $T1 $(+ $T2)*)?),*
Expand Down
15 changes: 11 additions & 4 deletions crates/bevy_reflect/src/func/return_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,16 @@ impl IntoReturn for () {
}
}

/// Implements the [`IntoReturn`] trait for the given type.
///
/// This will implement it for `ty`, `&ty`, and `&mut ty`.
///
/// See [`impl_function_traits`] for details on syntax.
///
/// [`impl_function_traits`]: crate::func::macros::impl_function_traits
macro_rules! impl_into_return {
(
$name: ty
$ty: ty
$(;
<
$($T: ident $(: $T1: tt $(+ $T2: tt)*)?),*
Expand All @@ -98,7 +105,7 @@ macro_rules! impl_into_return {
impl <
$($($T $(: $T1 $(+ $T2)*)?),*)?
$(, $(const $N : $size),*)?
> $crate::func::IntoReturn for $name
> $crate::func::IntoReturn for $ty
$(
where
$($U $(: $U1 $(+ $U2)*)?),*
Expand All @@ -112,7 +119,7 @@ macro_rules! impl_into_return {
impl <
$($($T $(: $T1 $(+ $T2)*)?),*)?
$(, $(const $N : $size),*)?
> $crate::func::IntoReturn for &'static $name
> $crate::func::IntoReturn for &'static $ty
$(
where
$($U $(: $U1 $(+ $U2)*)?),*
Expand All @@ -126,7 +133,7 @@ macro_rules! impl_into_return {
impl <
$($($T $(: $T1 $(+ $T2)*)?),*)?
$(, $(const $N : $size),*)?
> $crate::func::IntoReturn for &'static mut $name
> $crate::func::IntoReturn for &'static mut $ty
$(
where
$($U $(: $U1 $(+ $U2)*)?),*
Expand Down

0 comments on commit 1f49747

Please sign in to comment.