Skip to content

Commit c12fdaa

Browse files
committed
Move array/dict iterators to godot::builtin::iter
1 parent 799c3f5 commit c12fdaa

File tree

6 files changed

+116
-79
lines changed

6 files changed

+116
-79
lines changed

godot-core/src/builtin/array.rs renamed to godot-core/src/builtin/collections/array.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,18 @@
55
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
66
*/
77

8-
use godot_ffi as sys;
9-
10-
use crate::builtin::*;
11-
use crate::obj::EngineEnum;
12-
use crate::property::{builtin_type_string, Export, PropertyHintInfo, TypeStringHint, Var};
138
use std::fmt;
149
use std::marker::PhantomData;
15-
use sys::{ffi_methods, interface_fn, GodotFfi};
1610

17-
use super::meta::{
11+
use crate::builtin::meta::{
1812
ArrayElement, ConvertError, FromGodot, FromGodotError, FromVariantError, GodotConvert,
1913
GodotFfiVariant, GodotType, ToGodot,
2014
};
15+
use crate::builtin::*;
16+
use crate::obj::EngineEnum;
17+
use crate::property::{builtin_type_string, Export, PropertyHintInfo, TypeStringHint, Var};
18+
use godot_ffi as sys;
19+
use sys::{ffi_methods, interface_fn, GodotFfi};
2120

2221
/// Godot's `Array` type.
2322
///
@@ -682,13 +681,13 @@ impl<T: ArrayElement> Array<T> {
682681
}
683682

684683
/// Returns the runtime type info of this array.
685-
fn type_info(&self) -> TypeInfo {
684+
fn type_info(&self) -> ArrayTypeInfo {
686685
let variant_type = VariantType::from_sys(
687686
self.as_inner().get_typed_builtin() as sys::GDExtensionVariantType
688687
);
689688
let class_name = self.as_inner().get_typed_class_name();
690689

691-
TypeInfo {
690+
ArrayTypeInfo {
692691
variant_type,
693692
class_name,
694693
}
@@ -697,7 +696,7 @@ impl<T: ArrayElement> Array<T> {
697696
/// Checks that the inner array has the correct type set on it for storing elements of type `T`.
698697
fn with_checked_type(self) -> Result<Self, ConvertError> {
699698
let self_ty = self.type_info();
700-
let target_ty = TypeInfo::of::<T>();
699+
let target_ty = ArrayTypeInfo::of::<T>();
701700

702701
if self_ty == target_ty {
703702
Ok(self)
@@ -719,7 +718,7 @@ impl<T: ArrayElement> Array<T> {
719718
debug_assert!(self.is_empty());
720719
debug_assert!(!self.type_info().is_typed());
721720

722-
let type_info = TypeInfo::of::<T>();
721+
let type_info = ArrayTypeInfo::of::<T>();
723722
if type_info.is_typed() {
724723
let script = Variant::nil();
725724

@@ -1047,6 +1046,7 @@ impl<T: ArrayElement + FromGodot> From<&Array<T>> for Vec<T> {
10471046

10481047
// ----------------------------------------------------------------------------------------------------------------------------------------------
10491048

1049+
/// An iterator over typed elements of an [`Array`].
10501050
pub struct Iter<'a, T: ArrayElement> {
10511051
array: &'a Array<T>,
10521052
next_idx: usize,
@@ -1180,14 +1180,14 @@ macro_rules! varray {
11801180
///
11811181
/// We ignore the `script` parameter because it has no impact on typing in Godot.
11821182
#[derive(Eq, PartialEq)]
1183-
pub(crate) struct TypeInfo {
1183+
pub(crate) struct ArrayTypeInfo {
11841184
variant_type: VariantType,
11851185

11861186
/// Not a `ClassName` because some values come from Godot engine API.
11871187
class_name: StringName,
11881188
}
11891189

1190-
impl TypeInfo {
1190+
impl ArrayTypeInfo {
11911191
fn of<T: GodotType>() -> Self {
11921192
Self {
11931193
variant_type: <T::Via as GodotType>::Ffi::variant_type(),
@@ -1208,7 +1208,7 @@ impl TypeInfo {
12081208
}
12091209
}
12101210

1211-
impl fmt::Debug for TypeInfo {
1211+
impl fmt::Debug for ArrayTypeInfo {
12121212
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12131213
let class = self.class_name.to_string();
12141214
let class_str = if class.is_empty() {

godot-core/src/builtin/dictionary.rs renamed to godot-core/src/builtin/collections/dictionary.rs

Lines changed: 48 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
use godot_ffi as sys;
99

10-
use crate::builtin::meta::{FromGodot, ToGodot};
10+
use crate::builtin::meta::{impl_godot_as_self, FromGodot, ToGodot};
1111
use crate::builtin::{inner, Variant, VariantArray};
1212
use crate::property::{builtin_type_string, Export, PropertyHintInfo, TypeStringHint, Var};
1313
use sys::types::OpaqueDictionary;
@@ -16,8 +16,6 @@ use sys::{ffi_methods, interface_fn, GodotFfi};
1616
use std::marker::PhantomData;
1717
use std::{fmt, ptr};
1818

19-
use super::meta::impl_godot_as_self;
20-
2119
/// Godot's `Dictionary` type.
2220
///
2321
/// The keys and values of the dictionary are all `Variant`s, so they can be of different types.
@@ -211,48 +209,54 @@ impl Dictionary {
211209
self.as_inner().merge(other, overwrite)
212210
}
213211

214-
/// Returns a deep copy of the dictionary. All nested arrays and dictionaries are duplicated and
215-
/// will not be shared with the original dictionary. Note that any `Object`-derived elements will
216-
/// still be shallow copied.
212+
/// Deep copy, duplicating nested collections.
213+
///
214+
/// All nested arrays and dictionaries are duplicated and will not be shared with the original dictionary.
215+
/// Note that any `Object`-derived elements will still be shallow copied.
217216
///
218-
/// To create a shallow copy, use [`Self::duplicate_shallow()`] instead.
217+
/// To create a shallow copy, use [`Self::duplicate_shallow()`] instead.
219218
/// To create a new reference to the same dictionary data, use [`clone()`][Clone::clone].
220219
///
221220
/// _Godot equivalent: `dict.duplicate(true)`_
222221
pub fn duplicate_deep(&self) -> Self {
223222
self.as_inner().duplicate(true)
224223
}
225224

226-
/// Returns a shallow copy of the dictionary. All dictionary keys and values are copied, but
227-
/// any reference types (such as `Array`, `Dictionary` and `Object`) will still refer to the
228-
/// same value.
225+
/// Shallow copy, copying elements but sharing nested collections.
226+
///
227+
/// All dictionary keys and values are copied, but any reference types (such as `Array`, `Dictionary` and `Gd<T>` objects)
228+
/// will still refer to the same value.
229229
///
230-
/// To create a deep copy, use [`Self::duplicate_deep()`] instead.
230+
/// To create a deep copy, use [`Self::duplicate_deep()`] instead.
231231
/// To create a new reference to the same dictionary data, use [`clone()`][Clone::clone].
232232
///
233233
/// _Godot equivalent: `dict.duplicate(false)`_
234234
pub fn duplicate_shallow(&self) -> Self {
235235
self.as_inner().duplicate(false)
236236
}
237237

238-
/// Returns an iterator over the key-value pairs of the `Dictionary`. The pairs are each of type `(Variant, Variant)`.
239-
/// Each pair references the original `Dictionary`, but instead of a `&`-reference to key-value pairs as
240-
/// you might expect, the iterator returns a (cheap, shallow) copy of each key-value pair.
238+
/// Returns an iterator over the key-value pairs of the `Dictionary`.
241239
///
242-
/// Note that it's possible to modify the `Dictionary` through another reference while iterating
243-
/// over it. This will not result in unsoundness or crashes, but will cause the iterator to
244-
/// behave in an unspecified way.
240+
/// The pairs are each of type `(Variant, Variant)`. Each pair references the original `Dictionary`, but instead of a `&`-reference
241+
/// to key-value pairs as you might expect, the iterator returns a (cheap, shallow) copy of each key-value pair.
242+
///
243+
/// Note that it's possible to modify the `Dictionary` through another reference while iterating over it. This will not result in
244+
/// unsoundness or crashes, but will cause the iterator to behave in an unspecified way.
245+
///
246+
/// Use `iter_shared().typed::<K, V>()` to iterate over `(K, V)` pairs instead.
245247
pub fn iter_shared(&self) -> Iter<'_> {
246248
Iter::new(self)
247249
}
248250

249-
/// Returns an iterator over the keys `Dictionary`. The keys are each of type `Variant`. Each key references
250-
/// the original `Dictionary`, but instead of a `&`-reference to keys pairs as you might expect, the
251-
/// iterator returns a (cheap, shallow) copy of each key pair.
251+
/// Returns an iterator over the keys in a `Dictionary`.
252+
///
253+
/// The keys are each of type `Variant`. Each key references the original `Dictionary`, but instead of a `&`-reference to keys pairs
254+
/// as you might expect, the iterator returns a (cheap, shallow) copy of each key pair.
252255
///
253-
/// Note that it's possible to modify the `Dictionary` through another reference while iterating
254-
/// over it. This will not result in unsoundness or crashes, but will cause the iterator to
255-
/// behave in an unspecified way.
256+
/// Note that it's possible to modify the `Dictionary` through another reference while iterating over it. This will not result in
257+
/// unsoundness or crashes, but will cause the iterator to behave in an unspecified way.
258+
///
259+
/// Use `.keys_shared.typed::<K>()` to iterate over `K` keys instead.
256260
pub fn keys_shared(&self) -> Keys<'_> {
257261
Keys::new(self)
258262
}
@@ -504,8 +508,8 @@ impl<'a> DictionaryIter<'a> {
504508
ptr::addr_of_mut!(valid_u8),
505509
)
506510
};
507-
let valid = super::u8_to_bool(valid_u8);
508-
let has_next = super::u8_to_bool(has_next);
511+
let valid = u8_to_bool(valid_u8);
512+
let has_next = u8_to_bool(has_next);
509513

510514
if has_next {
511515
assert!(valid);
@@ -518,9 +522,9 @@ impl<'a> DictionaryIter<'a> {
518522

519523
// ----------------------------------------------------------------------------------------------------------------------------------------------
520524

521-
/// An iterator over key-value pairs from a `Dictionary`.
525+
/// Iterator over key-value pairs in a [`Dictionary`].
522526
///
523-
/// See [Dictionary::iter_shared()] for more information about iteration over dictionaries.
527+
/// See [`Dictionary::iter_shared()`] for more information about iteration over dictionaries.
524528
pub struct Iter<'a> {
525529
iter: DictionaryIter<'a>,
526530
}
@@ -553,9 +557,9 @@ impl<'a> Iterator for Iter<'a> {
553557

554558
// ----------------------------------------------------------------------------------------------------------------------------------------------
555559

556-
/// An iterator over keys from a `Dictionary`.
560+
/// Iterator over keys in a [`Dictionary`].
557561
///
558-
/// See [Dictionary::keys_shared()] for more information about iteration over dictionaries.
562+
/// See [`Dictionary::keys_shared()`] for more information about iteration over dictionaries.
559563
pub struct Keys<'a> {
560564
iter: DictionaryIter<'a>,
561565
}
@@ -595,10 +599,9 @@ impl<'a> Iterator for Keys<'a> {
595599

596600
// ----------------------------------------------------------------------------------------------------------------------------------------------
597601

598-
/// An iterator over key-value pairs from a `Dictionary` that will attempt to convert each
599-
/// key-value pair into a typed `(K, V)`.
602+
/// [`Dictionary`] iterator that converts each key-value pair into a typed `(K, V)`.
600603
///
601-
/// See [Dictionary::iter_shared()] for more information about iteration over dictionaries.
604+
/// See [`Dictionary::iter_shared()`] for more information about iteration over dictionaries.
602605
pub struct TypedIter<'a, K, V> {
603606
iter: DictionaryIter<'a>,
604607
_k: PhantomData<K>,
@@ -631,9 +634,9 @@ impl<'a, K: FromGodot, V: FromGodot> Iterator for TypedIter<'a, K, V> {
631634

632635
// ----------------------------------------------------------------------------------------------------------------------------------------------
633636

634-
/// An iterator over keys from a `Dictionary` that will attempt to convert each key into a `K`.
637+
/// [`Dictionary`] iterator that converts each key into a typed `K`.
635638
///
636-
/// See [Dictionary::iter_shared()] for more information about iteration over dictionaries.
639+
/// See [`Dictionary::iter_shared()`] for more information about iteration over dictionaries.
637640
pub struct TypedKeys<'a, K> {
638641
iter: DictionaryIter<'a>,
639642
_k: PhantomData<K>,
@@ -660,6 +663,17 @@ impl<'a, K: FromGodot> Iterator for TypedKeys<'a, K> {
660663
}
661664
}
662665

666+
// ----------------------------------------------------------------------------------------------------------------------------------------------
667+
// Helper functions
668+
669+
fn u8_to_bool(u: u8) -> bool {
670+
match u {
671+
0 => false,
672+
1 => true,
673+
_ => panic!("Invalid boolean value {u}"),
674+
}
675+
}
676+
663677
// ----------------------------------------------------------------------------------------------------------------------------------------------
664678

665679
/// Constructs [`Dictionary`] literals, close to Godot's own syntax.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (c) godot-rust; Bromeon and contributors.
3+
* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this
5+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
6+
*/
7+
8+
mod array;
9+
mod dictionary;
10+
mod packed_array;
11+
12+
// Re-export in godot::builtin.
13+
pub(crate) mod containers {
14+
pub use super::array::{Array, VariantArray};
15+
pub use super::dictionary::Dictionary;
16+
pub use super::packed_array::*;
17+
}
18+
19+
// Re-export in godot::builtin::iter.
20+
pub(crate) mod iterators {
21+
pub use super::array::Iter as ArrayIter;
22+
pub use super::dictionary::Iter as DictIter;
23+
pub use super::dictionary::Keys as DictKeys;
24+
pub use super::dictionary::TypedIter as DictTypedIter;
25+
pub use super::dictionary::TypedKeys as DictTypedKeys;
26+
}
27+
28+
// Crate-local re-exports.
29+
pub(crate) use array::ArrayTypeInfo;

godot-core/src/builtin/meta/godot_convert/convert_error.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@ use std::fmt;
1010

1111
use godot_ffi::VariantType;
1212

13-
use crate::builtin::{
14-
array_inner,
15-
meta::{ClassName, ToGodot},
16-
Variant,
17-
};
13+
use crate::builtin::collections::ArrayTypeInfo;
14+
use crate::builtin::meta::{ClassName, ToGodot};
15+
use crate::builtin::Variant;
1816

1917
type Cause = Box<dyn Error + Send + Sync>;
2018

@@ -173,8 +171,8 @@ impl fmt::Display for ErrorKind {
173171
#[derive(Eq, PartialEq, Debug)]
174172
pub(crate) enum FromGodotError {
175173
BadArrayType {
176-
expected: array_inner::TypeInfo,
177-
actual: array_inner::TypeInfo,
174+
expected: ArrayTypeInfo,
175+
actual: ArrayTypeInfo,
178176
},
179177
/// InvalidEnum is also used by bitfields.
180178
InvalidEnum,

0 commit comments

Comments
 (0)