1Macros for all your token pasting needs 2======================================= 3 4[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/paste-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/paste) 5[<img alt="crates.io" src="https://img.shields.io/crates/v/paste.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/paste) 6[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-paste-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/paste) 7[<img alt="build status" src="https://img.shields.io/github/workflow/status/dtolnay/paste/CI/master?style=for-the-badge" height="20">](https://github.com/dtolnay/paste/actions?query=branch%3Amaster) 8 9The nightly-only [`concat_idents!`] macro in the Rust standard library is 10notoriously underpowered in that its concatenated identifiers can only refer to 11existing items, they can never be used to define something new. 12 13[`concat_idents!`]: https://doc.rust-lang.org/std/macro.concat_idents.html 14 15This crate provides a flexible way to paste together identifiers in a macro, 16including using pasted identifiers to define new items. 17 18```toml 19[dependencies] 20paste = "1.0" 21``` 22 23This approach works with any Rust compiler 1.31+. 24 25<br> 26 27## Pasting identifiers 28 29Within the `paste!` macro, identifiers inside `[<`...`>]` are pasted together to 30form a single identifier. 31 32```rust 33use paste::paste; 34 35paste! { 36 // Defines a const called `QRST`. 37 const [<Q R S T>]: &str = "success!"; 38} 39 40fn main() { 41 assert_eq!( 42 paste! { [<Q R S T>].len() }, 43 8, 44 ); 45} 46``` 47 48<br> 49 50## More elaborate example 51 52The next example shows a macro that generates accessor methods for some struct 53fields. It demonstrates how you might find it useful to bundle a paste 54invocation inside of a macro\_rules macro. 55 56```rust 57use paste::paste; 58 59macro_rules! make_a_struct_and_getters { 60 ($name:ident { $($field:ident),* }) => { 61 // Define a struct. This expands to: 62 // 63 // pub struct S { 64 // a: String, 65 // b: String, 66 // c: String, 67 // } 68 pub struct $name { 69 $( 70 $field: String, 71 )* 72 } 73 74 // Build an impl block with getters. This expands to: 75 // 76 // impl S { 77 // pub fn get_a(&self) -> &str { &self.a } 78 // pub fn get_b(&self) -> &str { &self.b } 79 // pub fn get_c(&self) -> &str { &self.c } 80 // } 81 paste! { 82 impl $name { 83 $( 84 pub fn [<get_ $field>](&self) -> &str { 85 &self.$field 86 } 87 )* 88 } 89 } 90 } 91} 92 93make_a_struct_and_getters!(S { a, b, c }); 94 95fn call_some_getters(s: &S) -> bool { 96 s.get_a() == s.get_b() && s.get_c().is_empty() 97} 98``` 99 100<br> 101 102## Case conversion 103 104Use `$var:lower` or `$var:upper` in the segment list to convert an interpolated 105segment to lower- or uppercase as part of the paste. For example, `[<ld_ 106$reg:lower _expr>]` would paste to `ld_bc_expr` if invoked with $reg=`Bc`. 107 108Use `$var:snake` to convert CamelCase input to snake\_case. 109Use `$var:camel` to convert snake\_case to CamelCase. 110These compose, so for example `$var:snake:upper` would give you SCREAMING\_CASE. 111 112The precise Unicode conversions are as defined by [`str::to_lowercase`] and 113[`str::to_uppercase`]. 114 115[`str::to_lowercase`]: https://doc.rust-lang.org/std/primitive.str.html#method.to_lowercase 116[`str::to_uppercase`]: https://doc.rust-lang.org/std/primitive.str.html#method.to_uppercase 117 118<br> 119 120## Pasting documentation strings 121 122Within the `paste!` macro, arguments to a #\[doc ...\] attribute are implicitly 123concatenated together to form a coherent documentation string. 124 125```rust 126use paste::paste; 127 128macro_rules! method_new { 129 ($ret:ident) => { 130 paste! { 131 #[doc = "Create a new `" $ret "` object."] 132 pub fn new() -> $ret { todo!() } 133 } 134 }; 135} 136 137pub struct Paste {} 138 139method_new!(Paste); // expands to #[doc = "Create a new `Paste` object"] 140``` 141 142<br> 143 144#### License 145 146<sup> 147Licensed under either of <a href="LICENSE-APACHE">Apache License, Version 1482.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option. 149</sup> 150 151<br> 152 153<sub> 154Unless you explicitly state otherwise, any contribution intentionally submitted 155for inclusion in this crate by you, as defined in the Apache-2.0 license, shall 156be dual licensed as above, without any additional terms or conditions. 157</sub> 158