Macro macros::paste

source ·
paste!() { /* proc-macro */ }
Expand description

Paste identifiers together.

Within the paste! macro, identifiers inside [< and >] are concatenated together to form a single identifier.

This is similar to the paste crate, but with pasting feature limited to identifiers and literals (lifetimes and documentation strings are not supported). There is a difference in supported modifiers as well.

Example

use kernel::macro::paste;

macro_rules! pub_no_prefix {
    ($prefix:ident, $($newname:ident),+) => {
        paste! {
            $(pub(crate) const $newname: u32 = [<$prefix $newname>];)+
        }
    };
}

pub_no_prefix!(
    binder_driver_return_protocol_,
    BR_OK,
    BR_ERROR,
    BR_TRANSACTION,
    BR_REPLY,
    BR_DEAD_REPLY,
    BR_TRANSACTION_COMPLETE,
    BR_INCREFS,
    BR_ACQUIRE,
    BR_RELEASE,
    BR_DECREFS,
    BR_NOOP,
    BR_SPAWN_LOOPER,
    BR_DEAD_BINDER,
    BR_CLEAR_DEATH_NOTIFICATION_DONE,
    BR_FAILED_REPLY
);

assert_eq!(BR_OK, binder_driver_return_protocol_BR_OK);

Modifiers

For each identifier, it is possible to attach one or multiple modifiers to it.

Currently supported modifiers are:

  • span: change the span of concatenated identifier to the span of the specified token. By default the span of the [< >] group is used.
  • lower: change the identifier to lower case.
  • upper: change the identifier to upper case.
use kernel::macro::paste;

macro_rules! pub_no_prefix {
    ($prefix:ident, $($newname:ident),+) => {
        kernel::macros::paste! {
            $(pub(crate) const fn [<$newname:lower:span>]: u32 = [<$prefix $newname:span>];)+
        }
    };
}

pub_no_prefix!(
    binder_driver_return_protocol_,
    BR_OK,
    BR_ERROR,
    BR_TRANSACTION,
    BR_REPLY,
    BR_DEAD_REPLY,
    BR_TRANSACTION_COMPLETE,
    BR_INCREFS,
    BR_ACQUIRE,
    BR_RELEASE,
    BR_DECREFS,
    BR_NOOP,
    BR_SPAWN_LOOPER,
    BR_DEAD_BINDER,
    BR_CLEAR_DEATH_NOTIFICATION_DONE,
    BR_FAILED_REPLY
);

assert_eq!(br_ok(), binder_driver_return_protocol_BR_OK);

Literals

Literals can also be concatenated with other identifiers:

macro_rules! create_numbered_fn {
    ($name:literal, $val:literal) => {
        kernel::macros::paste! {
            fn [<some_ $name _fn $val>]() -> u32 { $val }
        }
    };
}

create_numbered_fn!("foo", 100);

assert_eq!(some_foo_fn100(), 100)