Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_reflect/src/tuple.rs
9357 views
1
//! Traits and types used to power [tuple-like] operations via reflection.
2
//!
3
//! [tuple-like]: https://doc.rust-lang.org/book/ch03-02-data-types.html#the-tuple-type
4
use bevy_reflect_derive::impl_type_path;
5
use variadics_please::all_tuples;
6
7
use crate::generics::impl_generic_info_methods;
8
use crate::{
9
type_info::impl_type_methods, utility::GenericTypePathCell, ApplyError, FromReflect, Generics,
10
GetTypeRegistration, MaybeTyped, PartialReflect, Reflect, ReflectCloneError, ReflectKind,
11
ReflectMut, ReflectOwned, ReflectRef, Type, TypeInfo, TypePath, TypeRegistration, TypeRegistry,
12
Typed, UnnamedField,
13
};
14
use alloc::{boxed::Box, vec, vec::Vec};
15
use core::{
16
any::Any,
17
fmt::{Debug, Formatter},
18
slice::Iter,
19
};
20
21
/// A trait used to power [tuple-like] operations via [reflection].
22
///
23
/// This trait uses the [`Reflect`] trait to allow implementors to have their fields
24
/// be dynamically addressed by index.
25
///
26
/// This trait is automatically implemented for arbitrary tuples of up to 12
27
/// elements, provided that each element implements [`Reflect`].
28
///
29
/// # Example
30
///
31
/// ```
32
/// use bevy_reflect::{PartialReflect, tuple::Tuple};
33
///
34
/// let foo = (123_u32, true);
35
/// assert_eq!(foo.field_len(), 2);
36
///
37
/// let field: &dyn PartialReflect = foo.field(0).unwrap();
38
/// assert_eq!(field.try_downcast_ref::<u32>(), Some(&123));
39
/// ```
40
///
41
/// [tuple-like]: https://doc.rust-lang.org/book/ch03-02-data-types.html#the-tuple-type
42
/// [reflection]: crate
43
pub trait Tuple: PartialReflect {
44
/// Returns a reference to the value of the field with index `index` as a
45
/// `&dyn Reflect`.
46
fn field(&self, index: usize) -> Option<&dyn PartialReflect>;
47
48
/// Returns a mutable reference to the value of the field with index `index`
49
/// as a `&mut dyn Reflect`.
50
fn field_mut(&mut self, index: usize) -> Option<&mut dyn PartialReflect>;
51
52
/// Returns the number of fields in the tuple.
53
fn field_len(&self) -> usize;
54
55
/// Returns an iterator over the values of the tuple's fields.
56
fn iter_fields(&self) -> TupleFieldIter<'_>;
57
58
/// Drain the fields of this tuple to get a vector of owned values.
59
fn drain(self: Box<Self>) -> Vec<Box<dyn PartialReflect>>;
60
61
/// Creates a new [`DynamicTuple`] from this tuple.
62
fn to_dynamic_tuple(&self) -> DynamicTuple {
63
DynamicTuple {
64
represented_type: self.get_represented_type_info(),
65
fields: self.iter_fields().map(PartialReflect::to_dynamic).collect(),
66
}
67
}
68
69
/// Will return `None` if [`TypeInfo`] is not available.
70
fn get_represented_tuple_info(&self) -> Option<&'static TupleInfo> {
71
self.get_represented_type_info()?.as_tuple().ok()
72
}
73
}
74
75
/// An iterator over the field values of a tuple.
76
pub struct TupleFieldIter<'a> {
77
pub(crate) tuple: &'a dyn Tuple,
78
pub(crate) index: usize,
79
}
80
81
impl<'a> TupleFieldIter<'a> {
82
/// Creates a new [`TupleFieldIter`].
83
pub fn new(value: &'a dyn Tuple) -> Self {
84
TupleFieldIter {
85
tuple: value,
86
index: 0,
87
}
88
}
89
}
90
91
impl<'a> Iterator for TupleFieldIter<'a> {
92
type Item = &'a dyn PartialReflect;
93
94
fn next(&mut self) -> Option<Self::Item> {
95
let value = self.tuple.field(self.index);
96
self.index += value.is_some() as usize;
97
value
98
}
99
100
fn size_hint(&self) -> (usize, Option<usize>) {
101
let size = self.tuple.field_len();
102
(size, Some(size))
103
}
104
}
105
106
impl<'a> ExactSizeIterator for TupleFieldIter<'a> {}
107
108
/// A convenience trait which combines fetching and downcasting of tuple
109
/// fields.
110
///
111
/// # Example
112
///
113
/// ```
114
/// use bevy_reflect::tuple::GetTupleField;
115
///
116
/// # fn main() {
117
/// let foo = ("blue".to_string(), 42_i32);
118
///
119
/// assert_eq!(foo.get_field::<String>(0), Some(&"blue".to_string()));
120
/// assert_eq!(foo.get_field::<i32>(1), Some(&42));
121
/// # }
122
/// ```
123
pub trait GetTupleField {
124
/// Returns a reference to the value of the field with index `index`,
125
/// downcast to `T`.
126
fn get_field<T: Reflect>(&self, index: usize) -> Option<&T>;
127
128
/// Returns a mutable reference to the value of the field with index
129
/// `index`, downcast to `T`.
130
fn get_field_mut<T: Reflect>(&mut self, index: usize) -> Option<&mut T>;
131
}
132
133
impl<S: Tuple> GetTupleField for S {
134
fn get_field<T: Reflect>(&self, index: usize) -> Option<&T> {
135
self.field(index)
136
.and_then(|value| value.try_downcast_ref::<T>())
137
}
138
139
fn get_field_mut<T: Reflect>(&mut self, index: usize) -> Option<&mut T> {
140
self.field_mut(index)
141
.and_then(|value| value.try_downcast_mut::<T>())
142
}
143
}
144
145
impl GetTupleField for dyn Tuple {
146
fn get_field<T: Reflect>(&self, index: usize) -> Option<&T> {
147
self.field(index)
148
.and_then(|value| value.try_downcast_ref::<T>())
149
}
150
151
fn get_field_mut<T: Reflect>(&mut self, index: usize) -> Option<&mut T> {
152
self.field_mut(index)
153
.and_then(|value| value.try_downcast_mut::<T>())
154
}
155
}
156
157
/// A container for compile-time tuple info.
158
#[derive(Clone, Debug)]
159
pub struct TupleInfo {
160
ty: Type,
161
generics: Generics,
162
fields: Box<[UnnamedField]>,
163
#[cfg(feature = "reflect_documentation")]
164
docs: Option<&'static str>,
165
}
166
167
impl TupleInfo {
168
/// Create a new [`TupleInfo`].
169
///
170
/// # Arguments
171
///
172
/// * `fields`: The fields of this tuple in the order they are defined
173
pub fn new<T: Reflect + TypePath>(fields: &[UnnamedField]) -> Self {
174
Self {
175
ty: Type::of::<T>(),
176
generics: Generics::new(),
177
fields: fields.to_vec().into_boxed_slice(),
178
#[cfg(feature = "reflect_documentation")]
179
docs: None,
180
}
181
}
182
183
/// Sets the docstring for this tuple.
184
#[cfg(feature = "reflect_documentation")]
185
pub fn with_docs(self, docs: Option<&'static str>) -> Self {
186
Self { docs, ..self }
187
}
188
189
/// Get the field at the given index.
190
pub fn field_at(&self, index: usize) -> Option<&UnnamedField> {
191
self.fields.get(index)
192
}
193
194
/// Iterate over the fields of this tuple.
195
pub fn iter(&self) -> Iter<'_, UnnamedField> {
196
self.fields.iter()
197
}
198
199
/// The total number of fields in this tuple.
200
pub fn field_len(&self) -> usize {
201
self.fields.len()
202
}
203
204
impl_type_methods!(ty);
205
206
/// The docstring of this tuple, if any.
207
#[cfg(feature = "reflect_documentation")]
208
pub fn docs(&self) -> Option<&'static str> {
209
self.docs
210
}
211
212
impl_generic_info_methods!(generics);
213
}
214
215
/// A tuple which allows fields to be added at runtime.
216
#[derive(Default, Debug)]
217
pub struct DynamicTuple {
218
represented_type: Option<&'static TypeInfo>,
219
fields: Vec<Box<dyn PartialReflect>>,
220
}
221
222
impl DynamicTuple {
223
/// Sets the [type] to be represented by this `DynamicTuple`.
224
///
225
/// # Panics
226
///
227
/// Panics if the given [type] is not a [`TypeInfo::Tuple`].
228
///
229
/// [type]: TypeInfo
230
pub fn set_represented_type(&mut self, represented_type: Option<&'static TypeInfo>) {
231
if let Some(represented_type) = represented_type {
232
assert!(
233
matches!(represented_type, TypeInfo::Tuple(_)),
234
"expected TypeInfo::Tuple but received: {represented_type:?}"
235
);
236
}
237
self.represented_type = represented_type;
238
}
239
240
/// Appends an element with value `value` to the tuple.
241
pub fn insert_boxed(&mut self, value: Box<dyn PartialReflect>) {
242
self.represented_type = None;
243
self.fields.push(value);
244
}
245
246
/// Appends a typed element with value `value` to the tuple.
247
pub fn insert<T: PartialReflect>(&mut self, value: T) {
248
self.represented_type = None;
249
self.insert_boxed(Box::new(value));
250
}
251
}
252
253
impl Tuple for DynamicTuple {
254
#[inline]
255
fn field(&self, index: usize) -> Option<&dyn PartialReflect> {
256
self.fields.get(index).map(|field| &**field)
257
}
258
259
#[inline]
260
fn field_mut(&mut self, index: usize) -> Option<&mut dyn PartialReflect> {
261
self.fields.get_mut(index).map(|field| &mut **field)
262
}
263
264
#[inline]
265
fn field_len(&self) -> usize {
266
self.fields.len()
267
}
268
269
#[inline]
270
fn iter_fields(&self) -> TupleFieldIter<'_> {
271
TupleFieldIter {
272
tuple: self,
273
index: 0,
274
}
275
}
276
277
#[inline]
278
fn drain(self: Box<Self>) -> Vec<Box<dyn PartialReflect>> {
279
self.fields
280
}
281
}
282
283
impl PartialReflect for DynamicTuple {
284
#[inline]
285
fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
286
self.represented_type
287
}
288
289
#[inline]
290
fn into_partial_reflect(self: Box<Self>) -> Box<dyn PartialReflect> {
291
self
292
}
293
294
fn as_partial_reflect(&self) -> &dyn PartialReflect {
295
self
296
}
297
298
fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect {
299
self
300
}
301
302
fn try_into_reflect(self: Box<Self>) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>> {
303
Err(self)
304
}
305
306
fn try_as_reflect(&self) -> Option<&dyn Reflect> {
307
None
308
}
309
310
fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect> {
311
None
312
}
313
314
fn apply(&mut self, value: &dyn PartialReflect) {
315
tuple_apply(self, value);
316
}
317
318
#[inline]
319
fn reflect_kind(&self) -> ReflectKind {
320
ReflectKind::Tuple
321
}
322
323
#[inline]
324
fn reflect_ref(&self) -> ReflectRef<'_> {
325
ReflectRef::Tuple(self)
326
}
327
328
#[inline]
329
fn reflect_mut(&mut self) -> ReflectMut<'_> {
330
ReflectMut::Tuple(self)
331
}
332
333
#[inline]
334
fn reflect_owned(self: Box<Self>) -> ReflectOwned {
335
ReflectOwned::Tuple(self)
336
}
337
338
fn try_apply(&mut self, value: &dyn PartialReflect) -> Result<(), ApplyError> {
339
tuple_try_apply(self, value)
340
}
341
342
fn reflect_partial_eq(&self, value: &dyn PartialReflect) -> Option<bool> {
343
tuple_partial_eq(self, value)
344
}
345
346
fn reflect_partial_cmp(&self, value: &dyn PartialReflect) -> Option<::core::cmp::Ordering> {
347
tuple_partial_cmp(self, value)
348
}
349
350
fn debug(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
351
write!(f, "DynamicTuple(")?;
352
tuple_debug(self, f)?;
353
write!(f, ")")
354
}
355
356
#[inline]
357
fn is_dynamic(&self) -> bool {
358
true
359
}
360
}
361
362
impl_type_path!((in bevy_reflect) DynamicTuple);
363
364
impl FromIterator<Box<dyn PartialReflect>> for DynamicTuple {
365
fn from_iter<I: IntoIterator<Item = Box<dyn PartialReflect>>>(fields: I) -> Self {
366
Self {
367
represented_type: None,
368
fields: fields.into_iter().collect(),
369
}
370
}
371
}
372
373
impl IntoIterator for DynamicTuple {
374
type Item = Box<dyn PartialReflect>;
375
type IntoIter = vec::IntoIter<Self::Item>;
376
377
fn into_iter(self) -> Self::IntoIter {
378
self.fields.into_iter()
379
}
380
}
381
382
impl<'a> IntoIterator for &'a DynamicTuple {
383
type Item = &'a dyn PartialReflect;
384
type IntoIter = TupleFieldIter<'a>;
385
386
fn into_iter(self) -> Self::IntoIter {
387
self.iter_fields()
388
}
389
}
390
391
/// Applies the elements of `b` to the corresponding elements of `a`.
392
///
393
/// # Panics
394
///
395
/// This function panics if `b` is not a tuple.
396
#[inline]
397
pub fn tuple_apply<T: Tuple>(a: &mut T, b: &dyn PartialReflect) {
398
if let Err(err) = tuple_try_apply(a, b) {
399
panic!("{err}");
400
}
401
}
402
403
/// Tries to apply the elements of `b` to the corresponding elements of `a` and
404
/// returns a Result.
405
///
406
/// # Errors
407
///
408
/// This function returns an [`ApplyError::MismatchedKinds`] if `b` is not a tuple or if
409
/// applying elements to each other fails.
410
#[inline]
411
pub fn tuple_try_apply<T: Tuple>(a: &mut T, b: &dyn PartialReflect) -> Result<(), ApplyError> {
412
let tuple = b.reflect_ref().as_tuple()?;
413
414
for (i, value) in tuple.iter_fields().enumerate() {
415
if let Some(v) = a.field_mut(i) {
416
v.try_apply(value)?;
417
}
418
}
419
420
Ok(())
421
}
422
423
/// Compares a [`Tuple`] with a [`PartialReflect`] value.
424
///
425
/// Returns true if and only if all of the following are true:
426
/// - `b` is a tuple;
427
/// - `b` has the same number of elements as `a`;
428
/// - [`PartialReflect::reflect_partial_eq`] returns `Some(true)` for pairwise elements of `a` and `b`.
429
///
430
/// Returns [`None`] if the comparison couldn't even be performed.
431
#[inline]
432
pub fn tuple_partial_eq<T: Tuple + ?Sized>(a: &T, b: &dyn PartialReflect) -> Option<bool> {
433
let ReflectRef::Tuple(b) = b.reflect_ref() else {
434
return Some(false);
435
};
436
437
if a.field_len() != b.field_len() {
438
return Some(false);
439
}
440
441
for (a_field, b_field) in a.iter_fields().zip(b.iter_fields()) {
442
let eq_result = a_field.reflect_partial_eq(b_field);
443
if let failed @ (Some(false) | None) = eq_result {
444
return failed;
445
}
446
}
447
448
Some(true)
449
}
450
451
/// Lexicographically compares two [`Tuple`] values and returns their ordering.
452
///
453
/// Returns [`None`] if the comparison couldn't be performed (e.g., kinds mismatch
454
/// or an element comparison returns `None`).
455
#[inline]
456
pub fn tuple_partial_cmp<T: Tuple + ?Sized>(
457
a: &T,
458
b: &dyn PartialReflect,
459
) -> Option<::core::cmp::Ordering> {
460
let ReflectRef::Tuple(b) = b.reflect_ref() else {
461
return None;
462
};
463
if a.field_len() != b.field_len() {
464
return None;
465
}
466
467
for (a_field, b_field) in a.iter_fields().zip(b.iter_fields()) {
468
match a_field.reflect_partial_cmp(b_field) {
469
None => return None,
470
Some(core::cmp::Ordering::Equal) => continue,
471
Some(ord) => return Some(ord),
472
}
473
}
474
475
Some(core::cmp::Ordering::Equal)
476
}
477
478
/// The default debug formatter for [`Tuple`] types.
479
///
480
/// # Example
481
/// ```
482
/// use bevy_reflect::Reflect;
483
///
484
/// let my_tuple: &dyn Reflect = &(1, 2, 3);
485
/// println!("{:#?}", my_tuple);
486
///
487
/// // Output:
488
///
489
/// // (
490
/// // 1,
491
/// // 2,
492
/// // 3,
493
/// // )
494
/// ```
495
#[inline]
496
pub fn tuple_debug(dyn_tuple: &dyn Tuple, f: &mut Formatter<'_>) -> core::fmt::Result {
497
let mut debug = f.debug_tuple("");
498
for field in dyn_tuple.iter_fields() {
499
debug.field(&field as &dyn Debug);
500
}
501
debug.finish()
502
}
503
504
macro_rules! impl_reflect_tuple {
505
{$($index:tt : $name:tt),*} => {
506
impl<$($name: Reflect + MaybeTyped + TypePath + GetTypeRegistration),*> Tuple for ($($name,)*) {
507
#[inline]
508
fn field(&self, index: usize) -> Option<&dyn PartialReflect> {
509
match index {
510
$($index => Some(&self.$index as &dyn PartialReflect),)*
511
_ => None,
512
}
513
}
514
515
#[inline]
516
fn field_mut(&mut self, index: usize) -> Option<&mut dyn PartialReflect> {
517
match index {
518
$($index => Some(&mut self.$index as &mut dyn PartialReflect),)*
519
_ => None,
520
}
521
}
522
523
#[inline]
524
fn field_len(&self) -> usize {
525
let indices: &[usize] = &[$($index as usize),*];
526
indices.len()
527
}
528
529
#[inline]
530
fn iter_fields(&self) -> TupleFieldIter<'_> {
531
TupleFieldIter {
532
tuple: self,
533
index: 0,
534
}
535
}
536
537
#[inline]
538
fn drain(self: Box<Self>) -> Vec<Box<dyn PartialReflect>> {
539
vec![
540
$(Box::new(self.$index),)*
541
]
542
}
543
}
544
545
impl<$($name: Reflect + MaybeTyped + TypePath + GetTypeRegistration),*> PartialReflect for ($($name,)*) {
546
fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
547
Some(<Self as Typed>::type_info())
548
}
549
550
#[inline]
551
fn into_partial_reflect(self: Box<Self>) -> Box<dyn PartialReflect> {
552
self
553
}
554
555
fn as_partial_reflect(&self) -> &dyn PartialReflect {
556
self
557
}
558
559
fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect {
560
self
561
}
562
563
fn try_into_reflect(self: Box<Self>) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>> {
564
Ok(self)
565
}
566
567
fn try_as_reflect(&self) -> Option<&dyn Reflect> {
568
Some(self)
569
}
570
571
fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect> {
572
Some(self)
573
}
574
575
fn reflect_kind(&self) -> ReflectKind {
576
ReflectKind::Tuple
577
}
578
579
fn reflect_ref(&self) -> ReflectRef <'_> {
580
ReflectRef::Tuple(self)
581
}
582
583
fn reflect_mut(&mut self) -> ReflectMut <'_> {
584
ReflectMut::Tuple(self)
585
}
586
587
fn reflect_owned(self: Box<Self>) -> ReflectOwned {
588
ReflectOwned::Tuple(self)
589
}
590
591
fn reflect_partial_eq(&self, value: &dyn PartialReflect) -> Option<bool> {
592
crate::tuple::tuple_partial_eq(self, value)
593
}
594
fn reflect_partial_cmp(&self, value: &dyn PartialReflect) -> Option<::core::cmp::Ordering> {
595
crate::tuple::tuple_partial_cmp(self, value)
596
}
597
598
fn apply(&mut self, value: &dyn PartialReflect) {
599
crate::tuple::tuple_apply(self, value);
600
}
601
602
fn try_apply(&mut self, value: &dyn PartialReflect) -> Result<(), ApplyError> {
603
crate::tuple::tuple_try_apply(self, value)
604
}
605
606
fn reflect_clone(&self) -> Result<Box<dyn Reflect>, ReflectCloneError> {
607
Ok(Box::new((
608
$(
609
self.$index.reflect_clone()?
610
.take::<$name>()
611
.expect("`Reflect::reflect_clone` should return the same type"),
612
)*
613
)))
614
}
615
}
616
617
impl<$($name: Reflect + MaybeTyped + TypePath + GetTypeRegistration),*> Reflect for ($($name,)*) {
618
fn into_any(self: Box<Self>) -> Box<dyn Any> {
619
self
620
}
621
622
fn as_any(&self) -> &dyn Any {
623
self
624
}
625
626
fn as_any_mut(&mut self) -> &mut dyn Any {
627
self
628
}
629
630
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
631
self
632
}
633
634
fn as_reflect(&self) -> &dyn Reflect {
635
self
636
}
637
638
fn as_reflect_mut(&mut self) -> &mut dyn Reflect {
639
self
640
}
641
642
fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
643
*self = value.take()?;
644
Ok(())
645
}
646
}
647
648
impl <$($name: Reflect + MaybeTyped + TypePath + GetTypeRegistration),*> Typed for ($($name,)*) {
649
fn type_info() -> &'static TypeInfo {
650
static CELL: $crate::utility::GenericTypeInfoCell = $crate::utility::GenericTypeInfoCell::new();
651
CELL.get_or_insert::<Self, _>(|| {
652
let fields = [
653
$(UnnamedField::new::<$name>($index),)*
654
];
655
let info = TupleInfo::new::<Self>(&fields);
656
TypeInfo::Tuple(info)
657
})
658
}
659
}
660
661
impl<$($name: Reflect + MaybeTyped + TypePath + GetTypeRegistration),*> GetTypeRegistration for ($($name,)*) {
662
fn get_type_registration() -> TypeRegistration {
663
TypeRegistration::of::<($($name,)*)>()
664
}
665
666
fn register_type_dependencies(_registry: &mut TypeRegistry) {
667
$(_registry.register::<$name>();)*
668
}
669
}
670
671
impl<$($name: FromReflect + MaybeTyped + TypePath + GetTypeRegistration),*> FromReflect for ($($name,)*)
672
{
673
fn from_reflect(reflect: &dyn PartialReflect) -> Option<Self> {
674
let _ref_tuple = reflect.reflect_ref().as_tuple().ok()?;
675
676
Some(
677
(
678
$(
679
<$name as FromReflect>::from_reflect(_ref_tuple.field($index)?)?,
680
)*
681
)
682
)
683
}
684
}
685
}
686
}
687
688
impl_reflect_tuple! {}
689
690
impl_reflect_tuple! {0: A}
691
692
impl_reflect_tuple! {0: A, 1: B}
693
694
impl_reflect_tuple! {0: A, 1: B, 2: C}
695
696
impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D}
697
698
impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E}
699
700
impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E, 5: F}
701
702
impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G}
703
704
impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G, 7: H}
705
706
impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G, 7: H, 8: I}
707
708
impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G, 7: H, 8: I, 9: J}
709
710
impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G, 7: H, 8: I, 9: J, 10: K}
711
712
impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G, 7: H, 8: I, 9: J, 10: K, 11: L}
713
714
macro_rules! impl_type_path_tuple {
715
($(#[$meta:meta])*) => {
716
$(#[$meta])*
717
impl TypePath for () {
718
fn type_path() -> &'static str {
719
"()"
720
}
721
722
fn short_type_path() -> &'static str {
723
"()"
724
}
725
}
726
};
727
728
($(#[$meta:meta])* $param:ident) => {
729
$(#[$meta])*
730
impl <$param: TypePath> TypePath for ($param,) {
731
fn type_path() -> &'static str {
732
use $crate::__macro_exports::alloc_utils::ToOwned;
733
static CELL: GenericTypePathCell = GenericTypePathCell::new();
734
CELL.get_or_insert::<Self, _>(|| {
735
"(".to_owned() + $param::type_path() + ",)"
736
})
737
}
738
739
fn short_type_path() -> &'static str {
740
use $crate::__macro_exports::alloc_utils::ToOwned;
741
static CELL: GenericTypePathCell = GenericTypePathCell::new();
742
CELL.get_or_insert::<Self, _>(|| {
743
"(".to_owned() + $param::short_type_path() + ",)"
744
})
745
}
746
}
747
};
748
749
($(#[$meta:meta])* $last:ident $(,$param:ident)*) => {
750
$(#[$meta])*
751
impl <$($param: TypePath,)* $last: TypePath> TypePath for ($($param,)* $last) {
752
fn type_path() -> &'static str {
753
use $crate::__macro_exports::alloc_utils::ToOwned;
754
static CELL: GenericTypePathCell = GenericTypePathCell::new();
755
CELL.get_or_insert::<Self, _>(|| {
756
"(".to_owned() $(+ $param::type_path() + ", ")* + $last::type_path() + ")"
757
})
758
}
759
760
fn short_type_path() -> &'static str {
761
use $crate::__macro_exports::alloc_utils::ToOwned;
762
static CELL: GenericTypePathCell = GenericTypePathCell::new();
763
CELL.get_or_insert::<Self, _>(|| {
764
"(".to_owned() $(+ $param::short_type_path() + ", ")* + $last::short_type_path() + ")"
765
})
766
}
767
}
768
};
769
}
770
771
all_tuples!(
772
#[doc(fake_variadic)]
773
impl_type_path_tuple,
774
0,
775
12,
776
P
777
);
778
779
#[cfg(feature = "functions")]
780
const _: () = {
781
macro_rules! impl_get_ownership_tuple {
782
($(#[$meta:meta])* $($name: ident),*) => {
783
$(#[$meta])*
784
$crate::func::args::impl_get_ownership!(($($name,)*); <$($name),*>);
785
};
786
}
787
788
all_tuples!(
789
#[doc(fake_variadic)]
790
impl_get_ownership_tuple,
791
0,
792
12,
793
P
794
);
795
796
macro_rules! impl_from_arg_tuple {
797
($(#[$meta:meta])* $($name: ident),*) => {
798
$(#[$meta])*
799
$crate::func::args::impl_from_arg!(($($name,)*); <$($name: FromReflect + MaybeTyped + TypePath + GetTypeRegistration),*>);
800
};
801
}
802
803
all_tuples!(
804
#[doc(fake_variadic)]
805
impl_from_arg_tuple,
806
0,
807
12,
808
P
809
);
810
811
macro_rules! impl_into_return_tuple {
812
($(#[$meta:meta])* $($name: ident),+) => {
813
$(#[$meta])*
814
$crate::func::impl_into_return!(($($name,)*); <$($name: FromReflect + MaybeTyped + TypePath + GetTypeRegistration),*>);
815
};
816
}
817
818
// The unit type (i.e. `()`) is special-cased, so we skip implementing it here.
819
all_tuples!(
820
#[doc(fake_variadic)]
821
impl_into_return_tuple,
822
1,
823
12,
824
P
825
);
826
};
827
828
#[cfg(test)]
829
mod tests {
830
use super::Tuple;
831
832
#[test]
833
fn next_index_increment() {
834
let mut iter = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11).iter_fields();
835
let size = iter.len();
836
iter.index = size - 1;
837
let prev_index = iter.index;
838
assert!(iter.next().is_some());
839
assert_eq!(prev_index, iter.index - 1);
840
841
// When None we should no longer increase index
842
assert!(iter.next().is_none());
843
assert_eq!(size, iter.index);
844
assert!(iter.next().is_none());
845
assert_eq!(size, iter.index);
846
}
847
}
848
849