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 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
#![no_std]
//! Macros that produce the name of the function they're invoked within.
//!
//! ## Uninstantiated Names
//! [`uninstantiated!`]: macro.uninstantiated.html
//! The [`uninstantiated!`] macro produces the name of the surrounding function
//! or method, *without* generics instantiated; e.g.:
//! ```
//! struct GenericType<A>(A);
//!
//! impl<A> GenericType<A> {
//! fn generic_method<B>(self, _: B) -> &'static str {
//! fn_name::uninstantiated!()
//! }
//! }
//!
//! fn main() {
//! assert_eq!(
//! GenericType(42u8).generic_method(false),
//! "GenericType<_>::generic_method"
//! );
//! }
//! ```
//!
//! ## Instantiated Names
//! [`instantiated!`]: macro.instantiated.html
//! The [`instantiated!`] macro produces the name of the surrounding function or
//! method, *including* instantiated generics (if any); e.g.:
//! ```
//! struct GenericType<A>(A);
//!
//! impl<A> GenericType<A> {
//! fn generic_method<B>(self, _: B) -> &'static str {
//! fn_name::instantiated!()
//! }
//! }
//!
//! fn main() {
//! assert_eq!(
//! GenericType(42u8).generic_method(false),
//! "GenericType<u8>::generic_method<bool>"
//! );
//! }
//! ```
//!
//! ## Limitations
//! The expansion of these macros is not (yet) const evaluable; their
//! implementations rely on `core::any::type_name`, which is not a `const fn`.
/// Produces the name of the surrounding function or method, *without* generics
/// instantiated.
///
/// ## Example
/// ```
/// struct GenericType<A>(A);
///
/// impl<A> GenericType<A> {
/// fn generic_method<B>(self, _: B) -> &'static str {
/// fn_name::uninstantiated!()
/// }
/// }
///
/// fn main() {
/// assert_eq!(
/// GenericType(42u8).generic_method(false),
/// "GenericType<_>::generic_method"
/// );
/// }
/// ```
#[macro_export]
macro_rules! uninstantiated {
() => {{
struct Here;
const PREFIX: &str = concat!(module_path!(), "::");
const SUFFIX: &str = "::Here";
let here = core::any::type_name::<Here>();
&here[PREFIX.len()..(here.len() - SUFFIX.len())]
}}
}
/// Produces the name of the surrounding function or method, *including*
/// instantiated generics (if any).
///
/// ## Example
/// ```
/// struct GenericType<A>(A);
///
/// impl<A> GenericType<A> {
/// fn generic_method<B>(self, _: B) -> &'static str {
/// fn_name::instantiated!()
/// }
/// }
///
/// fn main() {
/// assert_eq!(
/// GenericType(42u8).generic_method(false),
/// "GenericType<u8>::generic_method<bool>"
/// );
/// }
/// ```
#[macro_export]
macro_rules! instantiated {
() => {{
fn type_name_of_val<T: ?Sized>(_: &T) -> &'static str {
core::any::type_name::<T>()
}
const PREFIX: &str = concat!(module_path!(), "::");
const SUFFIX: &str = "::{{closure}}";
let here = &type_name_of_val(&||{});
&here[PREFIX.len()..(here.len() - SUFFIX.len())]
}}
}