0

I'm trying to adapt a macro that takes a variable number of type arguments, to a macro that takes a (possibly aliased) tuple type as its last argument:

macro_rules! serialize_individually2 {
  ($ecs:expr, $ser:expr, $data:expr, ($( $type:ty),*)) => {
      $(
      SerializeComponents::<NoError, SimpleMarker<SerializeMe>>::serialize(
          &( $ecs.read_storage::<$type>(), ),
          &$data.0,
          &$data.1,
          &mut $ser,
      )
      .unwrap();
      )*
  };
}

This works on non-aliased tuple types:

serialize_individually2!(ecs, serializer, data, (AreaOfEffect, BlocksTile));

But not on an aliased type:

type TupleComps = (AreaOfEffect, BlocksTile);
serialize_individually2!(ecs, serializer, data, TupleComps);

Is it possible to pattern match and de-alias TupleComps in a Rust macro?

Original question for reference (more generic, not as well thought out): How to store a list of types using a Rust macro?

bbarker
  • 11,636
  • 9
  • 38
  • 62

1 Answers1

1

This is not possible. However, you can create a trait that does the operation for tuples:

trait TupleReadStorage {
    fn read_storage(ecs: &mut Ecs) -> Self;
}

macro_rules! impl_TupleReadStorage {
    ( $first_item_type:ident $(, $rest_item_types:ident)* ) => {
        impl< $first_item_type, $($rest_item_types,)* > TupleReadStorage for ( $first_item_type, $($rest_item_types,)* ) {
            fn read_storage(ecs: &mut Ecs) -> Self {
                (
                    ecs.read_storage::<$first_item_type>(),
                    $( ecs.read_storage::<$rest_item_types>(), )*
                )
            }
        }
        impl_TupleReadStorage!( $($rest_item_types),* );
    };
    () => {
        impl TupleReadStorage for () {
            fn read_storage(_ecs: &mut Ecs) -> Self { () }
        }
    };
}

impl_TupleReadStorage!(A, B, C, D, E, F, G, H, I, J);

Then, use it in the macro:

macro_rules! serialize_individually2 {
    ($ecs:expr, $ser:expr, $data:expr, $type:ty) => {
        $(
            SerializeComponents::<NoError, SimpleMarker<SerializeMe>>::serialize(
                &<$type as TupleReadStorage>::read_storage(&mut $ecs),
                &$data.0,
                &$data.1,
                &mut $ser,
            )
            .unwrap();
        )*
    };
}
Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77