Reflection with macro

Since Rust doesn’t have reflection, I thought about how Reflection could be implemented with a procedural macro. Ideally, the API should use static dispatch where possible, so functions using reflection can be inlined.

But before I spend a lot of time writing this macro, I’d like to know what you think! Do you believe this would be useful? Do you have any suggestions for improvement?

Here’s an excerpt from my first prototype and an example at the end:

pub trait Struct<T> {
    fn name(&self) -> &'static str;
    fn is_pub(&self) -> bool;
    fn fields(&self) -> Vec<Box<dyn Field<T>>>;
    fn attributes(&self) -> Vec<Attribute>;
}

pub trait Field<T> {
    fn name(&self) -> &'static str;
    fn is_pub(&self) -> bool;
    fn ty(&self) -> Type;
    fn attributes(&self) -> Vec<Attribute>;
    fn structure(&self) -> Box<dyn Struct<T>>;
}

pub trait DataField<T, F> : Field<T> {
    fn get(&self, t: T) -> F;
    fn get_ref(&self, t: &T) -> &F;
    fn get_mut(&self, t: &mut T) -> &mut F;
}

When the macro is applied to a struct Foo, it should generate a zero-sized struct that implements Struct<Foo> and a static instance called Foo (a variable can have the same name as a struct):

struct Foo(x: String, y: u32);

struct RFoo {
    x: RFoo_x,
    y: RFoo_y,
}
impl Struct<Foo> for RFoo {...}

struct RFoo_x;
impl Field<Foo> for RFoo_x {...}
impl DataField<Foo, String> for RFoo_x {...}

struct RFoo_y;
impl Field<Foo> for RFoo_y {...}
impl DataField<Foo, u32> for RFoo_y {...}

static Foo: RFoo = RFoo {
    x: RFoo_x,
    y: RFoo_y,
};

Here’s an example how you could use it with static dispatch:

fn debug_prop<S, F: Debug>(structure: &S, prop: impl DataField<S, F>) {
    println!("{}.{} = {:?}",
        prop.structure().name(),
        prop.name(),
        prop.get_ref(structure));
}

let foo = Foo("bar".into(), 42u32);

debug_prop(&foo, Foo.x);  // prints Foo.x = "bar"
debug_prop(&foo, Foo.y);  // prints Foo.y = 42