1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
//! # code-path
//!
//! A code path macro
//!
//! ## Usage
//! ```rust
//! use code_path::code_path;
//!
//! fn foo() -> &'static str {
//! fn bar() -> &'static str {
//! code_path!()
//! }
//! bar()
//! }
//!
//! assert_eq!(foo(), "rust_out::main::_doctest_main_src_lib_rs_6_0::foo::bar");
//! ```
#![warn(clippy::all, missing_docs, nonstandard_style, future_incompatible)]
/// Returns the current code path. It could be used in errors, logs, etc to avoid typos.
#[macro_export]
macro_rules! code_path {
() => {{
fn f() {}
fn type_name_of<T>(_: T) -> &'static str {
::std::any::type_name::<T>()
}
let mut name = type_name_of(f);
name = &name[..name.len() - 3];
while name.ends_with("::{{closure}}") {
name = &name[..name.len() - 13];
}
name
}};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn nesting() {
fn foo() -> &'static str {
fn bar() -> &'static str {
code_path!()
}
bar()
}
assert_eq!(foo(), "code_path::tests::nesting::foo::bar");
}
#[test]
fn ending_cloures() {
fn foo() -> &'static str {
#[allow(clippy::redundant_closure_call)]
(|| (|| code_path!())())()
}
assert_eq!(foo(), "code_path::tests::ending_cloures::foo");
}
}