Add ArgCount

This commit is contained in:
Gino Valente 2024-12-08 12:55:13 -07:00
parent f93aadd0dd
commit c3b91562d1
12 changed files with 447 additions and 77 deletions

View File

@ -0,0 +1,311 @@
use crate::func::args::ArgCountOutOfBoundsError;
use core::fmt::{Debug, Formatter};
/// A container for zero or more argument counts for a function.
///
/// For most functions, this will contain a single count,
/// however, overloaded functions may contain more.
///
/// # Maximum Argument Count
///
/// The maximum number of arguments that can be represented by this struct is 63,
/// as given by [`ArgCount::MAX_COUNT`].
/// The reason for this is that all counts are stored internally as a single `u64`
/// with each bit representing a specific count based on its bit index.
///
/// This allows for a smaller memory footprint and faster lookups compared to a
/// `HashSet` or `Vec` of possible counts.
/// It's also more appropriate for representing the argument counts of a function
/// given that most functions will not have more than a few arguments.
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct ArgCount {
/// The bits representing the argument counts.
///
/// Each bit represents a specific count based on its bit index.
bits: u64,
/// The total number of argument counts.
len: u8,
}
impl ArgCount {
/// The maximum number of arguments that can be represented by this struct.
pub const MAX_COUNT: usize = u64::BITS as usize - 1;
/// Create a new [`ArgCount`] with the given count.
///
/// # Errors
///
/// Returns an error if the count is greater than [`Self::MAX_COUNT`].
pub fn new(count: usize) -> Result<Self, ArgCountOutOfBoundsError> {
Ok(Self {
bits: 1 << Self::try_to_u8(count)?,
len: 1,
})
}
/// Adds the given count to this [`ArgCount`].
///
/// # Panics
///
/// Panics if the count is greater than [`Self::MAX_COUNT`].
pub fn add(&mut self, count: usize) {
self.try_add(count).unwrap();
}
/// Attempts to add the given count to this [`ArgCount`].
///
/// # Errors
///
/// Returns an error if the count is greater than [`Self::MAX_COUNT`].
pub fn try_add(&mut self, count: usize) -> Result<(), ArgCountOutOfBoundsError> {
let count = Self::try_to_u8(count)?;
if !self.contains_unchecked(count) {
self.len += 1;
self.bits |= 1 << count;
}
Ok(())
}
/// Removes the given count from this [`ArgCount`].
pub fn remove(&mut self, count: usize) {
self.try_remove(count).unwrap();
}
/// Attempts to remove the given count from this [`ArgCount`].
///
/// # Errors
///
/// Returns an error if the count is greater than [`Self::MAX_COUNT`].
pub fn try_remove(&mut self, count: usize) -> Result<(), ArgCountOutOfBoundsError> {
let count = Self::try_to_u8(count)?;
if self.contains_unchecked(count) {
self.len -= 1;
self.bits &= !(1 << count);
}
Ok(())
}
/// Checks if this [`ArgCount`] contains the given count.
pub fn contains(&self, count: usize) -> bool {
count < usize::BITS as usize && (self.bits >> count) & 1 == 1
}
/// Returns the total number of argument counts that this [`ArgCount`] contains.
pub fn len(&self) -> usize {
self.len as usize
}
/// Returns true if this [`ArgCount`] contains no argument counts.
pub fn is_empty(&self) -> bool {
self.len == 0
}
/// Returns an iterator over the argument counts in this [`ArgCount`].
pub fn iter(&self) -> ArgCountIter {
ArgCountIter {
count: *self,
index: 0,
found: 0,
}
}
/// Checks if this [`ArgCount`] contains the given count without any bounds checking.
///
/// # Panics
///
/// Panics if the count is greater than [`Self::MAX_COUNT`].
fn contains_unchecked(&self, count: u8) -> bool {
(self.bits >> count) & 1 == 1
}
/// Attempts to convert the given count to a `u8` within the bounds of the [maximum count].
///
/// [maximum count]: Self::MAX_COUNT
fn try_to_u8(count: usize) -> Result<u8, ArgCountOutOfBoundsError> {
if count > Self::MAX_COUNT {
Err(ArgCountOutOfBoundsError(count))
} else {
Ok(count as u8)
}
}
}
/// Defaults this [`ArgCount`] to empty.
///
/// This means that it contains no argument counts, including zero.
impl Default for ArgCount {
fn default() -> Self {
Self { bits: 0, len: 0 }
}
}
impl Debug for ArgCount {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.debug_set().entries(self.iter()).finish()
}
}
/// An iterator for the argument counts in an [`ArgCount`].
pub struct ArgCountIter {
count: ArgCount,
index: u8,
found: u8,
}
impl Iterator for ArgCountIter {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
loop {
if self.index as usize > ArgCount::MAX_COUNT {
return None;
}
if self.found == self.count.len {
// All counts have been found
return None;
}
if self.count.contains_unchecked(self.index) {
self.index += 1;
self.found += 1;
return Some(self.index as usize - 1);
}
self.index += 1;
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.count.len(), Some(self.count.len()))
}
}
impl ExactSizeIterator for ArgCountIter {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn should_default_to_empty() {
let count = ArgCount::default();
assert_eq!(count.len(), 0);
assert!(count.is_empty());
assert!(!count.contains(0));
}
#[test]
fn should_construct_with_count() {
let count = ArgCount::new(3).unwrap();
assert_eq!(count.len(), 1);
assert!(!count.is_empty());
assert!(count.contains(3));
}
#[test]
fn should_add_count() {
let mut count = ArgCount::default();
count.add(3);
assert_eq!(count.len(), 1);
assert!(count.contains(3));
}
#[test]
fn should_add_multiple_counts() {
let mut count = ArgCount::default();
count.add(3);
count.add(5);
count.add(7);
assert_eq!(count.len(), 3);
assert!(!count.contains(0));
assert!(!count.contains(1));
assert!(!count.contains(2));
assert!(count.contains(3));
assert!(count.contains(5));
assert!(count.contains(7));
}
#[test]
fn should_add_idempotently() {
let mut count = ArgCount::default();
count.add(3);
count.add(3);
assert_eq!(count.len(), 1);
assert!(count.contains(3));
}
#[test]
fn should_remove_count() {
let mut count = ArgCount::default();
count.add(3);
assert_eq!(count.len(), 1);
assert!(count.contains(3));
count.remove(3);
assert_eq!(count.len(), 0);
assert!(!count.contains(3));
}
#[test]
fn should_allow_removeting_nonexistent_count() {
let mut count = ArgCount::default();
assert_eq!(count.len(), 0);
assert!(!count.contains(3));
count.remove(3);
assert_eq!(count.len(), 0);
assert!(!count.contains(3));
}
#[test]
fn should_iterate_over_counts() {
let mut count = ArgCount::default();
count.add(3);
count.add(5);
count.add(7);
let mut iter = count.iter();
assert_eq!(iter.len(), 3);
assert_eq!(iter.next(), Some(3));
assert_eq!(iter.next(), Some(5));
assert_eq!(iter.next(), Some(7));
assert_eq!(iter.next(), None);
}
#[test]
fn should_return_error_for_out_of_bounds_count() {
let count = ArgCount::new(64);
assert_eq!(count, Err(ArgCountOutOfBoundsError(64)));
let mut count = ArgCount::default();
assert_eq!(count.try_add(64), Err(ArgCountOutOfBoundsError(64)));
assert_eq!(count.try_remove(64), Err(ArgCountOutOfBoundsError(64)));
}
#[test]
fn should_return_false_for_out_of_bounds_contains() {
let count = ArgCount::default();
assert!(!count.contains(64));
}
}

View File

@ -32,3 +32,8 @@ pub enum ArgError {
#[error("expected an argument but received none")]
EmptyArgList,
}
/// The given argument count is out of bounds.
#[derive(Debug, Error, PartialEq)]
#[error("argument count out of bounds: {0}")]
pub struct ArgCountOutOfBoundsError(pub usize);

View File

@ -4,6 +4,7 @@
//! [`DynamicFunctionMut`]: crate::func::DynamicFunctionMut
pub use arg::*;
pub use count::*;
pub use error::*;
pub use from_arg::*;
pub use info::*;
@ -11,6 +12,7 @@ pub use list::*;
pub use ownership::*;
mod arg;
mod count;
mod error;
mod from_arg;
mod info;

View File

@ -2,7 +2,9 @@ use crate::{
self as bevy_reflect,
__macro_exports::RegisterForReflection,
func::{
args::ArgList, dynamic_function_internal::DynamicFunctionInternal, info::FunctionInfo,
args::{ArgCount, ArgList},
dynamic_function_internal::DynamicFunctionInternal,
info::FunctionInfo,
DynamicFunctionMut, Function, FunctionOverloadError, FunctionResult, IntoFunction,
IntoFunctionMut,
},
@ -13,7 +15,6 @@ use crate::{
use alloc::{borrow::Cow, boxed::Box, sync::Arc};
use bevy_reflect_derive::impl_type_path;
use core::fmt::{Debug, Formatter};
use core::ops::RangeInclusive;
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec};
@ -83,7 +84,10 @@ impl<'env> DynamicFunction<'env> {
///
/// # Panics
///
/// Panics if no [`SignatureInfo`] is provided or if the conversion to [`FunctionInfo`] fails.
/// This function may panic for any of the following reasons:
/// - No [`SignatureInfo`] is provided.
/// - A provided [`SignatureInfo`] has more arguments than [`ArgCount::MAX_COUNT`].
/// - The conversion to [`FunctionInfo`] fails.
///
/// [calling]: crate::func::dynamic_function::DynamicFunction::call
/// [`SignatureInfo`]: crate::func::SignatureInfo
@ -309,27 +313,25 @@ impl<'env> DynamicFunction<'env> {
pub fn is_overloaded(&self) -> bool {
self.internal.is_overloaded()
}
/// Returns the number of arguments the function expects.
///
/// For [overloaded] functions that can have a variable number of arguments,
/// this will return the minimum and maximum number of arguments.
///
/// Otherwise, the range will have the same start and end.
/// this will contain the full set of counts for all signatures.
///
/// # Example
///
/// ```
/// # use bevy_reflect::func::IntoFunction;
/// let add = (|a: i32, b: i32| a + b).into_function();
/// assert_eq!(add.arg_count(), 2..=2);
/// assert!(add.arg_count().contains(2));
///
/// let add = add.with_overload(|a: f32, b: f32, c: f32| a + b + c);
/// assert_eq!(add.arg_count(), 2..=3);
/// assert!(add.arg_count().contains(2));
/// assert!(add.arg_count().contains(3));
/// ```
///
/// [overloaded]: Self::with_overload
pub fn arg_count(&self) -> RangeInclusive<usize> {
pub fn arg_count(&self) -> ArgCount {
self.internal.arg_count()
}
}
@ -510,7 +512,7 @@ mod tests {
assert_eq!(
error,
FunctionError::ArgCountMismatch {
expected: 2..=2,
expected: ArgCount::new(2).unwrap(),
received: 1
}
);
@ -527,12 +529,16 @@ mod tests {
.push_owned(2_i32)
.push_owned(3_i32)
.push_owned(4_i32);
let error = func.call(args).unwrap_err();
let mut expected_count = ArgCount::new(2).unwrap();
expected_count.add(3);
assert_eq!(
error,
FunctionError::ArgCountMismatch {
expected: 2..=3,
expected: expected_count,
received: 4
}
);

View File

@ -1,9 +1,9 @@
use crate::func::args::ArgCount;
use crate::func::signature::{ArgListSignature, ArgumentSignature};
use crate::func::{ArgList, FunctionError, FunctionInfo, FunctionOverloadError};
use alloc::borrow::Cow;
use bevy_utils::hashbrown::HashMap;
use core::fmt::{Debug, Formatter};
use core::ops::RangeInclusive;
/// An internal structure for storing a function and its corresponding [function information].
///
@ -101,11 +101,9 @@ impl<F> DynamicFunctionInternal<F> {
/// Returns the number of arguments the function expects.
///
/// For[overloaded functions that can have a variable number of arguments,
/// this will return the minimum and maximum number of arguments.
///
/// Otherwise, the range will have the same start and end.
pub fn arg_count(&self) -> RangeInclusive<usize> {
/// For overloaded functions that can have a variable number of arguments,
/// this will contain the full set of counts for all signatures.
pub fn arg_count(&self) -> ArgCount {
self.info.arg_count()
}
@ -117,7 +115,7 @@ impl<F> DynamicFunctionInternal<F> {
let expected_arg_count = self.arg_count();
let received_arg_count = args.len();
if !expected_arg_count.contains(&received_arg_count) {
if !expected_arg_count.contains(received_arg_count) {
Err(FunctionError::ArgCountMismatch {
expected: expected_arg_count,
received: received_arg_count,

View File

@ -1,13 +1,13 @@
use alloc::{borrow::Cow, boxed::Box, sync::Arc};
use core::fmt::{Debug, Formatter};
use core::ops::RangeInclusive;
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec};
use crate::func::{
args::ArgList, dynamic_function_internal::DynamicFunctionInternal, DynamicFunction,
FunctionInfo, FunctionOverloadError, FunctionResult, IntoFunctionMut,
args::{ArgCount, ArgList},
dynamic_function_internal::DynamicFunctionInternal,
DynamicFunction, FunctionInfo, FunctionOverloadError, FunctionResult, IntoFunctionMut,
};
/// A [`Box`] containing a callback to a reflected function.
@ -85,7 +85,10 @@ impl<'env> DynamicFunctionMut<'env> {
///
/// # Panics
///
/// Panics if no [`SignatureInfo`] is provided or if the conversion to [`FunctionInfo`] fails.
/// This function may panic for any of the following reasons:
/// - No [`SignatureInfo`] is provided.
/// - A provided [`SignatureInfo`] has more arguments than [`ArgCount::MAX_COUNT`].
/// - The conversion to [`FunctionInfo`] fails.
///
/// [calling]: crate::func::dynamic_function_mut::DynamicFunctionMut::call
/// [`SignatureInfo`]: crate::func::SignatureInfo
@ -313,23 +316,22 @@ impl<'env> DynamicFunctionMut<'env> {
/// Returns the number of arguments the function expects.
///
/// For [overloaded] functions that can have a variable number of arguments,
/// this will return the minimum and maximum number of arguments.
///
/// Otherwise, the range will have the same start and end.
/// this will contain the full set of counts for all signatures.
///
/// # Example
///
/// ```
/// # use bevy_reflect::func::IntoFunctionMut;
/// let add = (|a: i32, b: i32| a + b).into_function_mut();
/// assert_eq!(add.arg_count(), 2..=2);
/// assert!(add.arg_count().contains(2));
///
/// let add = add.with_overload(|a: f32, b: f32, c: f32| a + b + c);
/// assert_eq!(add.arg_count(), 2..=3);
/// assert!(add.arg_count().contains(2));
/// assert!(add.arg_count().contains(3));
/// ```
///
/// [overloaded]: Self::with_overload
pub fn arg_count(&self) -> RangeInclusive<usize> {
pub fn arg_count(&self) -> ArgCount {
self.internal.arg_count()
}
}
@ -412,7 +414,7 @@ mod tests {
assert_eq!(
error,
FunctionError::ArgCountMismatch {
expected: 2..=2,
expected: ArgCount::new(2).unwrap(),
received: 1
}
);
@ -422,7 +424,7 @@ mod tests {
assert_eq!(
error,
FunctionError::ArgCountMismatch {
expected: 2..=2,
expected: ArgCount::new(2).unwrap(),
received: 1
}
);

View File

@ -1,8 +1,10 @@
use crate::func::signature::ArgumentSignature;
use crate::func::{args::ArgError, Return};
use crate::func::{
args::{ArgCount, ArgError},
Return,
};
use alloc::borrow::Cow;
use bevy_utils::HashSet;
use core::ops::RangeInclusive;
use thiserror::Error;
#[cfg(not(feature = "std"))]
@ -18,11 +20,8 @@ pub enum FunctionError {
#[error(transparent)]
ArgError(#[from] ArgError),
/// The number of arguments provided does not match the expected number.
#[error("expected {expected:?} arguments but received {received}")]
ArgCountMismatch {
expected: RangeInclusive<usize>,
received: usize,
},
#[error("received {received} arguments but expected one of {expected:?}")]
ArgCountMismatch { expected: ArgCount, received: usize },
/// No overload was found for the given set of arguments.
#[error("no overload found for arguments with signature `{received:?}`, expected one of `{expected:?}`")]
NoOverload {
@ -51,6 +50,12 @@ pub enum FunctionOverloadError {
/// An error that occurs when attempting to add a function overload with a duplicate signature.
#[error("could not add function overload: duplicate found for signature `{0:?}`")]
DuplicateSignature(ArgumentSignature),
#[error(
"argument signature `{:?}` has too many arguments (max {})",
0,
ArgCount::MAX_COUNT
)]
TooManyArguments(ArgumentSignature),
}
/// An error that occurs when registering a function into a [`FunctionRegistry`].

View File

@ -1,10 +1,12 @@
use crate::{
func::{ArgList, DynamicFunction, FunctionInfo, FunctionResult},
func::{
args::{ArgCount, ArgList},
DynamicFunction, FunctionInfo, FunctionResult,
},
PartialReflect,
};
use alloc::borrow::Cow;
use core::fmt::Debug;
use core::ops::RangeInclusive;
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec};
@ -51,10 +53,8 @@ pub trait Function: PartialReflect + Debug {
/// Returns the number of arguments the function expects.
///
/// For overloaded functions that can have a variable number of arguments,
/// this will return the minimum and maximum number of arguments.
///
/// Otherwise, the range will have the same start and end.
fn arg_count(&self) -> RangeInclusive<usize> {
/// this will contain the full set of counts for all signatures.
fn arg_count(&self) -> ArgCount {
self.info().arg_count()
}

View File

@ -1,18 +1,17 @@
use alloc::{borrow::Cow, vec};
use core::fmt::{Debug, Formatter};
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec};
use crate::{
func::args::{ArgInfo, GetOwnership, Ownership},
func::args::{ArgCount, ArgCountOutOfBoundsError, ArgInfo, GetOwnership, Ownership},
func::signature::ArgumentSignature,
func::FunctionOverloadError,
type_info::impl_type_methods,
Type, TypePath,
};
use core::fmt::{Debug, Formatter};
use core::ops::RangeInclusive;
use variadics_please::all_tuples;
/// Type information for a [`DynamicFunction`] or [`DynamicFunctionMut`].
@ -28,14 +27,21 @@ use variadics_please::all_tuples;
#[derive(Debug, Clone)]
pub struct FunctionInfo {
name: Option<Cow<'static, str>>,
arg_count: ArgCount,
signatures: Box<[SignatureInfo]>,
}
impl FunctionInfo {
/// Create a new [`FunctionInfo`] for a function with the given signature.
///
/// # Panics
///
/// Panics if the given signature has more than the maximum number of arguments
/// as specified by [`ArgCount::MAX_COUNT`].
pub fn new(signature: SignatureInfo) -> Self {
Self {
name: signature.name.clone(),
arg_count: ArgCount::new(signature.arg_count()).unwrap(),
signatures: vec![signature].into(),
}
}
@ -48,9 +54,23 @@ impl FunctionInfo {
) -> Result<Self, FunctionOverloadError> {
let mut iter = signatures.into_iter();
let mut info = Self::new(iter.next().ok_or(FunctionOverloadError::MissingSignature)?);
let base = iter.next().ok_or(FunctionOverloadError::MissingSignature)?;
if base.arg_count() > ArgCount::MAX_COUNT {
return Err(FunctionOverloadError::TooManyArguments(
ArgumentSignature::from(&base),
));
}
let mut info = Self::new(base);
for signature in iter {
if signature.arg_count() > ArgCount::MAX_COUNT {
return Err(FunctionOverloadError::TooManyArguments(
ArgumentSignature::from(&signature),
));
}
info = info.with_overload(signature).map_err(|sig| {
FunctionOverloadError::DuplicateSignature(ArgumentSignature::from(&sig))
})?;
@ -102,6 +122,11 @@ impl FunctionInfo {
///
/// If a signature with the same [`ArgumentSignature`] already exists,
/// an error is returned with the given signature.
///
/// # Panics
///
/// Panics if the given signature has more than the maximum number of arguments
/// as specified by [`ArgCount::MAX_COUNT`].
pub fn with_overload(mut self, signature: SignatureInfo) -> Result<Self, SignatureInfo> {
let is_duplicate = self.signatures.iter().any(|s| {
s.arg_count() == signature.arg_count()
@ -112,6 +137,7 @@ impl FunctionInfo {
return Err(signature);
}
self.arg_count.add(signature.arg_count());
self.signatures = IntoIterator::into_iter(self.signatures)
.chain(Some(signature))
.collect();
@ -121,16 +147,9 @@ impl FunctionInfo {
/// Returns the number of arguments the function expects.
///
/// For overloaded functions that can have a variable number of arguments,
/// this will return the minimum and maximum number of arguments.
///
/// Otherwise, the range will have the same start and end.
pub fn arg_count(&self) -> RangeInclusive<usize> {
self.signatures
.iter()
.map(SignatureInfo::arg_count)
.fold(RangeInclusive::new(usize::MAX, usize::MIN), |acc, count| {
RangeInclusive::new((*acc.start()).min(count), (*acc.end()).max(count))
})
/// this will contain the full set of counts for all signatures.
pub fn arg_count(&self) -> ArgCount {
self.arg_count
}
/// The signatures of the function.
@ -164,6 +183,11 @@ impl FunctionInfo {
}
/// Extend this [`FunctionInfo`] with another without checking for duplicates.
///
/// # Panics
///
/// Panics if the given signature has more than the maximum number of arguments
/// as specified by [`ArgCount::MAX_COUNT`].
pub(super) fn extend_unchecked(&mut self, other: FunctionInfo) {
if self.name.is_none() {
self.name = other.name;
@ -173,12 +197,26 @@ impl FunctionInfo {
self.signatures = IntoIterator::into_iter(signatures)
.chain(IntoIterator::into_iter(other.signatures))
.collect();
self.arg_count = self
.signatures
.iter()
.fold(ArgCount::default(), |mut count, sig| {
count.add(sig.arg_count());
count
});
}
}
impl From<SignatureInfo> for FunctionInfo {
fn from(info: SignatureInfo) -> Self {
Self::new(info)
impl TryFrom<SignatureInfo> for FunctionInfo {
type Error = ArgCountOutOfBoundsError;
fn try_from(signature: SignatureInfo) -> Result<Self, Self::Error> {
let count = signature.arg_count();
if count > ArgCount::MAX_COUNT {
return Err(ArgCountOutOfBoundsError(count));
}
Ok(Self::new(signature))
}
}
@ -531,7 +569,7 @@ impl<'a> Debug for PrettyPrintSignatureInfo<'a> {
///
/// let info = print.get_function_info();
/// assert!(info.name().unwrap().ends_with("print"));
/// assert!(info.arg_count().contains(&1));
/// assert!(info.arg_count().contains(1));
/// assert_eq!(info.base().args()[0].type_path(), "alloc::string::String");
/// assert_eq!(info.base().return_info().type_path(), "()");
/// ```

View File

@ -191,13 +191,13 @@ pub mod signature;
mod tests {
use alloc::borrow::Cow;
use super::*;
use crate::func::args::ArgCount;
use crate::{
func::args::{ArgError, ArgList, Ownership},
TypePath,
};
use super::*;
#[test]
fn should_error_on_missing_args() {
fn foo(_: i32) {}
@ -208,7 +208,7 @@ mod tests {
assert_eq!(
result.unwrap_err(),
FunctionError::ArgCountMismatch {
expected: 1..=1,
expected: ArgCount::new(1).unwrap(),
received: 0
}
);
@ -224,7 +224,7 @@ mod tests {
assert_eq!(
result.unwrap_err(),
FunctionError::ArgCountMismatch {
expected: 0..=0,
expected: ArgCount::new(0).unwrap(),
received: 1
}
);

View File

@ -5,8 +5,9 @@ use alloc::{boxed::Box, format, vec};
use crate::{
func::{
args::FromArg, macros::count_tokens, ArgList, FunctionError, FunctionResult, IntoReturn,
ReflectFnMut,
args::{ArgCount, FromArg},
macros::count_tokens,
ArgList, FunctionError, FunctionResult, IntoReturn, ReflectFnMut,
},
Reflect, TypePath,
};
@ -96,7 +97,7 @@ macro_rules! impl_reflect_fn {
if args.len() != COUNT {
return Err(FunctionError::ArgCountMismatch {
expected: COUNT..=COUNT,
expected: ArgCount::new(COUNT).unwrap(),
received: args.len(),
});
}
@ -125,7 +126,7 @@ macro_rules! impl_reflect_fn {
if args.len() != COUNT {
return Err(FunctionError::ArgCountMismatch {
expected: COUNT..=COUNT,
expected: ArgCount::new(COUNT).unwrap(),
received: args.len(),
});
}
@ -155,7 +156,7 @@ macro_rules! impl_reflect_fn {
if args.len() != COUNT {
return Err(FunctionError::ArgCountMismatch {
expected: COUNT..=COUNT,
expected: ArgCount::new(COUNT).unwrap(),
received: args.len(),
});
}
@ -185,7 +186,7 @@ macro_rules! impl_reflect_fn {
if args.len() != COUNT {
return Err(FunctionError::ArgCountMismatch {
expected: COUNT..=COUNT,
expected: ArgCount::new(COUNT).unwrap(),
received: args.len(),
});
}

View File

@ -5,7 +5,9 @@ use alloc::{boxed::Box, format, vec};
use crate::{
func::{
args::FromArg, macros::count_tokens, ArgList, FunctionError, FunctionResult, IntoReturn,
args::{ArgCount, FromArg},
macros::count_tokens,
ArgList, FunctionError, FunctionResult, IntoReturn,
},
Reflect, TypePath,
};
@ -102,7 +104,7 @@ macro_rules! impl_reflect_fn_mut {
if args.len() != COUNT {
return Err(FunctionError::ArgCountMismatch {
expected: COUNT..=COUNT,
expected: ArgCount::new(COUNT).unwrap(),
received: args.len(),
});
}
@ -131,7 +133,7 @@ macro_rules! impl_reflect_fn_mut {
if args.len() != COUNT {
return Err(FunctionError::ArgCountMismatch {
expected: COUNT..=COUNT,
expected: ArgCount::new(COUNT).unwrap(),
received: args.len(),
});
}
@ -161,7 +163,7 @@ macro_rules! impl_reflect_fn_mut {
if args.len() != COUNT {
return Err(FunctionError::ArgCountMismatch {
expected: COUNT..=COUNT,
expected: ArgCount::new(COUNT).unwrap(),
received: args.len(),
});
}
@ -191,7 +193,7 @@ macro_rules! impl_reflect_fn_mut {
if args.len() != COUNT {
return Err(FunctionError::ArgCountMismatch {
expected: COUNT..=COUNT,
expected: ArgCount::new(COUNT).unwrap(),
received: args.len(),
});
}