use specs::join::Join; struct Pos { x: usize, } impl specs::Component for Pos { type Storage = specs::VecStorage; } struct Mov; impl specs::Component for Mov { type Storage = specs::VecStorage; } macro_rules! system { ($name:ident $pat:tt => $block:block ) => { struct $name; impl<'a> specs::System<'a> for $name { type SystemData = args_to_systemdata!($pat); fn run(&mut self, args_to_pat!($pat): Self::SystemData) { for args_to_pat!($pat) in (args_to_join!($pat)).join() { $block } } } }; } macro_rules! args_to_systemdata { ( ( $( $name:ident : $ty: ty ),* ) ) => { ( $( specs::WriteStorage<'a, $ty> ),* ) } } macro_rules! args_to_pat { ( ( $( $name:ident : $ty: ty ),* ) ) => { ( $( mut $name ),* ) } } macro_rules! args_to_join { ( ( $( $name:ident : $ty: ty ),* ) ) => { ( $( &mut $name ),* ) } } system!{ Foo (_x: Mov, y: Pos) => { y.x += 1; } } #[cfg(test)] mod tests { #[test] fn it_works() { assert_eq!(2 + 2, 4); } }