1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
//! This is Rust quasi-quoting library like [quote](quote) that gives you `mquote!` macro providing //! several features aimed on better readability and usability. It supports: //! * [expression insertion](#expression-insertion) //! * [**if/else**](#if--elif--else) condition //! * [**for**](#for) iteration //! * [**match**](#matching)ing //! * [**extend**](#extending)ing //! //! ## Example //! ```rust //! # use mquote::mquote; //! # let having_fun = true; //! mquote!{ //! #{if having_fun} //! fn funny_method() { ... } //! #{endif} //! fn regular_method() { ... } //! }; //! ``` //! //! Crate contains `mquote!` and `mquote_spanned!`. Usage examples of the first one //! are [below](#expression-insertion). The second one allow you to set //! span of producing tokens stream by this syntax: `mquote_spanned!(span => ...)`. //! //! ## Expression insertion //! Turns given expression into tokens by using [`ToTokens`](../quote/trait.ToTokens.html). //! ```rust //! # use mquote::mquote; //! # struct Person { name: &'static str, age: u16 } //! fn put_filter(enabled: bool) -> proc_macro2::TokenStream { //! let good_person = Person{ name: "Oleg", age: 20 }; //! mquote!{ //! assert!(!#{enabled} || person.name == #{good_person.name} //! && person.age >= #{good_person.age}) //! } //! } //! ``` //! //! ## If / elif / else //! ```rust //! # use mquote::mquote; //! fn define_container(amount: usize) -> proc_macro2::TokenStream { //! mquote!{ //! #{if amount > 1} //! struct People(Vec<Person>); //! #{elif amount == 1} //! struct Human(Person); //! #{else} //! struct NoneHuman; //! #{endif} //! } //! } //! ``` //! //! ## For //! ```rust //! # use mquote::mquote; //! # use proc_macro2::Ident; //! fn define_person(fields: Vec<(Ident, Ident)>) -> proc_macro2::TokenStream { //! mquote!{ //! pub struct Person { //! #{for (name, ty) in fields} //! #{name}: #{ty} //! #{endfor} //! } //! } //! } //! ``` //! //! ## Matching //! ```rust //! # use mquote::mquote; //! # use proc_macro2::Ident; //! fn hardcode_it(var: Ident, value: Option<&str>) -> proc_macro2::TokenStream { //! mquote!{ //! static #var: &str = #{match value} //! #{of Some(x) if x.len() > 0} //! #{x}; //! #{of Some(_)} //! "case for empty strings"; //! #{of None} //! "default value"; //! #{endmatch} //! } //! } //! ``` //! //! ## Extending //! Sometimes you want `mquote!` to consume an iterator of `TokenTree`s //! without cloning. It's possible with special syntax `^{iterable}` that accepts //! any `IntoIterator<Item=TokenTree>`. //! //! ```rust //! # use mquote::mquote; //! # use proc_macro2::TokenStream; //! fn assign_by_ref(stream: TokenStream) -> TokenStream { //! let tail = stream.into_iter().skip(5); // here could be something //! // more reasonable //! mquote!{ //! let _ = ^{tail} //! } //! } //! ``` //! //! ## Escaping `#{}` or `^{}` //! If you want to put either `#{abc}` or `^{abc}` as is, you should double braces: //! ```rust //! # use mquote::mquote; //! fn it_works() { //! let tokens = mquote!(#{{abc}} ^{{abc}}); //! assert_eq!(tokens.to_string(), "# { abc } ^ { abc }") //! } //! ``` extern crate mquote_impl; extern crate proc_macro_hack; extern crate quote; extern crate proc_macro2; use proc_macro_hack::proc_macro_hack; /// Turns given directives into [TokenStream](../proc_macro2/struct.TokenStream.html). /// /// You may learn syntax in [root level documentation](index.html). #[proc_macro_hack] pub use mquote_impl::mquote; /// Same as [mquote!](macro.mquote.html), but applies a given span to all tokens originating within the macro invocation. /// /// ## Example /// ```rust /// # use mquote::mquote_spanned; /// let span = proc_macro2::Span::call_site(); /// mquote_spanned!(span => let _ = Some(12)); /// ``` #[proc_macro_hack] pub use mquote_impl::mquote_spanned; #[cfg(not(mquote_span_testing))] #[doc(hidden)] pub mod __rt { pub mod quote { pub use crate::quote::*; } pub mod proc_macro2 { pub use crate::proc_macro2::*; } pub mod std { pub use ::std::*; } } #[cfg(mquote_span_testing)] #[doc(hidden)] #[path = "mocked_runtime/mod.rs"] pub mod __rt;