Expand description
The nightly-onlyconcat_idents!
macro in the Rust standard library isnotoriously underpowered in that its concatenated identifiers can only refer toexisting items, they can never be used to define something new.
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 Rust compiler 1.31+.
§Pasting identifiers
Within thepaste!
macro, identifiers inside[<
…>]
are pastedtogether to form a single identifier.
usepaste::paste;paste! {// Defines a const called `QRST`.const[<Q R S T>]:&str ="success!";}fnmain() {assert_eq!(paste! { [<Q R S T>].len() },8, );}
§More elaborate example
The next example shows a macro that generates accessor methods for somestruct fields. It demonstrates how you might find it useful to bundle apaste invocation inside of a macro_rules macro.
usepaste::paste;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! {impl$name{ $(pub fn[<get_$field>](&self) ->&str {&self.$field} )* } } }}make_a_struct_and_getters!(S { a, b, c });fncall_some_getters(s:&S) -> bool { s.get_a() == s.get_b() && s.get_c().is_empty()}
§Case conversion
Use$var:lower
or$var:upper
in the segment list to convert aninterpolated segment to lower- or uppercase as part of the paste. Forexample,[<ld_ $reg:lower _expr>]
would paste told_bc_expr
if invokedwith $reg=Bc
.
Use$var:snake
to convert CamelCase input to snake_case.Use$var:camel
to convert snake_case to CamelCase.These compose, so for example$var:snake:upper
would give you SCREAMING_CASE.
The precise Unicode conversions are as defined bystr::to_lowercase
andstr::to_uppercase
.
§Pasting documentation strings
Within thepaste!
macro, arguments to a #[doc …] attribute areimplicitly concatenated together to form a coherent documentation string.
usepaste::paste;macro_rules! method_new { ($ret:ident) => {paste! {#[doc ="Create a new `"$ret"` object."]pub fnnew() ->$ret{todo!() } } };}pub structPaste {}method_new!(Paste);// expands to #[doc = "Create a new `Paste` object"]