#[macro_export]
macro_rules! function_name {
() => {{
const fn f() {}
fn type_name_of<T>(_: &T) -> &'static str {
std::any::type_name::<T>()
}
let name: &'static str = type_name_of(&f);
let name: &'static str = &name[..name.len() - 3];
const SPLIT: &str = "::";
const SPLIT_LEN: usize = SPLIT.len();
let rfind: Option<usize> = name.rfind(SPLIT);
let len = name.len();
match rfind {
Some(index) => {
if index + SPLIT_LEN < len {
&name[index + SPLIT_LEN..]
} else {
&name[index..]
}
}
None => {
name
}
}
}};
}
pub use function_name;
#[macro_export]
macro_rules! function_name_plus {
($plus:literal) => {{
const fn f() {}
fn type_name_of<T>(_: &T) -> &'static str {
std::any::type_name::<T>()
}
let name: &'static str = type_name_of(&f);
let name: &'static str = &name[..name.len() - 3];
const SPLIT: &str = "::";
const SPLIT_LEN: usize = SPLIT.len();
let mut plus_: usize = $plus + 1;
let mut at = name.len();
while plus_ > 0 {
let rfind: Option<usize> = name[..at].rfind(SPLIT);
let len = name[..at].len();
at = match rfind {
Some(index) => {
if index < len {
index
} else {
len
}
}
None => {
len
}
};
plus_ -= 1;
}
if at + SPLIT_LEN < name.len() {
&name[at + SPLIT_LEN..]
} else if at < name.len() {
&name[at..]
} else {
&name
}
}};
}
pub use function_name_plus;
#[macro_export]
macro_rules! function_name_full {
() => {{
const fn f() {}
fn type_name_of<T>(_: &T) -> &'static str {
std::any::type_name::<T>()
}
let name: &'static str = type_name_of(&f);
let name: &'static str = &name[..name.len() - 3];
name
}};
}
pub use function_name_full;
#[cfg(test)]
mod tests {
use super::{function_name, function_name_full, function_name_plus};
#[test]
fn test_function_name() {
eprintln!("function_name! \"{}\"", function_name!());
fn func1() {
eprintln!("function_name! \"{}\"", function_name!());
assert_eq!("func1", function_name!());
}
func1();
assert_eq!("test_function_name", function_name!());
}
#[test]
fn test_function_name_function_name_plus0() {
assert_eq!(function_name!(), function_name_plus!(0));
}
#[test]
fn test_function_name_plus0() {
eprintln!("function_name_plus!(0) \"{}\"", function_name_plus!(0));
fn func1() {
eprintln!("function_name_plus!(0) \"{}\"", function_name_plus!(0));
assert_eq!("func1", function_name_plus!(0));
}
func1();
assert_eq!("test_function_name_plus0", function_name_plus!(0));
}
#[test]
fn test_function_name_plus1() {
eprintln!("function_name_plus!(1) \"{}\"", function_name_plus!(1));
fn func1() {
eprintln!("function_name_plus!(1) \"{}\"", function_name_plus!(1));
assert_eq!("test_function_name_plus1::func1", function_name_plus!(1));
}
func1();
assert_eq!("tests::test_function_name_plus1", function_name_plus!(1));
}
#[test]
fn test_function_name_plus2() {
eprintln!("function_name_plus!(2) \"{}\"", function_name_plus!(2));
fn func1() {
eprintln!("function_name_plus!(2) \"{}\"", function_name_plus!(2));
assert_eq!("tests::test_function_name_plus2::func1", function_name_plus!(2));
}
func1();
assert_eq!("function_name::tests::test_function_name_plus2", function_name_plus!(2));
}
mod more_tests {
#[test]
fn test_function_name_plus0() {
eprintln!("function_name_plus!(0) \"{}\"", function_name_plus!(0));
fn func1() {
eprintln!("function_name_plus!(0) \"{}\"", function_name_plus!(0));
assert_eq!("func1", function_name_plus!(0));
}
func1();
assert_eq!("test_function_name_plus0", function_name_plus!(0));
}
#[test]
fn test_function_name_plus1() {
eprintln!("function_name_plus!(1) \"{}\"", function_name_plus!(1));
fn func1() {
eprintln!("function_name_plus!(1) \"{}\"", function_name_plus!(1));
assert_eq!("test_function_name_plus1::func1", function_name_plus!(1));
}
func1();
assert_eq!("more_tests::test_function_name_plus1", function_name_plus!(1));
}
#[test]
fn test_function_name_plus2() {
eprintln!("function_name_plus!(2) \"{}\"", function_name_plus!(2));
fn func1() {
eprintln!("function_name_plus!(2) \"{}\"", function_name_plus!(2));
assert_eq!("more_tests::test_function_name_plus2::func1", function_name_plus!(2));
}
func1();
assert_eq!("tests::more_tests::test_function_name_plus2", function_name_plus!(2));
}
}
#[test]
fn test_function_name_full() {
eprintln!("function_name_full! \"{}\"", function_name_full!());
fn func1() {
eprintln!("function_name_full! \"{}\"", function_name_full!());
assert_eq!(
"si_trace_print::function_name::tests::test_function_name_full::func1",
function_name_full!()
);
}
func1();
assert_eq!(
"si_trace_print::function_name::tests::test_function_name_full",
function_name_full!()
);
}
}