Did you think Macros 1.1 was only for custom derives? Think again.
This approach works with any Rust version >= 1.15.0.
Two crates are required to define a macro.
This crate is allowed to contain other public things if you need, for example traits or functions or ordinary macros.
https://github.com/dtolnay/proc-macro-hack/tree/master/demo-hack
```rust
extern crate procmacrohack;
// This is what allows the users to depend on just your // declaration crate rather than both crates.
extern crate demohackimpl;
pub use demohackimpl::*;
procmacroexprdecl! { /// Add one to an expression. addone! => addoneimpl }
procmacroitemdecl! { /// A function that always returns 2. twofn! => twofnimpl } ```
This crate must contain nothing but procedural macros. Private helper functions and private modules are fine but nothing can be public.
A less trivial macro would probably use the [syn
] crate to parse its input and
the [quote
] crate to generate the output.
https://github.com/dtolnay/proc-macro-hack/tree/master/demo-hack-impl
```rust
extern crate procmacrohack;
procmacroexprimpl! { /// Add one to an expression. pub fn addone_impl(input: &str) -> String { format!("1 + {}", input) } }
procmacroitemimpl! { /// A function that always returns 2. pub fn twofn_impl(input: &str) -> String { format!("fn {}() -> u8 {{ 2 }}", input) } } ```
Both crates depend on proc-macro-hack
:
toml
[dependencies]
proc-macro-hack = "0.4"
Additionally, your implementation crate (but not your declaration crate) is a proc macro:
toml
[lib]
proc-macro = true
Users of your crate depend on your declaration crate (not your implementation crate), then use your procedural macros as though it were magic. They even get reasonable error messages if your procedural macro panics.
https://github.com/dtolnay/proc-macro-hack/tree/master/example
```rust
extern crate demo_hack;
two_fn!(two);
fn main() { let nine = addone!(two()) + addone!(2 + 3); println!("nine = {}", nine); } ```
mashup
] – A stable approach to concatenating identifiers.indoc
] – Macro that allows the content of string literals to be indented in
source code.structure
] – Macro that uses a format string to create strongly-typed data
pack/unpack interfaces.bstring
] – Macro for formatting byte strings.net-literals
] – Macros for writing IP/socket address literals that are
checked for validity at compile time.wstr
] – Macros for compile-time UTF-16 (wide) string literals.hexf
] – Macros that enable hexadecimal floating point literals.binary_macros
] – Macros for decoding base64 and hexadecimal-like encodings
from string literals to [u8] literals at compile time.autoimpl
] – Macro to generate a default blanket impl for a generic trait.$crate
([#19]).Licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this hack by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.