Skip to content

Commit 7ebe979

Browse files
committed
Consistent by-ref and by-value parameters for Packed*Array
1 parent 3771abc commit 7ebe979

File tree

4 files changed

+39
-43
lines changed

4 files changed

+39
-43
lines changed

godot-core/src/builtin/array.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ impl<T: ArrayElement> Array<T> {
242242
// SAFETY: The array has type `T` and we're writing a value of type `T` to it.
243243
unsafe { self.as_inner_mut() }.push_front(value.to_variant());
244244
}
245+
245246
/// Removes and returns the last element of the array. Returns `None` if the array is empty.
246247
///
247248
/// _Godot equivalent: `pop_back`_
@@ -266,7 +267,7 @@ impl<T: ArrayElement> Array<T> {
266267
})
267268
}
268269

269-
/// Inserts a new element before the index. The index must be valid or the end of the array (`index == len()`).
270+
/// ⚠️ Inserts a new element before the index. The index must be valid or the end of the array (`index == len()`).
270271
///
271272
/// On large arrays, this method is much slower than [`push()`][Self::push], as it will move all the array's elements after the inserted element.
272273
/// The larger the array, the slower `insert()` will be.
@@ -286,12 +287,13 @@ impl<T: ArrayElement> Array<T> {
286287

287288
/// ⚠️ Removes and returns the element at the specified index. Equivalent of `pop_at` in GDScript.
288289
///
289-
/// On large arrays, this method is much slower than `pop_back()` as it will move all the array's
290+
/// On large arrays, this method is much slower than [`pop()`][Self::pop] as it will move all the array's
290291
/// elements after the removed element. The larger the array, the slower `remove()` will be.
291292
///
292293
/// # Panics
293294
///
294295
/// If `index` is out of bounds.
296+
#[doc(alias = "pop_at")]
295297
pub fn remove(&mut self, index: usize) -> T {
296298
self.check_bounds(index);
297299

@@ -304,7 +306,7 @@ impl<T: ArrayElement> Array<T> {
304306
///
305307
/// If the value does not exist in the array, nothing happens. To remove an element by index, use [`remove()`][Self::remove] instead.
306308
///
307-
/// On large arrays, this method is much slower than [`pop_back()`][Self::pop_back], as it will move all the array's
309+
/// On large arrays, this method is much slower than [`pop()`][Self::pop], as it will move all the array's
308310
/// elements after the removed element.
309311
pub fn erase(&mut self, value: &T) {
310312
// SAFETY: We don't write anything to the array.

godot-core/src/builtin/packed_array.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,13 @@ macro_rules! impl_packed_array {
101101
///
102102
/// _Godot equivalent: `has`_
103103
#[doc(alias = "has")]
104-
pub fn contains(&self, value: $Element) -> bool {
105-
self.as_inner().has(Self::into_arg(value))
104+
pub fn contains(&self, value: &$Element) -> bool {
105+
self.as_inner().has(Self::to_arg(value))
106106
}
107107

108108
/// Returns the number of times a value is in the array.
109-
pub fn count(&self, value: $Element) -> usize {
110-
to_usize(self.as_inner().count(Self::into_arg(value)))
109+
pub fn count(&self, value: &$Element) -> usize {
110+
to_usize(self.as_inner().count(Self::to_arg(value)))
111111
}
112112

113113
/// Returns the number of elements in the array. Equivalent of `size()` in Godot.
@@ -276,9 +276,9 @@ macro_rules! impl_packed_array {
276276
/// Searches the array for the first occurrence of a value and returns its index, or
277277
/// `None` if not found. Starts searching at index `from`; pass `None` to search the
278278
/// entire array.
279-
pub fn find(&self, value: $Element, from: Option<usize>) -> Option<usize> {
279+
pub fn find(&self, value: &$Element, from: Option<usize>) -> Option<usize> {
280280
let from = to_i64(from.unwrap_or(0));
281-
let index = self.as_inner().find(Self::into_arg(value), from);
281+
let index = self.as_inner().find(Self::to_arg(value), from);
282282
if index >= 0 {
283283
Some(index.try_into().unwrap())
284284
} else {
@@ -289,9 +289,9 @@ macro_rules! impl_packed_array {
289289
/// Searches the array backwards for the last occurrence of a value and returns its
290290
/// index, or `None` if not found. Starts searching at index `from`; pass `None` to
291291
/// search the entire array.
292-
pub fn rfind(&self, value: $Element, from: Option<usize>) -> Option<usize> {
292+
pub fn rfind(&self, value: &$Element, from: Option<usize>) -> Option<usize> {
293293
let from = from.map(to_i64).unwrap_or(-1);
294-
let index = self.as_inner().rfind(Self::into_arg(value), from);
294+
let index = self.as_inner().rfind(Self::to_arg(value), from);
295295
// It's not documented, but `rfind` returns -1 if not found.
296296
if index >= 0 {
297297
Some(to_usize(index))
@@ -305,13 +305,13 @@ macro_rules! impl_packed_array {
305305
/// If the value is not present in the array, returns the insertion index that would maintain sorting order.
306306
///
307307
/// Calling `bsearch()` on an unsorted array results in unspecified (but safe) behavior.
308-
pub fn bsearch(&self, value: $Element) -> usize {
309-
to_usize(self.as_inner().bsearch(Self::into_arg(value), true))
308+
pub fn bsearch(&self, value: &$Element) -> usize {
309+
to_usize(self.as_inner().bsearch(Self::to_arg(value), true))
310310
}
311311

312312
#[deprecated = "Renamed to bsearch like in Godot, to avoid confusion with Rust's slice::binary_search."]
313313
pub fn binary_search(&self, value: $Element) -> usize {
314-
self.bsearch(value)
314+
self.bsearch(&value)
315315
}
316316

317317
/// Reverses the order of the elements in the array.
@@ -386,6 +386,12 @@ macro_rules! impl_packed_array {
386386
e.into()
387387
}
388388

389+
#[inline]
390+
fn to_arg(e: &$Element) -> $Arg {
391+
// Once PackedArra<T> is generic, this could use a better tailored implementation that may not need to clone.
392+
e.clone().into()
393+
}
394+
389395
#[doc(hidden)]
390396
pub fn as_inner(&self) -> inner::$Inner<'_> {
391397
inner::$Inner::from_outer(self)

itest/rust/src/builtin_tests/containers/packed_array_test.rs

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ fn packed_array_clone() {
6767
let mut array = PackedByteArray::from(&[1, 2]);
6868
#[allow(clippy::redundant_clone)]
6969
let clone = array.clone();
70-
array.set(0, 3);
70+
array[0] = 3;
7171

7272
assert_eq!(clone[0], 1);
7373
}
@@ -159,41 +159,29 @@ fn packed_array_get() {
159159
fn packed_array_binary_search() {
160160
let array = PackedByteArray::from(&[1, 3]);
161161

162-
assert_eq!(array.binary_search(0), 0);
163-
assert_eq!(array.binary_search(1), 0);
164-
assert_eq!(array.binary_search(2), 1);
165-
assert_eq!(array.binary_search(3), 1);
166-
assert_eq!(array.binary_search(4), 2);
162+
assert_eq!(array.bsearch(&0), 0);
163+
assert_eq!(array.bsearch(&1), 0);
164+
assert_eq!(array.bsearch(&2), 1);
165+
assert_eq!(array.bsearch(&3), 1);
166+
assert_eq!(array.bsearch(&4), 2);
167167
}
168168

169169
#[itest]
170170
fn packed_array_find() {
171171
let array = PackedByteArray::from(&[1, 2, 1]);
172172

173-
assert_eq!(array.find(0, None), None);
174-
assert_eq!(array.find(1, None), Some(0));
175-
assert_eq!(array.find(1, Some(1)), Some(2));
173+
assert_eq!(array.find(&0, None), None);
174+
assert_eq!(array.find(&1, None), Some(0));
175+
assert_eq!(array.find(&1, Some(1)), Some(2));
176176
}
177177

178178
#[itest]
179179
fn packed_array_rfind() {
180180
let array = PackedByteArray::from(&[1, 2, 1]);
181181

182-
assert_eq!(array.rfind(0, None), None);
183-
assert_eq!(array.rfind(1, None), Some(2));
184-
assert_eq!(array.rfind(1, Some(1)), Some(0));
185-
}
186-
187-
#[itest]
188-
fn packed_array_set() {
189-
let mut array = PackedByteArray::from(&[1, 2]);
190-
191-
array.set(0, 3);
192-
assert_eq!(array[0], 3);
193-
194-
expect_panic("Array index 2 out of bounds: length is 2", move || {
195-
array.set(2, 4);
196-
});
182+
assert_eq!(array.rfind(&0, None), None);
183+
assert_eq!(array.rfind(&1, None), Some(2));
184+
assert_eq!(array.rfind(&1, Some(1)), Some(0));
197185
}
198186

199187
#[itest]

itest/rust/src/register_tests/constant_test.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ fn constants_correct_value() {
8989
.done();
9090

9191
for (constant_name, constant_value) in CONSTANTS {
92-
assert!(constants.contains(constant_name.into()));
92+
assert!(constants.contains(&constant_name.into()));
9393
assert_eq!(
9494
ClassDb::singleton().class_get_integer_constant(
9595
HasConstants::class_name().to_string_name(),
@@ -216,11 +216,11 @@ macro_rules! test_enum_export {
216216
.done();
217217

218218
for (variant_name, variant_value) in variants {
219-
assert!(godot_variants.contains(variant_name.into()));
220-
assert!(constants.contains(variant_name.into()));
219+
let variant_name = GString::from(variant_name);
220+
assert!(godot_variants.contains(&variant_name));
221+
assert!(constants.contains(&variant_name));
221222
assert_eq!(
222-
ClassDb::singleton()
223-
.class_get_integer_constant(class_name.to_string_name(), variant_name.into()),
223+
ClassDb::singleton().class_get_integer_constant(class_name.to_string_name(), variant_name.into()),
224224
variant_value
225225
);
226226
}

0 commit comments

Comments
 (0)