From f7b1f4e77ac9d7be5921db91d850723cfbc38d58 Mon Sep 17 00:00:00 2001 From: makspll Date: Wed, 26 Feb 2025 23:03:35 +0000 Subject: [PATCH] fix: remove `map` global and instead allow hashmap `FromScript` from list of tuples --- .../src/bindings/function/from.rs | 49 +++++++++++++++++++ .../src/bindings/function/mod.rs | 6 +-- .../src/bindings/function/script_function.rs | 6 ++- .../bevy_mod_scripting_functions/src/core.rs | 19 ------- 4 files changed, 56 insertions(+), 24 deletions(-) diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/from.rs b/crates/bevy_mod_scripting_core/src/bindings/function/from.rs index e3b9fed070..bc46ae2b66 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/function/from.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/function/from.rs @@ -449,6 +449,14 @@ where } Ok(hashmap) } + ScriptValue::List(list) => { + let mut hashmap = std::collections::HashMap::new(); + for elem in list { + let (key, val) = <(String, V)>::from_script(elem, world.clone())?; + hashmap.insert(key, val); + } + Ok(hashmap) + } _ => Err(InteropError::value_mismatch( std::any::TypeId::of::>(), value, @@ -499,3 +507,44 @@ where } } } + +macro_rules! impl_from_script_tuple { + ($($ty:ident),*) => { + #[allow(non_snake_case)] + impl<$($ty: FromScript),*> FromScript for ($($ty,)*) + where + Self: 'static, + $( + for<'w> $ty::This<'w>: Into<$ty>, + )* + { + type This<'w> = Self; + + fn from_script(value: ScriptValue, world: WorldGuard<'_>) -> Result { + match value { + ScriptValue::List(list) => { + let expected_arg_count = $crate::bindings::function::script_function::count!( $($ty)* ); + if list.len() != expected_arg_count { + return Err(InteropError::length_mismatch(expected_arg_count, list.len())); + } + + let mut iter = list.into_iter(); + $( + let next_item = iter.next().ok_or_else(|| InteropError::invariant("list has right amount of elements"))?; + let $ty = $ty::from_script(next_item, world.clone())?.into(); + )* + + + Ok(($($ty,)*)) + } + _ => Err(InteropError::value_mismatch( + std::any::TypeId::of::(), + value, + )), + } + } + } + }; +} + +bevy::utils::all_tuples!(impl_from_script_tuple, 1, 14, T); diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/mod.rs b/crates/bevy_mod_scripting_core/src/bindings/function/mod.rs index 274e3c4cb0..1a89f511ba 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/function/mod.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/function/mod.rs @@ -151,9 +151,9 @@ mod test { for<'a> T::This<'a>: Into, { test_is_valid_arg_and_return::<()>(); - test_is_valid_return::<(T,)>(); - test_is_valid_return::<(T, T)>(); - test_is_valid_return::<(T, T, T, T, T, T, T, T, T, T)>(); + test_is_valid_arg_and_return::<(T,)>(); + test_is_valid_arg_and_return::<(T, T)>(); + test_is_valid_arg_and_return::<(T, T, T, T, T, T, T, T, T, T)>(); } fn test_option() diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs b/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs index bdb309d9de..424b2b3ebe 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs @@ -530,10 +530,12 @@ impl ScriptFunctionRegistry { } macro_rules! count { - () => (0usize); - ( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*)); + () => (0usize); + ( $x:tt $($xs:tt)* ) => (1usize + $crate::bindings::function::script_function::count!($($xs)*)); } +pub(crate) use count; + macro_rules! impl_script_function { ($( $param:ident ),* ) => { diff --git a/crates/bevy_mod_scripting_functions/src/core.rs b/crates/bevy_mod_scripting_functions/src/core.rs index 8f22b99bcb..2142c5b3d5 100644 --- a/crates/bevy_mod_scripting_functions/src/core.rs +++ b/crates/bevy_mod_scripting_functions/src/core.rs @@ -656,25 +656,6 @@ impl GlobalNamespace { &mut allocator, )) } - - /// Constructs a hash map. Useful for languages which do not make the distinction between lists and dictionaries. - /// - /// Arguments: - /// * `map_or_list`: The list or map to convert to a hash map. - /// Returns: - /// * `hashMap`: The converted hash map - fn map( - map_or_list: Union, Vec>, - ) -> HashMap { - match map_or_list.into_left() { - Ok(map) => map, - Err(list) => list - .into_iter() - .enumerate() - .map(|(k, v)| (k.to_string(), v)) - .collect(), - } - } } pub fn register_core_functions(app: &mut App) {