aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Macnak <natsu@google.com>2020-03-18 02:08:27 +0000
committerJason Macnak <natsu@google.com>2020-04-06 10:44:38 -0700
commit1e8b07068e8a586ce0b2d66e46a5d435fdb842f8 (patch)
tree771b90bcb706bf560961a9c2f903e18136722d72 /src
parent88c32390b829d0b7083428cefbf5728e2f2860e0 (diff)
downloadpaste-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.rs127
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;