List types of a struct

Hello,

Do you know a crate that is able to do this below ?
(I saw memoffset can partially do it, and type-layoutjust display all the list)

#[repr(C)]
struct MyStruct {
   var1: u8,
   var2:i64
}

for   var_info   in    magic_macro!(MyStruct) {
   println!("Name={}  Type={} Size={} Offset={}",
         var_info.name() , 
         var_info.type_str(),
         var_info.size_in_byte(),
         var_info.offset()
   );
}

... output this :

Name=var1 Type=std::u8  Size=1 Offset=0
Name=var2 Type=std::i64 Size=8 Offset=8

I don't know of anything that would do that - nor can I think of how to implement it exactly as listed.

What would be possible would be something like:

#[derive(introspect)]
struct MyStruct {
   var1: u8,
   var2:i64
}

let StructInfo {name, type_str, size, offset} = MyStruct::introspect();

You can try:

macro_rules! reflect {
    ($(#[$attr:meta])* struct $struct:ident { 
        $($field:ident : $type:ty $(,)?)+
    }) => {
        $(#[$attr])*
        struct $struct {
            $($field: $type,)+
        }
        
        impl $struct {
            #[doc(hidden)]
            #[allow(unused)]
            fn field_info() -> impl Iterator<Item = (
                &'static str,
                &'static str,
                usize, 
                usize,
            )> {
                [$((
                    stringify!($field),
                    std::any::type_name::<$type>(),
                    size_of::<$type>() * 8,
                    std::mem::offset_of!($struct, $field)
                ),)+].into_iter()
            }
        }
    };
    ($struct:ident) => {
        $struct::field_info()
    };
} 

reflect! {
    #[repr(C)]
    struct MyStruct {
       var1: u8,
       var2: i64
    }
}

fn main() {
    for (nm, tp, sz, off) in reflect!(MyStruct) {
       println!("Name={nm}  Type={tp} Size={sz} Offset={off}");
    }
}

On nightly, this can be done without attaching any macro to the struct definition through the unstable type_info feature, e.g. TypeId::field(). On stable, you may be interested in facet - Rust, which requires a derive but not an application-specific one.

Thanks you all !

I'm trying to use TypeId::field() to list variables in a struct, but it gives an error (below) :

error: comptime fns can only be called at compile time
  --> src/main.rs:66:5
   |
66 |     typeid.generics();
   |     ^^^^^^^^^^^^^^^^^

... with this code :

    let typeid = TypeId::of::<MyStruct2>().type_id();
    for field_index in typeid.fields(0) {
        let t = typeid.field(0, field_index);
    }

Is it possible to use this nightly feature to list properties of fields of a struct ?

Right now that feature is very new and unfinished and constantly changing. It only works in specially tagged compile-time only functions (#[rustc_comptime] fn ...), which itself requires additional (unfinished) nightly-only features. It might be able to do what you want eventually, but it is not there just yet.

Ok. Thanks.

Do you authorize me to publish a crate with your code, in MIT license ?

It's just a snippet, no need to ask for my permission. Feel free to use it however you see fit.

Thanks you! So I've review to use as a #derive and publish it : https://crates.io/crates/struct-fields-info. So it can be useful for others.