#![crate_name = "nameof"]
#![no_std]
#[macro_export]
macro_rules! name_of {
($n: ident) => {{
let _ = || {
let _ = &$n;
};
stringify!($n)
}};
(type $t: ty) => {{
$crate::name_of_type!($t)
}};
($n: ident in $t: ty) => {{
let _ = |f: $t| {
let _ = &f.$n;
};
stringify!($n)
}};
(const $n: ident in $t: ty) => {{
let _ = || {
let _ = &<$t>::$n;
};
stringify!($n)
}};
}
#[macro_export]
macro_rules! name_of_type {
($t: ty) => {{
let _ = || {
let _: $t;
};
stringify!($t)
}};
}
#[cfg(test)]
extern crate std;
#[cfg(test)]
mod tests {
use std::string::String;
fn test_fn() {
}
struct TestStruct {
test_field: i32,
}
impl TestStruct {
const TEST_CONST: i32 = 1;
}
struct TestGenericStruct<T> {
test_field: T,
}
struct TestGenericStructMultiType<T, U> {
test_field_t: T,
test_field_u: U,
}
#[test]
fn name_of_binding() {
let test_variable = 123;
assert_eq!(name_of!(test_variable), "test_variable");
}
#[test]
fn name_of_fn() {
assert_eq!(name_of!(test_fn), "test_fn");
}
#[test]
fn name_of_type() {
assert_eq!(name_of!(type i32), "i32");
assert_eq!(name_of_type!(i32), "i32");
}
#[test]
fn name_of_struct() {
assert_eq!(name_of!(type TestStruct), "TestStruct");
assert_eq!(name_of_type!(TestStruct), "TestStruct");
}
#[test]
fn name_of_generic_struct() {
assert_eq!(
name_of!(type TestGenericStruct<i32>),
"TestGenericStruct<i32>"
);
assert_eq!(
name_of_type!(TestGenericStruct<i32>),
"TestGenericStruct<i32>"
);
}
#[test]
fn name_of_generic_multi_type_struct() {
assert_eq!(
name_of!(type TestGenericStructMultiType<i32, TestGenericStruct<String>>),
"TestGenericStructMultiType<i32, TestGenericStruct<String>>"
);
assert_eq!(
name_of_type!( TestGenericStructMultiType<i32, TestGenericStruct<String>>),
"TestGenericStructMultiType<i32, TestGenericStruct<String>>"
);
}
#[test]
fn name_of_struct_field() {
assert_eq!(name_of!(test_field in TestStruct), "test_field");
}
#[test]
fn name_of_generic_struct_field() {
assert_eq!(name_of!(test_field in TestGenericStruct<i32>), "test_field");
}
#[test]
fn name_of_generic_multi_type_struct_field() {
assert_eq!(
name_of!(test_field_t in TestGenericStructMultiType<i32, TestGenericStruct<String>>),
"test_field_t"
);
assert_eq!(
name_of!(test_field_u in TestGenericStructMultiType<i32, TestGenericStruct<String>>),
"test_field_u"
);
}
#[test]
fn name_of_struct_constant() {
assert_eq!(name_of!(const TEST_CONST in TestStruct), "TEST_CONST");
}
}