1 #![allow(clippy::let_underscore_untyped)]
2
3 use paste::paste;
4
5 #[test]
test_shared_hygiene()6 fn test_shared_hygiene() {
7 paste! {
8 let [<a a>] = 1;
9 assert_eq!([<a a>], 1);
10 }
11 }
12
13 #[test]
test_repeat()14 fn test_repeat() {
15 const ROCKET_A: &str = "/a";
16 const ROCKET_B: &str = "/b";
17
18 macro_rules! routes {
19 ($($route:ident),*) => {{
20 paste! {
21 vec![$( [<ROCKET_ $route>] ),*]
22 }
23 }}
24 }
25
26 let routes = routes!(A, B);
27 assert_eq!(routes, vec!["/a", "/b"]);
28 }
29
30 #[test]
test_literal_to_identifier()31 fn test_literal_to_identifier() {
32 const CONST0: &str = "const0";
33
34 let pasted = paste!([<CONST 0>]);
35 assert_eq!(pasted, CONST0);
36
37 let pasted = paste!([<CONST '0'>]);
38 assert_eq!(pasted, CONST0);
39
40 let pasted = paste!([<CONST "0">]);
41 assert_eq!(pasted, CONST0);
42
43 let pasted = paste!([<CONST r"0">]);
44 assert_eq!(pasted, CONST0);
45
46 let pasted = paste!([<CONST '\u{30}'>]);
47 assert_eq!(pasted, CONST0);
48 }
49
50 #[test]
test_literal_suffix()51 fn test_literal_suffix() {
52 macro_rules! literal {
53 ($bit:tt) => {
54 paste!([<1_u $bit>])
55 };
56 }
57
58 assert_eq!(literal!(32), 1);
59 }
60
61 #[test]
test_underscore()62 fn test_underscore() {
63 paste! {
64 const A_B: usize = 0;
65 assert_eq!([<A _ B>], 0);
66 }
67 }
68
69 #[test]
test_lifetime()70 fn test_lifetime() {
71 paste! {
72 #[allow(dead_code)]
73 struct S<[<'d e>]> {
74 q: &[<'d e>] str,
75 }
76 }
77 }
78
79 #[test]
test_keyword()80 fn test_keyword() {
81 paste! {
82 struct [<F move>];
83
84 let _ = Fmove;
85 }
86 }
87
88 #[test]
test_literal_str()89 fn test_literal_str() {
90 paste! {
91 #[allow(non_camel_case_types)]
92 struct [<Foo "Bar-Baz">];
93
94 let _ = FooBar_Baz;
95 }
96 }
97
98 #[test]
test_env_literal()99 fn test_env_literal() {
100 paste! {
101 struct [<Lib env bar>];
102
103 let _ = Libenvbar;
104 }
105 }
106
107 #[test]
test_env_present()108 fn test_env_present() {
109 paste! {
110 struct [<Lib env!("CARGO_PKG_NAME")>];
111
112 let _ = Libpaste;
113 }
114 }
115
116 #[test]
test_raw_identifier()117 fn test_raw_identifier() {
118 paste! {
119 struct [<F r#move>];
120
121 let _ = Fmove;
122 }
123 }
124
125 #[test]
test_false_start()126 fn test_false_start() {
127 trait Trait {
128 fn f() -> usize;
129 }
130
131 struct S;
132
133 impl Trait for S {
134 fn f() -> usize {
135 0
136 }
137 }
138
139 paste! {
140 let x = [<S as Trait>::f()];
141 assert_eq!(x[0], 0);
142 }
143 }
144
145 #[test]
test_local_variable()146 fn test_local_variable() {
147 let yy = 0;
148
149 paste! {
150 assert_eq!([<y y>], 0);
151 }
152 }
153
154 #[test]
test_empty()155 fn test_empty() {
156 paste! {
157 assert_eq!(stringify!([<y y>]), "yy");
158 assert_eq!(stringify!([<>]).replace(' ', ""), "[<>]");
159 }
160 }
161
162 #[test]
test_env_to_lower()163 fn test_env_to_lower() {
164 paste! {
165 struct [<Lib env!("CARGO_PKG_NAME"):lower>];
166
167 let _ = Libpaste;
168 }
169 }
170
171 #[test]
test_env_to_upper()172 fn test_env_to_upper() {
173 paste! {
174 const [<LIB env!("CARGO_PKG_NAME"):upper>]: &str = "libpaste";
175
176 let _ = LIBPASTE;
177 }
178 }
179
180 #[test]
test_env_to_snake()181 fn test_env_to_snake() {
182 paste! {
183 const [<LIB env!("CARGO_PKG_NAME"):snake:upper>]: &str = "libpaste";
184
185 let _ = LIBPASTE;
186 }
187 }
188
189 #[test]
test_env_to_camel()190 fn test_env_to_camel() {
191 paste! {
192 #[allow(non_upper_case_globals)]
193 const [<LIB env!("CARGO_PKG_NAME"):camel>]: &str = "libpaste";
194
195 let _ = LIBPaste;
196 }
197 }
198
199 mod test_x86_feature_literal {
200 // work around https://github.com/rust-lang/rust/issues/72726
201
202 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
203 macro_rules! my_is_x86_feature_detected {
204 ($feat:literal) => {
205 use paste::paste;
206
207 paste! {
208 #[test]
209 fn test() {
210 let _ = is_x86_feature_detected!($feat);
211 }
212 }
213 };
214 }
215
216 #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
217 macro_rules! my_is_x86_feature_detected {
218 ($feat:literal) => {
219 #[ignore]
220 #[test]
221 fn test() {}
222 };
223 }
224
225 my_is_x86_feature_detected!("mmx");
226 }
227
228 #[rustversion::since(1.46)]
229 mod test_local_setter {
230 // https://github.com/dtolnay/paste/issues/7
231
232 use paste::paste;
233
234 #[derive(Default)]
235 struct Test {
236 val: i32,
237 }
238
239 impl Test {
set_val(&mut self, arg: i32)240 fn set_val(&mut self, arg: i32) {
241 self.val = arg;
242 }
243 }
244
245 macro_rules! setter {
246 ($obj:expr, $field:ident, $value:expr) => {
247 paste! { $obj.[<set_ $field>]($value); }
248 };
249
250 ($field:ident, $value:expr) => {{
251 let mut new = Test::default();
252 setter!(new, val, $value);
253 new
254 }};
255 }
256
257 #[test]
test_local_setter()258 fn test_local_setter() {
259 let a = setter!(val, 42);
260 assert_eq!(a.val, 42);
261 }
262 }
263
264 // https://github.com/dtolnay/paste/issues/85
265 #[test]
test_top_level_none_delimiter()266 fn test_top_level_none_delimiter() {
267 macro_rules! clone {
268 ($val:expr) => {
269 paste! {
270 $val.clone()
271 }
272 };
273 }
274
275 #[derive(Clone)]
276 struct A;
277
278 impl A {
279 fn consume_self(self) {
280 let _ = self;
281 }
282 }
283
284 clone!(&A).consume_self();
285 }
286