Expansion de constantes en français

Nous souhaitons créer une macro procédurale french qui remplacera un nombre litéral (une constante) par sa représentation textuelle en français lors de la compilation. Par exemple, le code suivant

  println!("1000 + 230 = {}", french!(1230));

affichera

1000 + 230 = mille-deux-cent-trente (1230)

Nous nous aiderons pour cela de l'excellent crate french-numbers.

  1. Ajoutez le crate french-numbers aux dépendances du projet macros. Notons que nous ne l'ajouterons pas aux dépendances du projet pwdchk car tout se passera lors de la compilation.

  2. Créez dans src/lib.rs du projet macros une fonction french avec l'attribut #[proc_macro] avec la signature correspondant à une macro procédurale :

extern crate proc_macro;

#[proc_macro]
pub fn french(item: TokenStream) -> TokenStream {
  item
}

Étant donné que proc_macro est fourni par le compilateur et pas ajouté explicitement dans nos dépendances, il faut l'importer avec extern crate proc_macro.

Pour l'instant, notre macro ne fait rien. Nous pouvons le vérifier en important macros::french dans notre programme pwdchk et en recopiant le println!() ci-dessus dans notre programme principal.

Il faut maintenant remplir notre fonction french. En vous aidant des exemples du cours, effectuez les étapes suivantes :

  1. Parsez le flux d'entrée sous la forme d'un LitInt qui représente un entier litéral grâce à la macro idione qui vient du crate syn.
  2. Parsez cet entier litéral, et en cas de succès, construisez la chaîne de caractères contenant sa représentation en français suivi de sa valeur entre parenthèses. Vous pouvez ensuite construire un proc_macro2::TokenStream en utilisant la macro quote du crate éponyme et le convertir en proc_macro::TokenStream avec into().
  3. En cas d'erreur lors de l'étape précédente, insérez avec la macro quote_spanned du crate quote une invocation de la macro compile_error expliquant que la macro french ne fonctionne qu'avec un entier litéral.

Bravo, vous avez créé votre première macro procédurale. Vérifiez qu'elle fonctionne comme attendu.