<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: dexter</title>
    <description>The latest articles on Forem by dexter (@dexter_76).</description>
    <link>https://forem.com/dexter_76</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1134932%2F45d0f12e-b0c0-49a2-83c8-dfedbbf59580.jpg</url>
      <title>Forem: dexter</title>
      <link>https://forem.com/dexter_76</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dexter_76"/>
    <language>en</language>
    <item>
      <title>starting overview of my new project animal_game</title>
      <dc:creator>dexter</dc:creator>
      <pubDate>Thu, 21 Sep 2023 13:08:34 +0000</pubDate>
      <link>https://forem.com/dexter_76/starting-overview-of-my-new-project-animalgame-19cj</link>
      <guid>https://forem.com/dexter_76/starting-overview-of-my-new-project-animalgame-19cj</guid>
      <description>&lt;p&gt;The goal is to create an ecosystem simulator similar to &lt;a href="https://rainworldgame.com/"&gt;Rainworld&lt;/a&gt;. Maybe turned into a game if I get an idea that wouldn't just copy Rainworld. The main purpose is to learn (however with the ambition to reach a working product). One of the side goals is to find a better name.&lt;/p&gt;

&lt;p&gt;This project currently consists of three repos. The &lt;a href="https://github.com/pgurtner/animal_game"&gt;game/simulator&lt;/a&gt;. The minimalistic &lt;a href="https://github.com/pgurtner/animal_game_engine"&gt;game engine&lt;/a&gt; written in parallel for this project. The &lt;a href="https://github.com/pgurtner/animal_game_ecs_macros"&gt;macros repo&lt;/a&gt; for ECS abstractions.&lt;/p&gt;

&lt;p&gt;I'll try to write blog posts about this project to...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;practice writing in English&lt;/li&gt;
&lt;li&gt;get additional motivation from these little milestones (blog posts about what I did or maybe what my plans are if they're interesting enough for a post)&lt;/li&gt;
&lt;li&gt;to be forced to think through ideas well enough to be able to explain them&lt;/li&gt;
&lt;li&gt;the tutorial style posts maybe will help someone (like &lt;a href="https://dev.to/dexter_76/how-to-abstract-away-library-interfaces-working-directly-through-syntax-in-rust-with-procedural-macros-3pgm"&gt;this one&lt;/a&gt; that's actually the first post about this software project) and the rest might be interesting to read&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  some technical aspects
&lt;/h2&gt;

&lt;p&gt;This project will use &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rust, because I want to further learn the language, my experience is limited to reading the book and an unfinished tetris game&lt;/li&gt;
&lt;li&gt;the Entity Component System pattern, I'm intrigued by the concept and want to try it &lt;/li&gt;
&lt;li&gt;a minimalistic &lt;a href="https://github.com/pgurtner/animal_game_engine"&gt;game engine&lt;/a&gt; written in parallel that's build on top of &lt;a href="https://docs.rs/ggez/latest/ggez/"&gt;ggez&lt;/a&gt;, I want to learn how to implement the physics part of a game and I already used ggez. ggez is just there for the fundamental parts like game loop or drawing graphics, the rest is something I want to learn myself.&lt;/li&gt;
&lt;li&gt;decentralized algorithms for animal behaviour, I'm currently very interested in decentralized, self-correcting, etc. systems/algorithms/... and want to learn about it (this was the main reason why this project idea won against others)&lt;/li&gt;
&lt;li&gt;clean code and architecture, I've read about these concepts in multiple books by Robert C. Martin, but until now only used it to rewrite my last project in the middle of development which turned it from pure hell to something nice, this time I want to create a clean system from the start&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In terms of software architecture (especially interfaces), my current approach is to look at what I need right now (and maybe in the not so distant future) and built it in a way that enables future extensions and easy switching of components. With that I hope I don't get into perfectionistic planning hell while ensuring a clean architecture. Let's see how this approach will develop and how/whether it will work.&lt;/p&gt;

&lt;h2&gt;
  
  
  current plans for the game engine
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;graphics: 

&lt;ul&gt;
&lt;li&gt;draw various objects including abstract ones (light, fluids)&lt;/li&gt;
&lt;li&gt;varying window sizes&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;physics:

&lt;ul&gt;
&lt;li&gt;applying forces: hitting, throwing, grabbing&lt;/li&gt;
&lt;li&gt;dynamic vs. static objects&lt;/li&gt;
&lt;li&gt;fluids&lt;/li&gt;
&lt;li&gt;friction (no idea if friction is doable or how to do it, in school this thing did not exist, I have no idea about it)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;animal bodies:

&lt;ul&gt;
&lt;li&gt;bone system for movements&lt;/li&gt;
&lt;li&gt;body rendering that uses individual body parts instead of whole sprites&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  current plans and ideas for the game/simulation
&lt;/h2&gt;

&lt;p&gt;The game itself is about visualizing animals and environment and (the main part) animal behaviour.&lt;br&gt;
The current ideas include (not exhaustive, a lot taken from Rainworld):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;basic senses: seeing, hearing, touching?, smelling?&lt;/li&gt;
&lt;li&gt;basic reflexes: attack vs. run, hunting/eating&lt;/li&gt;
&lt;li&gt;more complex behaviour

&lt;ul&gt;
&lt;li&gt;personality: small set of fundamental characteristic aspects that influence the behaviour. E.g. impulsiveness, willingness to take risks&lt;/li&gt;
&lt;li&gt;social memory: remembering interactions with others to cause things like rivalry, groups, etc. (maybe even revenge)&lt;/li&gt;
&lt;li&gt;dynamic food chain position: no fixed positions, a worm should in theory be able to kill a giant somehow&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;somehow evolution (not sure if some parts are doable)

&lt;ul&gt;
&lt;li&gt;implement mating and giving birth functionality (the foundation for evolution)&lt;/li&gt;
&lt;li&gt;newborns get a mix of their parents' personality with some randomness&lt;/li&gt;
&lt;li&gt;try to make physical appearance affected by evolution&lt;/li&gt;
&lt;li&gt;try to make dynamically developed instincts&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>How to abstract away library interfaces working directly through syntax in Rust with procedural macros</title>
      <dc:creator>dexter</dc:creator>
      <pubDate>Thu, 21 Sep 2023 11:41:32 +0000</pubDate>
      <link>https://forem.com/dexter_76/how-to-abstract-away-library-interfaces-working-directly-through-syntax-in-rust-with-procedural-macros-3pgm</link>
      <guid>https://forem.com/dexter_76/how-to-abstract-away-library-interfaces-working-directly-through-syntax-in-rust-with-procedural-macros-3pgm</guid>
      <description>&lt;p&gt;In this post I describe how I wrote two macros to separate the &lt;a href="https://docs.rs/bevy_ecs/latest/bevy_ecs/"&gt;bevy_ecs&lt;/a&gt; interface from my app core even though bevy_ecs' system interface works directly via the function syntax. &lt;br&gt;
This isn't a complete tutorial for Rust's syn and quote libraries, the Entity Component System pattern or Rust macros. I won't explain every struct that I use. Read the library documentations for that.&lt;/p&gt;

&lt;p&gt;You can find my source code &lt;a href="https://github.com/pgurtner/animal_game_ecs_macros"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  general info about procedural macros
&lt;/h2&gt;

&lt;p&gt;In both cases I'm using procedural macros to remain flexible. With bevy_ecs a derive Component macro would probably suffice, but some ECS libraries presumably use another way which would cause problems if I tried to switch to them.&lt;/p&gt;

&lt;p&gt;Procedural macros get two token streams (one for the macro arguments like &lt;code&gt;Debug&lt;/code&gt; in &lt;code&gt;#[derive(Debug)]&lt;/code&gt;, one for the block that has the macro) and return one (the code that replaces the code block which is affected by the macro). They look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[proc_macro_attribute]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;macro_name&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TokenStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TokenStream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;TokenStream&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I haven't used macro arguments yet, so I won't describe them.&lt;/p&gt;

&lt;p&gt;To parse the incoming token streams into something usable like a token tree, Rust offers the &lt;a href="https://docs.rs/syn/latest/syn/"&gt;syn&lt;/a&gt; package. For the opposite direction Rust offers the &lt;a href="https://docs.rs/quote/latest/quote/"&gt;quote&lt;/a&gt; package.&lt;/p&gt;

&lt;p&gt;To get from the token stream to a token tree, syn has multiple parsing macros. I used &lt;code&gt;parse_macro_input!&lt;/code&gt;. The main difference to the others is that &lt;code&gt;parse_macro_input!&lt;/code&gt; enforces what type of syntax block you get. E.g. &lt;code&gt;parse_quote!&lt;/code&gt; just parses any string.&lt;br&gt;
A call would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;parsed_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;parse_macro_input!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;ItemStruct&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case my custom macro is expecting a struct. I parse the &lt;code&gt;input&lt;/code&gt; parameter to &lt;code&gt;ItemStruct&lt;/code&gt; and &lt;code&gt;parse_macro_input!&lt;/code&gt; checks if &lt;code&gt;input&lt;/code&gt; actually is a struct and returns an &lt;code&gt;ItemStruct&lt;/code&gt; instance. &lt;code&gt;ItemStruct&lt;/code&gt; is a normal Rust struct provided by syn that can be nicely worked with!&lt;/p&gt;

&lt;p&gt;After you've edited your token tree or created a new one you have to create a new token stream that will be the output of the custom macro. There are multiple ways for different scenarios.&lt;br&gt;
The most simple one is using the &lt;code&gt;quote!&lt;/code&gt; macro.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;parsed_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;something_that_implements_ToTokens&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;input_struct_identifier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;again_something_that_implements_ToTokens&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;new_tokenstream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;quote!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    #&lt;span class="n"&gt;parsed_input&lt;/span&gt;

    &lt;span class="k"&gt;impl&lt;/span&gt; #&lt;span class="n"&gt;input_struct_identifier&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;im_just_here_to_show_what_quote_can_do&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100_00&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In &lt;code&gt;quote!&lt;/code&gt; you can directly write Rust syntax and use variables that implement the &lt;code&gt;ToTokens&lt;/code&gt; trait (&lt;code&gt;parsed_input&lt;/code&gt; and &lt;code&gt;input_struct_identifier&lt;/code&gt; in this example). &lt;code&gt;quote!&lt;/code&gt; substitutes these variables with their token streams.&lt;br&gt;
The example above could produce a token stream resembling something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;SomeStruct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;SomeStruct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;im_just_here_to_show_what_quote_can_do&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100_00&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, if you created a struct that already implements the &lt;code&gt;ToToken&lt;/code&gt; trait you can directly parse it into a token stream.&lt;br&gt;
E.g. like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;item_struct&lt;/span&gt;&lt;span class="nf"&gt;.into_token_stream&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  component macro
&lt;/h2&gt;

&lt;p&gt;The component macro is rather simple. bevy_ecs uses the same style that I want, so the macro simply adds a &lt;code&gt;#[derive(bevy_ecs::component::Component)]&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;expanded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;quote!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;#[derive(bevy_ecs::component::Component)]&lt;/span&gt;
    #&lt;span class="n"&gt;input&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is probably a way to add the derive macro in the &lt;code&gt;ItemStruct&lt;/code&gt; instance, but I didn't try that.&lt;/p&gt;

&lt;h2&gt;
  
  
  system macro
&lt;/h2&gt;

&lt;p&gt;The system macro is far more complex and interesting.&lt;br&gt;
In general, I want my system functions like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[system]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;some_system&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ComponentA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;ComponentB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//a,b and entity are used here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;bevy_ecs on the other hand, uses this style:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;some_system&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ComponentA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;ComponentB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//a, b and entity are used here&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This has quite some syntax overhead that I don't like. Thus, I combined keeping dependencies away from my program with getting an interface more of my liking.&lt;/p&gt;

&lt;p&gt;This comparison already shows how the token stream input looks like and how the output is supposed to be.&lt;/p&gt;

&lt;p&gt;The macro can be seperated in creating a new function signature and creating the for loop. Then you create a new function that copies all the other properties from the old function and insert the new signature and new function body.&lt;br&gt;
It could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;create_fn_item&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ItemFn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ItemFn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TokenStream&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;new_sig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_new_sig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="py"&gt;.sig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;for_loop_stmts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_new_loop_stmts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;new_fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ItemFn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="py"&gt;.attrs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// attributes like #[repr(transparent)]&lt;/span&gt;
        &lt;span class="n"&gt;vis&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="py"&gt;.vis&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// visibility&lt;/span&gt;
        &lt;span class="n"&gt;sig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;new_sig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// signature&lt;/span&gt;
        &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;syn&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Block&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// function body&lt;/span&gt;
            &lt;span class="n"&gt;brace_token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;stmts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;for_loop_stmts&lt;/span&gt;
        &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_fn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I won't explain the steps for the signature and the for loop in detail because it would mainly be copying source code and writing some redundant comment. My biggest advise is to parse the structures you want and print them to the console. Then look how they are build up and combined with the syn documentation build your wanted syntax structures. You can use my &lt;a href="https://github.com/pgurtner/animal_game_ecs_macros/blob/main/src/bevy_system.rs"&gt;source code&lt;/a&gt; as an example.&lt;/p&gt;

&lt;h2&gt;
  
  
  debugging procedural macros
&lt;/h2&gt;

&lt;p&gt;Currently procedural macros can only be executed in their default way with &lt;code&gt;#macro_name&lt;/code&gt;, even though they're just special functions. This means quite some problems for debugging because macros are executed at compile time. There are some debugging options but not a usual IDE debugger.&lt;br&gt;
However, there is a workaround for that. The library &lt;a href="https://docs.rs/proc-macro2/latest/proc_macro2/"&gt;proc_macro2&lt;/a&gt;. This is a wrapper around the procedural macro API, and it can be used outside a procedural macro. That means you can outsource your macro logic into plain functions and call these from your macro. The actual macro only does the initial syntax parsing, the conversion between proc_macro and proc_macro2 and calls the outsourced function. Because the latter is a plain and normal Rust function, you can unit test it or do whatever else you want.&lt;br&gt;
This is an example how it might look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[proc_macro_attribute]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;to_bevy_component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="n"&gt;_args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TokenStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TokenStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;TokenStream&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;parse_macro_input!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;ItemStruct&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;bevy_component&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;to_bevy_component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nn"&gt;proc_macro&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;TokenStream&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;to_bevy_component&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ItemStruct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;proc_macro2&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;TokenStream&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;expanded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;quote!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;#[derive(bevy_ecs::component::Component)]&lt;/span&gt;
        #&lt;span class="n"&gt;input&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;expanded&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[cfg(test)]&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  throwing errors in procedural macros
&lt;/h2&gt;

&lt;p&gt;In case I mess up and use a macro on some invalid syntax thing I wanted error management via &lt;code&gt;Result&lt;/code&gt; like usual. This doesn't mean syntactical problems but e.g. some syntax thing that isn't supposed to appear in the syntax things affected by the macro and that I therefore don't want to have to handle.&lt;br&gt;
You can do it quite easily. You just have to create a &lt;code&gt;syn::Error&lt;/code&gt;, call &lt;code&gt;.into_compile_error()&lt;/code&gt; on it, parse it into a token stream and return it from your macro. For Rust to be able to determine the right spot that caused the error, you have to get the correct span. A span is some part of your parsed code that starts and ends somewhere. Usually you can get it from the syn structs.&lt;/p&gt;

&lt;p&gt;I used this technique to exclude self parameters, because systems will never be associated to a struct (or at least don't offer any additional value than normal functions).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;fn_arg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nn"&gt;FnArg&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Receiver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rec&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nn"&gt;syn&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rec&lt;/span&gt;&lt;span class="py"&gt;.self_token.span&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"systems can't have a self parameter"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="nf"&gt;.into_compile_error&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>rust</category>
      <category>cleancode</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
