1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
//! The nightly-only [`concat_idents!`] macro in the Rust standard library is //! notoriously underpowered in that its concatenated identifiers can only refer to //! existing items, they can never be used to define something new. //! //! [`concat_idents!`]: https://doc.rust-lang.org/std/macro.concat_idents.html //! //! This crate provides a flexible way to paste together identifiers in a macro, //! including using pasted identifiers to define new items. //! //! This approach works with any stable or nightly Rust compiler 1.30+. //! //! # Pasting identifiers //! //! There are two entry points, `paste::expr!` for macros in expression position and //! `paste::item!` for macros in item position. //! //! Within either one, identifiers inside `[<`...`>]` are pasted together to form a //! single identifier. //! //! ``` //! // Macro in item position: at module scope or inside of an impl block. //! paste::item! { //! // Defines a const called `QRST`. //! const [<Q R S T>]: &str = "success!"; //! } //! //! fn main() { //! // Macro in expression position: inside a function body. //! assert_eq!( //! paste::expr! { [<Q R S T>].len() }, //! 8, //! ); //! } //! ``` //! //! # More elaborate examples //! //! This program demonstrates how you may want to bundle a paste invocation inside //! of a more convenient user-facing macro of your own. Here the `routes!(A, B)` //! macro expands to a vector containing `ROUTE_A` and `ROUTE_B`. //! //! ``` //! const ROUTE_A: &str = "/a"; //! const ROUTE_B: &str = "/b"; //! //! macro_rules! routes { //! ($($route:ident),*) => {{ //! paste::expr! { //! vec![$( [<ROUTE_ $route>] ),*] //! } //! }} //! } //! //! fn main() { //! let routes = routes!(A, B); //! assert_eq!(routes, vec!["/a", "/b"]); //! } //! ``` //! //! The next example shows a macro that generates accessor methods for some struct //! fields. //! //! ``` //! macro_rules! make_a_struct_and_getters { //! ($name:ident { $($field:ident),* }) => { //! // Define a struct. This expands to: //! // //! // pub struct S { //! // a: String, //! // b: String, //! // c: String, //! // } //! pub struct $name { //! $( //! $field: String, //! )* //! } //! //! // Build an impl block with getters. This expands to: //! // //! // impl S { //! // pub fn get_a(&self) -> &str { &self.a } //! // pub fn get_b(&self) -> &str { &self.b } //! // pub fn get_c(&self) -> &str { &self.c } //! // } //! paste::item! { //! impl $name { //! $( //! pub fn [<get_ $field>](&self) -> &str { //! &self.$field //! } //! )* //! } //! } //! } //! } //! //! make_a_struct_and_getters!(S { a, b, c }); //! //! fn call_some_getters(s: &S) -> bool { //! s.get_a() == s.get_b() && s.get_c().is_empty() //! } //! # //! # fn main() {} //! ``` #![no_std] use proc_macro_hack::proc_macro_hack; /// Paste identifiers within a macro invocation that expands to an expression. #[proc_macro_hack] pub use paste_impl::expr; /// Paste identifiers within a macro invocation that expands to one or more /// items. /// /// An item is like a struct definition, function, impl block, or anything else /// that can appear at the top level of a module scope. pub use paste_impl::item; /// Paste identifiers within a macro invocation that expands to one or more /// macro_rules macros or items containing macros. pub use paste_impl::item_with_macros; #[doc(hidden)] pub use paste_impl::EnumHack;