use super::{Reflect, ReflectRef, ReflectMut}; pub trait Tuple: Reflect { fn item_at(&self, idx: usize) -> Option<&dyn Reflect>; fn item_at_mut(&mut self, idx: usize) -> Option<&mut dyn Reflect>; fn items_len(&self) -> usize; } macro_rules! impl_reflect_tuple { ( $count: tt, $( ($name: ident, $idx: tt) ),+ ) => ( impl<$($name: Reflect + Clone),+> Reflect for ($($name,)+) { fn name(&self) -> String { std::any::type_name::().to_string() } fn type_id(&self) -> std::any::TypeId { std::any::TypeId::of::() } fn as_any(&self) -> &dyn std::any::Any { self } fn as_any_mut(&mut self) -> &mut dyn std::any::Any { self } fn apply(&mut self, val: &dyn Reflect) { let val = val.as_any().downcast_ref::() .expect("The type of `val` is not the same as `self`"); *self = val.clone(); } fn clone_inner(&self) -> Box { Box::new(self.clone()) } fn reflect_ref(&self) -> ReflectRef { ReflectRef::Tuple(self) } fn reflect_mut(&mut self) -> ReflectMut { ReflectMut::Tuple(self) } fn reflect_val(&self) -> &dyn Reflect { self } fn reflect_val_mut(&mut self) -> &mut dyn Reflect { self } } impl<$($name: Reflect + Clone,)+> Tuple for ($($name,)+) { fn item_at(&self, at_idx: usize) -> Option<&dyn Reflect> { match at_idx { $( $idx => Some(&self.$idx), )+ _ => None, } } fn item_at_mut(&mut self, at_idx: usize) -> Option<&mut dyn Reflect> { match at_idx { $( $idx => Some(&mut self.$idx), )+ _ => None, } } fn items_len(&self) -> usize { $count } } ); } // this is absolute cancer, but I can't be asked to make something nicer looking impl_reflect_tuple!(1, (A, 0) ); impl_reflect_tuple!(2, (A, 0), (B, 1) ); impl_reflect_tuple!(3, (A, 0), (B, 1), (C, 2) ); impl_reflect_tuple!(4, (A, 0), (B, 1), (C, 2), (D, 3) ); impl_reflect_tuple!(5, (A, 0), (B, 1), (C, 2), (D, 3), (E, 4) ); impl_reflect_tuple!(6, (A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5) ); impl_reflect_tuple!(7, (A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6) ); impl_reflect_tuple!(8, (A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6), (H, 7) ); impl_reflect_tuple!(9, (A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6), (H, 7), (I, 8) ); impl_reflect_tuple!(10, (A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6), (H, 7), (I, 8), (J, 9) ); impl_reflect_tuple!(11, (A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6), (H, 7), (I, 8), (J, 9), (K, 10) ); impl_reflect_tuple!(12, (A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6), (H, 7), (I, 8), (J, 9), (K, 10), (L, 11) ); impl_reflect_tuple!(13, (A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6), (H, 7), (I, 8), (J, 9), (K, 10), (L, 11), (M, 12) ); impl_reflect_tuple!(14, (A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6), (H, 7), (I, 8), (J, 9), (K, 10), (L, 11), (M, 12), (N, 13) ); impl_reflect_tuple!(15, (A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6), (H, 7), (I, 8), (J, 9), (K, 10), (L, 11), (M, 12), (N, 13), (O, 14) ); impl_reflect_tuple!(16, (A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6), (H, 7), (I, 8), (J, 9), (K, 10), (L, 11), (M, 12), (N, 13), (O, 14), (P, 15) );