Obj -> name of concrete type

struct Foo {};
struct Bar<T> { ... };

x: Foo;
y: Bar<u32>;
z: Bar<String>;

is there a way to define an auto derived ::name (or some macro) so that

x.name() or name!(x) -> "Foo".to_string();
y.name() or name!(y) -> "Bar<u32>".to_string();
z.name() or name!(z) => "Bar<String>".to_string();

so I am asking for something that returns the type of 'concrete' (i.e. not trait) objects as a String.

std::any::type_name, though it may not be as pretty as you like (or consistent).

pub trait SayMyName {
    fn name(&self) -> String;
}

impl<T: ?Sized> SayMyName for T {
    fn name(&self) -> String {
        std::any::type_name::<T>().into()
    }
}

Playground. Note that dyn Trait types are "concrete types" by my vocabulary; it doesn't see through them to the underlying erased type, if that's what you mean (see playground).

std::any::type_name_of_val also exists, but it's unstable.

Macro approaches and exploiting Serde and the like have come up on the forum before.

1 Like

Here's the thread I was thinking of.

Note that if you don't need it to be an owned, modifyable Sting, you can of course change @quinedot's code

to return &'static str instead of String; since that's what any::type_name returns.

pub trait SayMyName {
    fn name(&self) -> &'static str;
}

impl<T: ?Sized> SayMyName for T {
    fn name(&self) -> &'static str {
        std::any::type_name::<T>()
    }
}

(modified playground)

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.