4 [![Build Status](https://api.travis-ci.org/dtolnay/quote.svg?branch=master)](https://travis-ci.org/dtolnay/quote)
5 [![Latest Version](https://img.shields.io/crates/v/quote.svg)](https://crates.io/crates/quote)
6 [![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/quote/)
8 This crate provides the [`quote!`] macro for turning Rust syntax tree data
9 structures into tokens of source code.
11 [`quote!`]: https://docs.rs/quote/0.6/quote/macro.quote.html
13 Procedural macros in Rust receive a stream of tokens as input, execute arbitrary
14 Rust code to determine how to manipulate those tokens, and produce a stream of
15 tokens to hand back to the compiler to compile into the caller's crate.
16 Quasi-quoting is a solution to one piece of that -- producing tokens to return
19 The idea of quasi-quoting is that we write *code* that we treat as *data*.
20 Within the `quote!` macro, we can write what looks like code to our text editor
21 or IDE. We get all the benefits of the editor's brace matching, syntax
22 highlighting, indentation, and maybe autocompletion. But rather than compiling
23 that as code into the current crate, we can treat it as data, pass it around,
24 mutate it, and eventually hand it back to the compiler as tokens to compile into
25 the macro caller's crate.
27 This crate is motivated by the procedural macro use case, but is a
28 general-purpose Rust quasi-quoting library and is not specific to procedural
31 *Version requirement: Quote supports any compiler version back to Rust's very
32 first support for procedural macros in Rust 1.15.0.*
34 [*Release notes*](https://github.com/dtolnay/quote/releases)
43 The quote crate provides a [`quote!`] macro within which you can write Rust code
44 that gets packaged into a [`TokenStream`] and can be treated as data. You should
45 think of `TokenStream` as representing a fragment of Rust source code.
47 [`TokenStream`]: https://docs.rs/proc-macro2/0.4/proc_macro2/struct.TokenStream.html
49 Within the `quote!` macro, interpolation is done with `#var`. Any type
50 implementing the [`quote::ToTokens`] trait can be interpolated. This includes
51 most Rust primitive types as well as most of the syntax tree types from [`syn`].
53 [`quote::ToTokens`]: https://docs.rs/quote/0.6/quote/trait.ToTokens.html
54 [`syn`]: https://github.com/dtolnay/syn
58 struct SerializeWith #generics #where_clause {
60 phantom: core::marker::PhantomData<#item_ty>,
63 impl #generics serde::Serialize for SerializeWith #generics #where_clause {
64 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
68 #path(self.value, serializer)
74 phantom: core::marker::PhantomData::<#item_ty>,
81 Repetition is done using `#(...)*` or `#(...),*` similar to `macro_rules!`. This
82 iterates through the elements of any variable interpolated within the repetition
83 and inserts a copy of the repetition body for each one. The variables in an
84 interpolation may be anything that implements `IntoIterator`, including `Vec` or
85 a pre-existing iterator.
87 - `#(#var)*` — no separators
88 - `#(#var),*` — the character before the asterisk is used as a separator
89 - `#( struct #var; )*` — the repetition can contain other things
90 - `#( #k => println!("{}", #v), )*` — even multiple interpolations
92 Note that there is a difference between `#(#var ,)*` and `#(#var),*`—the latter
93 does not produce a trailing comma. This matches the behavior of delimiters in
96 ## Returning tokens to the compiler
98 The `quote!` macro evaluates to an expression of type
99 `proc_macro2::TokenStream`. Meanwhile Rust procedural macros are expected to
100 return the type `proc_macro::TokenStream`.
102 The difference between the two types is that `proc_macro` types are entirely
103 specific to procedural macros and cannot ever exist in code outside of a
104 procedural macro, while `proc_macro2` types may exist anywhere including tests
105 and non-macro code like main.rs and build.rs. This is why even the procedural
106 macro ecosystem is largely built around `proc_macro2`, because that ensures the
107 libraries are unit testable and accessible in non-macro contexts.
109 There is a [`From`]-conversion in both directions so returning the output of
110 `quote!` from a procedural macro usually looks like `tokens.into()` or
111 `proc_macro::TokenStream::from(tokens)`.
113 [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
117 ### Combining quoted fragments
119 Usually you don't end up constructing an entire final `TokenStream` in one
120 piece. Different parts may come from different helper functions. The tokens
121 produced by `quote!` themselves implement `ToTokens` and so can be interpolated
122 into later `quote!` invocations to build up a final result.
125 let type_definition = quote! {...};
126 let methods = quote! {...};
128 let tokens = quote! {
134 ### Constructing identifiers
136 Suppose we have an identifier `ident` which came from somewhere in a macro
137 input and we need to modify it in some way for the macro output. Let's consider
138 prepending the identifier with an underscore.
140 Simply interpolating the identifier next to an underscore will not have the
141 behavior of concatenating them. The underscore and the identifier will continue
142 to be two separate tokens as if you had written `_ x`.
151 The solution is to perform token-level manipulations using the APIs provided by
155 let concatenated = format!("_{}", ident);
156 let varname = syn::Ident::new(&concatenated, ident.span());
158 let mut #varname = 0;
162 ### Making method calls
164 Let's say our macro requires some type specified in the macro input to have a
165 constructor called `new`. We have the type in a variable called `field_type` of
166 type `syn::Type` and want to invoke the constructor.
171 let value = #field_type::new();
175 This works only sometimes. If `field_type` is `String`, the expanded code
176 contains `String::new()` which is fine. But if `field_type` is something like
177 `Vec<i32>` then the expanded code is `Vec<i32>::new()` which is invalid syntax.
178 Ordinarily in handwritten Rust we would write `Vec::<i32>::new()` but for macros
179 often the following is more convenient.
183 let value = <#field_type>::new();
187 This expands to `<Vec<i32>>::new()` which behaves correctly.
189 A similar pattern is appropriate for trait methods.
193 let value = <#field_type as core::default::Default>::default();
199 Any interpolated tokens preserve the `Span` information provided by their
200 `ToTokens` implementation. Tokens that originate within a `quote!` invocation
201 are spanned with [`Span::call_site()`].
203 [`Span::call_site()`]: https://docs.rs/proc-macro2/0.4/proc_macro2/struct.Span.html#method.call_site
205 A different span can be provided explicitly through the [`quote_spanned!`]
208 [`quote_spanned!`]: https://docs.rs/quote/0.6/quote/macro.quote_spanned.html
212 - A non-repeating variable may not be interpolated inside of a repeating block
214 - The same variable may not be interpolated more than once inside of a repeating
217 [#7]: https://github.com/dtolnay/quote/issues/7
218 [#8]: https://github.com/dtolnay/quote/issues/8
222 The `quote!` macro relies on deep recursion so some large invocations may fail
223 with "recursion limit reached" when you compile. If it fails, bump up the
224 recursion limit by adding `#![recursion_limit = "128"]` to your crate. An even
225 higher limit may be necessary for especially large invocations. You don't need
226 this unless the compiler tells you that you need it.
230 Licensed under either of
232 * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
233 * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
239 Unless you explicitly state otherwise, any contribution intentionally submitted
240 for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
241 be dual licensed as above, without any additional terms or conditions.