README.md
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 = "0.1"
21```
22
23This approach works with any stable or nightly Rust compiler 1.30+.
24
25<br>
26
27## Pasting identifiers
28
29There are two entry points, `paste::expr!` for macros in expression position and
30`paste::item!` for macros in item position.
31
32Within either one, identifiers inside `[<`...`>]` are pasted together to form a
33single identifier.
34
35```rust
36// Macro in item position: at module scope or inside of an impl block.
37paste::item! {
38 // Defines a const called `QRST`.
39 const [<Q R S T>]: &str = "success!";
40}
41
42fn main() {
43 // Macro in expression position: inside a function body.
44 assert_eq!(
45 paste::expr! { [<Q R S T>].len() },
46 8,
47 );
48}
49```
50
51<br>
52
53## More elaborate examples
54
55This program demonstrates how you may want to bundle a paste invocation inside
56of a more convenient user-facing macro of your own. Here the `routes!(A, B)`
57macro expands to a vector containing `ROUTE_A` and `ROUTE_B`.
58
59```rust
60const ROUTE_A: &str = "/a";
61const ROUTE_B: &str = "/b";
62
63macro_rules! routes {
64 ($($route:ident),*) => {{
65 paste::expr! {
66 vec![$( [<ROUTE_ $route>] ),*]
67 }
68 }}
69}
70
71fn main() {
72 let routes = routes!(A, B);
73 assert_eq!(routes, vec!["/a", "/b"]);
74}
75```
76
77The next example shows a macro that generates accessor methods for some struct
78fields.
79
80```rust
81macro_rules! make_a_struct_and_getters {
82 ($name:ident { $($field:ident),* }) => {
83 // Define a struct. This expands to:
84 //
85 // pub struct S {
86 // a: String,
87 // b: String,
88 // c: String,
89 // }
90 pub struct $name {
91 $(
92 $field: String,
93 )*
94 }
95
96 // Build an impl block with getters. This expands to:
97 //
98 // impl S {
99 // pub fn get_a(&self) -> &str { &self.a }
100 // pub fn get_b(&self) -> &str { &self.b }
101 // pub fn get_c(&self) -> &str { &self.c }
102 // }
103 paste::item! {
104 impl $name {
105 $(
106 pub fn [<get_ $field>](&self) -> &str {
107 &self.$field
108 }
109 )*
110 }
111 }
112 }
113}
114
115make_a_struct_and_getters!(S { a, b, c });
116
117fn call_some_getters(s: &S) -> bool {
118 s.get_a() == s.get_b() && s.get_c().is_empty()
119}
120```
121
122<br>
123
124## Case conversion
125
126Use `$var:lower` or `$var:upper` in the segment list to convert an interpolated
127segment to lower- or uppercase as part of the paste. For example, `[<ld_
128$reg:lower _expr>]` would paste to `ld_bc_expr` if invoked with $reg=`Bc`.
129
130Use `$var:snake` to convert CamelCase input to snake\_case.
131Use `$var:camel` to convert snake\_case to CamelCase.
132These compose, so for example `$var:snake:upper` would give you SCREAMING\_CASE.
133
134The precise Unicode conversions are as defined by [`str::to_lowercase`] and
135[`str::to_uppercase`].
136
137[`str::to_lowercase`]: https://doc.rust-lang.org/std/primitive.str.html#method.to_lowercase
138[`str::to_uppercase`]: https://doc.rust-lang.org/std/primitive.str.html#method.to_uppercase
139
140<br>
141
142#### License
143
144<sup>
145Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
1462.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
147</sup>
148
149<br>
150
151<sub>
152Unless you explicitly state otherwise, any contribution intentionally submitted
153for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
154be dual licensed as above, without any additional terms or conditions.
155</sub>
156