diff options
author | Jason Macnak <natsu@google.com> | 2020-03-18 02:08:27 +0000 |
---|---|---|
committer | Jason Macnak <natsu@google.com> | 2020-04-06 10:44:38 -0700 |
commit | 1e8b07068e8a586ce0b2d66e46a5d435fdb842f8 (patch) | |
tree | 771b90bcb706bf560961a9c2f903e18136722d72 /src | |
parent | 88c32390b829d0b7083428cefbf5728e2f2860e0 (diff) | |
download | paste-1e8b07068e8a586ce0b2d66e46a5d435fdb842f8.tar.gz |
Import 'paste' rust crate version 0.1.7
Bug: b/151760391
Test: m crosvm.experimental
Change-Id: I6e9288d1a0c749166c6ce8cf483c7646a70d32b3
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..34663c5 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,127 @@ +//! The nightly-only [`concat_idents!`] macro in the Rust standard library is +//! notoriously underpowered in that its concatenated identifiers can only refer to +//! existing items, they can never be used to define something new. +//! +//! [`concat_idents!`]: https://doc.rust-lang.org/std/macro.concat_idents.html +//! +//! This crate provides a flexible way to paste together identifiers in a macro, +//! including using pasted identifiers to define new items. +//! +//! This approach works with any stable or nightly Rust compiler 1.30+. +//! +//! # Pasting identifiers +//! +//! There are two entry points, `paste::expr!` for macros in expression position and +//! `paste::item!` for macros in item position. +//! +//! Within either one, identifiers inside `[<`...`>]` are pasted together to form a +//! single identifier. +//! +//! ``` +//! // Macro in item position: at module scope or inside of an impl block. +//! paste::item! { +//! // Defines a const called `QRST`. +//! const [<Q R S T>]: &str = "success!"; +//! } +//! +//! fn main() { +//! // Macro in expression position: inside a function body. +//! assert_eq!( +//! paste::expr! { [<Q R S T>].len() }, +//! 8, +//! ); +//! } +//! ``` +//! +//! # More elaborate examples +//! +//! This program demonstrates how you may want to bundle a paste invocation inside +//! of a more convenient user-facing macro of your own. Here the `routes!(A, B)` +//! macro expands to a vector containing `ROUTE_A` and `ROUTE_B`. +//! +//! ``` +//! const ROUTE_A: &str = "/a"; +//! const ROUTE_B: &str = "/b"; +//! +//! macro_rules! routes { +//! ($($route:ident),*) => {{ +//! paste::expr! { +//! vec![$( [<ROUTE_ $route>] ),*] +//! } +//! }} +//! } +//! +//! fn main() { +//! let routes = routes!(A, B); +//! assert_eq!(routes, vec!["/a", "/b"]); +//! } +//! ``` +//! +//! The next example shows a macro that generates accessor methods for some struct +//! fields. +//! +//! ``` +//! macro_rules! make_a_struct_and_getters { +//! ($name:ident { $($field:ident),* }) => { +//! // Define a struct. This expands to: +//! // +//! // pub struct S { +//! // a: String, +//! // b: String, +//! // c: String, +//! // } +//! pub struct $name { +//! $( +//! $field: String, +//! )* +//! } +//! +//! // Build an impl block with getters. This expands to: +//! // +//! // impl S { +//! // pub fn get_a(&self) -> &str { &self.a } +//! // pub fn get_b(&self) -> &str { &self.b } +//! // pub fn get_c(&self) -> &str { &self.c } +//! // } +//! paste::item! { +//! impl $name { +//! $( +//! pub fn [<get_ $field>](&self) -> &str { +//! &self.$field +//! } +//! )* +//! } +//! } +//! } +//! } +//! +//! make_a_struct_and_getters!(S { a, b, c }); +//! +//! fn call_some_getters(s: &S) -> bool { +//! s.get_a() == s.get_b() && s.get_c().is_empty() +//! } +//! # +//! # fn main() {} +//! ``` + +#![no_std] + +use proc_macro_hack::proc_macro_hack; + +/// Paste identifiers within a macro invocation that expands to an expression. +#[proc_macro_hack] +pub use paste_impl::expr; + +/// Paste identifiers within a macro invocation that expands to one or more +/// items. +/// +/// An item is like a struct definition, function, impl block, or anything else +/// that can appear at the top level of a module scope. +pub use paste_impl::item; + +/// Paste identifiers within a macro invocation that expands to one or more +/// macro_rules macros or items containing macros. +pub use paste_impl::item_with_macros; + +#[doc(hidden)] +pub use paste_impl::EnumHack; |