use paste::paste;
#[test]
fn test_shared_hygiene() {
paste! {
let [<a a>] =
1;
assert_eq!([<a a>],
1);
}
}
#[test]
fn test_repeat() {
const ROCKET_A: &str =
"/a";
const ROCKET_B: &str =
"/b";
macro_rules! routes {
($($route:ident),*) => {{
paste! {
vec![$( [<ROCKET_ $route>] ),*]
}
}}
}
let routes = routes!(A, B);
assert_eq!(routes, vec![
"/a",
"/b"]);
}
#[test]
fn test_literal_to_identifier() {
const CONST0: &str =
"const0";
let pasted = paste!([<
CONST 0>]);
assert_eq!(pasted, CONST0);
let pasted = paste!([<
CONST '0'>]);
assert_eq!(pasted, CONST0);
let pasted = paste!([<
CONST "0">]);
assert_eq!(pasted, CONST0);
let pasted = paste!([<
CONST r
"0">]);
assert_eq!(pasted, CONST0);
let pasted = paste!([<
CONST '\u{30}'>]);
assert_eq!(pasted, CONST0);
}
#[test]
fn test_literal_suffix() {
macro_rules! literal {
($bit:tt) => {
paste!([<
1_u $bit>])
};
}
assert_eq!(literal!(
32),
1);
}
#[test]
fn test_underscore() {
paste! {
const A_B: usize =
0;
assert_eq!([<A _ B>],
0);
}
}
#[test]
fn test_lifetime() {
paste! {
#[allow(dead_code)]
struct S<[<
'd e>]> {
q: &[<
'd e>] str,
}
}
}
#[test]
fn test_keyword() {
paste! {
struct [<F
move>];
let _ = Fmove;
}
}
#[test]
fn test_literal_str() {
paste! {
#[allow(non_camel_case_types)]
struct [<Foo
"Bar-Baz">];
let _ = FooBar_Baz;
}
}
#[test]
fn test_env_literal() {
paste! {
struct [<Lib env bar>];
let _ = Libenvbar;
}
}
#[test]
fn test_env_present() {
paste! {
struct [<Lib env!(
"CARGO_PKG_NAME")>];
let _ = Libpaste;
}
}
#[test]
fn test_raw_identifier() {
paste! {
struct [<F r
#move>];
let _ = Fmove;
}
}
#[test]
fn test_false_start() {
trait Trait {
fn f() -> usize;
}
struct S;
impl Trait for S {
fn f() -> usize {
0
}
}
paste! {
let x = [<S
as Trait>::f()];
assert_eq!(x[
0],
0);
}
}
#[test]
fn test_local_variable() {
let yy =
0;
paste! {
assert_eq!([<y y>],
0);
}
}
#[test]
fn test_empty() {
paste! {
assert_eq!(stringify!([<y y>]),
"yy");
assert_eq!(stringify!([<>]).replace(
' ',
""),
"[<>]");
}
}
#[test]
fn test_env_to_lower() {
paste! {
struct [<Lib env!(
"CARGO_PKG_NAME"):lower>];
let _ = Libpaste;
}
}
#[test]
fn test_env_to_upper() {
paste! {
const [<LIB env!(
"CARGO_PKG_NAME"):upper>]: &str =
"libpaste";
let _ = LIBPASTE;
}
}
#[test]
fn test_env_to_snake() {
paste! {
const [<LIB env!(
"CARGO_PKG_NAME"):snake:upper>]: &str =
"libpaste";
let _ = LIBPASTE;
}
}
#[test]
fn test_env_to_camel() {
paste! {
#[allow(non_upper_case_globals)]
const [<LIB env!(
"CARGO_PKG_NAME"):camel>]: &str =
"libpaste";
let _ = LIBPaste;
}
}
mod test_x86_feature_literal {
// work around https://github.com/rust-lang/rust/issues/72726
use paste::paste;
#[cfg(any(target_arch =
"x86", target_arch =
"x86_64"))]
macro_rules! my_is_x86_feature_detected {
($feat:literal) => {
paste! {
#[test]
fn test() {
let _ = is_x86_feature_detected!($feat);
}
}
};
}
#[cfg(not(any(target_arch =
"x86", target_arch =
"x86_64")))]
macro_rules! my_is_x86_feature_detected {
($feat:literal) => {
#[ignore]
#[test]
fn test() {}
};
}
my_is_x86_feature_detected!(
"mmx");
}
#[rustversion::since(
1.
46)]
mod test_local_setter {
// https://github.com/dtolnay/paste/issues/7
use paste::paste;
#[derive(Default)]
struct Test {
val: i32,
}
impl Test {
fn set_val(&
mut self, arg: i32) {
self.val = arg;
}
}
macro_rules! setter {
($obj:expr, $field:ident, $value:expr) => {
paste! { $obj.[<set_ $field>]($value); }
};
($field:ident, $value:expr) => {{
let mut new = Test::default();
setter!(new, val, $value);
new
}};
}
#[test]
fn test_local_setter() {
let a = setter!(val,
42);
assert_eq!(a.val,
42);
}
}
// https://github.com/dtolnay/paste/issues/85
#[test]
fn test_top_level_none_delimiter() {
macro_rules! clone {
($val:expr) => {
paste! {
$val.clone()
}
};
}
#[derive(Clone)]
struct A;
impl A {
fn consume_self(
self) {
let _ =
self;
}
}
clone!(&A).consume_self();
}