Rust macros from a beginner point of view

This tracks what I understood writting my first real rust macro.

The goal was to simplify creating test data while writting a text adventure game framework of library in Rust.

The model is a simplifier first version of what I want achieve later. It starts with just a Book that contains Chapters, the Chapters have an Id, their own text, plus a list of Choices that associate some descriptions to the Id of the chapter that must be read if the player make that choice.

The current allows writting this:

#![allow(unused)]
fn main() {
let l = livre![ //.
    chapter_one_id: {                         // This is a chapter
        "text of chapter one",                // This is the text of the chapter
        chapter_one_id: "Make choice one",    // This is a choice
        chapter_two_id: "Make choice two",
        chapter_three_id: "Make choice three"
    },
    chapter_two_id: {
        "texte du chapitre deux",
        chapter_two_id: "Make choice one"
    },
    chapter_three_id: {
        "texte du chapitre trois",
        chapter_three_id: "Make choice one"
    }
];
}

instead of this:

#![allow(unused)]
fn main() {
let l = Livre {
    chapitres: HashMap::from([
        (
            "chapter_one_id".into(),
            Chapitre {
                texte: "text of chapter one".into(),
                choix: vec![
                    ("chapter_one_id".into(), "Make choice one".into()),
                    ("chapter_two_id".into(), "Make choice two".into()),
                    ("chapter_three_id".into(), "Make choice three".into()),
                ],
            },
        ),
        (
            "chapter_two_id".into(),
            Chapitre {
                texte: "text of chapter two".into(),
                choix: vec![("chapter_one_id".into(), "Make choice one".into()),],
            },
        ),
        (
            "chapter_three_id".into(),
            Chapitre {
                texte: "text of chapter three".into(),
                choix: vec![("chapter_three_id".into(), "Make choice one".into()),],
            },
        ),
    ]),
};
}

The original code is available on this version of the code.

development environnement

I used:

    $ rustc --version
    rustc 1.84.0-nightly (03ee48451 2024-11-18)

the choice! macro

I tried to start with a macro to generate Chapters, but this one hade two separate problems since the pattern for Choices and the text of the chapter where a bit different.

After some attempts, I simplified the problem by starting writting a macro for choices only.

It is used like this:

#![allow(unused)]
fn main() {
choice! 
  { //.
      id_chapter_one: "Make first choice",
      id_chapter_three: "Make second choice",
  };
}

and produces a code Rust code eauivalent to:

#![allow(unused)]
fn main() {
vec![
    ("id_chapter_one".into(), "Make first choice".into()),
    ("id_chapter_three".into(), "Make second choice".into()),
]
}

truvc dont il faut parler :

  • stringify!()
  • comment il arrive a trouver le type du into() et comment j'ai pu virer le String::from() -la macro peut s'appeler avec des crochet ou des accolades aussi (q: peut on faire des matchings differents pour les trois cas ?)