Skip to content

Commit 8b18502

Browse files
committed
Add varray![...] macro to construct variant arrays
1 parent 18f3a7b commit 8b18502

File tree

5 files changed

+54
-55
lines changed

5 files changed

+54
-55
lines changed

godot-core/src/builtin/array.rs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -801,29 +801,48 @@ impl<T: VariantMetadata> GodotFfi for TypedArray<T> {
801801
}
802802
}
803803

804-
/// Allows for construction of [`TypedArray`] literals, much in the same way as Rust's standard
805-
/// `vec!` macro. The type of the array is inferred from the arguments.
806-
///
807-
/// # Example
804+
/// Allows for construction of [`TypedArray`] literals, similar to Rust's standard `vec!` macro.
805+
/// The type of the array is inferred from the arguments.
808806
///
807+
/// Example:
809808
/// ```no_run
810809
/// # use godot::prelude::*;
811-
/// let arr = array![3, 1, 4];
810+
/// let arr = array![3, 1, 4]; // type Array<i32>
812811
/// ```
813812
///
814-
/// To create an `Array` of variants, you need to convert each element explicitly:
813+
/// To create an `Array` of variants, see the [`varray!`] macro.
814+
#[macro_export]
815+
macro_rules! array {
816+
($($elements:expr),* $(,)?) => {
817+
{
818+
let mut array = $crate::builtin::TypedArray::default();
819+
$(
820+
array.push($elements);
821+
)*
822+
array
823+
}
824+
};
825+
}
826+
827+
/// Allows for construction of [`VariantArray`] literals, similar to Rust's standard `vec!` macro.
828+
/// The type of the array is always [`Variant`].
815829
///
830+
/// Example:
816831
/// ```no_run
817832
/// # use godot::prelude::*;
818-
/// let arr: Array = array![42_i64.to_variant(), "hello".to_variant()];
833+
/// let arr: Array = varray![42_i64, "hello", true];
819834
/// ```
835+
///
836+
/// To create a typed `Array` with a single element type, see the [`array!`] macro.
820837
#[macro_export]
821-
macro_rules! array {
838+
macro_rules! varray {
839+
// Note: use to_variant() and not Variant::from(), as that works with both references and values
822840
($($elements:expr),* $(,)?) => {
823841
{
824-
let mut array = $crate::builtin::TypedArray::default();
842+
use $crate::builtin::ToVariant as _;
843+
let mut array = $crate::builtin::Array::default();
825844
$(
826-
array.push($elements);
845+
array.push($elements.to_variant());
827846
)*
828847
array
829848
}

godot-core/src/builtin/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ mod vector4i;
5555
pub mod meta;
5656

5757
// Re-export macros.
58-
pub use crate::{array, dict};
58+
pub use crate::{array, dict, varray};
5959

6060
pub use array::*;
6161
pub use color::*;

godot/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ pub use godot_core::private;
128128
pub mod prelude {
129129
pub use super::bind::{godot_api, GodotClass, GodotExt};
130130
pub use super::builtin::*;
131-
pub use super::builtin::{array, dict}; // Re-export macros.
131+
pub use super::builtin::{array, dict, varray}; // Re-export macros.
132132
pub use super::engine::{
133133
load, try_load, utilities, AudioStreamPlayer, Camera2D, Camera3D, Input, Node, Node2D,
134134
Node3D, Object, PackedScene, RefCounted, Resource, SceneTree,

itest/rust/src/array_test.rs

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ fn typed_array_from_to_variant() {
7777

7878
#[itest]
7979
fn untyped_array_from_to_variant() {
80-
let array = array![1.to_variant(), 2.to_variant()];
80+
let array = varray![1, 2];
8181
let variant = array.to_variant();
8282
let result = Array::try_from_variant(&variant);
8383
assert_eq!(result, Ok(array));
@@ -91,7 +91,7 @@ fn array_from_packed_array() {
9191
// which is not reflected in our static type. It would make sense if it did, but Godot decided
9292
// otherwise: we get an untyped array.
9393
array.push(GodotString::from("hi").to_variant());
94-
assert_eq!(array, array![42.to_variant(), "hi".to_variant()]);
94+
assert_eq!(array, varray![42, "hi"]);
9595
}
9696

9797
#[itest]
@@ -146,7 +146,7 @@ fn array_share() {
146146
#[itest]
147147
fn array_duplicate_shallow() {
148148
let subarray = array![2, 3];
149-
let array = array![1.to_variant(), subarray.to_variant()];
149+
let array = varray![1, subarray];
150150
let duplicate = array.duplicate_shallow();
151151
TypedArray::<i64>::try_from_variant(&duplicate.get(1))
152152
.unwrap()
@@ -157,7 +157,7 @@ fn array_duplicate_shallow() {
157157
#[itest]
158158
fn array_duplicate_deep() {
159159
let subarray = array![2, 3];
160-
let array = array![1.to_variant(), subarray.to_variant()];
160+
let array = varray![1, subarray];
161161
let duplicate = array.duplicate_deep();
162162
TypedArray::<i64>::try_from_variant(&duplicate.get(1))
163163
.unwrap()
@@ -172,7 +172,7 @@ fn array_slice_shallow() {
172172
assert_eq!(slice, array![5, 3]);
173173

174174
let subarray = array![2, 3];
175-
let array = array![1.to_variant(), subarray.to_variant()];
175+
let array = varray![1, subarray];
176176
let slice = array.slice_shallow(1, 2, None);
177177
TypedArray::<i64>::try_from_variant(&slice.get(0))
178178
.unwrap()
@@ -187,7 +187,7 @@ fn array_slice_deep() {
187187
assert_eq!(slice, array![5, 3]);
188188

189189
let subarray = array![2, 3];
190-
let array = array![1.to_variant(), subarray.to_variant()];
190+
let array = varray![1, subarray];
191191
let slice = array.slice_deep(1, 2, None);
192192
TypedArray::<i64>::try_from_variant(&slice.get(0))
193193
.unwrap()
@@ -255,7 +255,7 @@ fn array_min_max() {
255255
assert_eq!(int_array.min(), Some(1));
256256
assert_eq!(int_array.max(), Some(2));
257257

258-
let uncomparable_array = array![1.to_variant(), GodotString::from("two").to_variant()];
258+
let uncomparable_array = varray![1, GodotString::from("two")];
259259

260260
assert_eq!(uncomparable_array.min(), None);
261261
assert_eq!(uncomparable_array.max(), None);
@@ -351,14 +351,14 @@ fn array_mixed_values() {
351351
let node = Node::new_alloc();
352352
let ref_counted = RefCounted::new();
353353

354-
let array = array![
355-
int.to_variant(),
356-
string.to_variant(),
357-
packed_array.to_variant(),
358-
typed_array.to_variant(),
359-
object.to_variant(),
360-
node.to_variant(),
361-
ref_counted.to_variant(),
354+
let array = varray![
355+
int,
356+
string,
357+
packed_array,
358+
typed_array,
359+
object,
360+
node,
361+
ref_counted,
362362
];
363363

364364
assert_eq!(i64::try_from_variant(&array.get(0)).unwrap(), int);
@@ -405,10 +405,7 @@ fn untyped_array_pass_to_godot_func() {
405405
node.queue_free(); // Do not leak even if the test fails.
406406

407407
assert_eq!(
408-
node.callv(
409-
StringName::from("has_signal"),
410-
array!["tree_entered".to_variant()]
411-
),
408+
node.callv(StringName::from("has_signal"), varray!["tree_entered"]),
412409
true.to_variant()
413410
);
414411
}
@@ -426,14 +423,7 @@ fn untyped_array_return_from_godot_func() {
426423
node.queue_free(); // Do not leak even if the test fails.
427424
let result = node.get_node_and_resource("child_node".into());
428425

429-
assert_eq!(
430-
result,
431-
array![
432-
child.to_variant(),
433-
Variant::nil(),
434-
NodePath::default().to_variant()
435-
]
436-
);
426+
assert_eq!(result, varray![child, Variant::nil(), NodePath::default()]);
437427
}
438428

439429
// TODO All API functions that take a `TypedArray` are even more obscure and not included in
@@ -489,7 +479,7 @@ impl ArrayTest {
489479

490480
#[func]
491481
fn return_untyped_array(&self) -> Array {
492-
array![42.to_variant(), "answer".to_variant()]
482+
varray![42, "answer"]
493483
}
494484

495485
#[func]

itest/rust/src/dictionary_test.rs

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::collections::{HashMap, HashSet};
88

99
use crate::{expect_panic, itest};
1010
use godot::{
11-
builtin::{array, dict, Dictionary, FromVariant, ToVariant},
11+
builtin::{dict, varray, Dictionary, FromVariant, ToVariant},
1212
prelude::{Share, Variant},
1313
};
1414

@@ -339,16 +339,12 @@ fn dictionary_contains_keys() {
339339
assert!(dictionary.contains_key("foo"), "key = \"foo\"");
340340
assert!(dictionary.contains_key("bar"), "key = \"bar\"");
341341
assert!(
342-
dictionary.contains_all_keys(array!["foo".to_variant(), "bar".to_variant()]),
342+
dictionary.contains_all_keys(varray!["foo", "bar"]),
343343
"keys = [\"foo\", \"bar\"]"
344344
);
345345
assert!(!dictionary.contains_key("missing"), "key = \"missing\"");
346346
assert!(
347-
!dictionary.contains_all_keys(array![
348-
"foo".to_variant(),
349-
"bar".to_variant(),
350-
"missing".to_variant()
351-
]),
347+
!dictionary.contains_all_keys(varray!["foo", "bar", "missing"]),
352348
"keys = [\"foo\", \"bar\", \"missing\"]"
353349
);
354350
}
@@ -360,14 +356,8 @@ fn dictionary_keys_values() {
360356
"bar": true,
361357
};
362358

363-
assert_eq!(
364-
dictionary.keys_array(),
365-
array!["foo".to_variant(), "bar".to_variant()]
366-
);
367-
assert_eq!(
368-
dictionary.values_array(),
369-
array![0.to_variant(), true.to_variant()]
370-
);
359+
assert_eq!(dictionary.keys_array(), varray!["foo", "bar"]);
360+
assert_eq!(dictionary.values_array(), varray![0, true]);
371361
}
372362

373363
#[itest]

0 commit comments

Comments
 (0)