Search code examples
reflectionrustintrospection

How to get struct field names in Rust?


Is there some equivalent of JS's Object.keys() for Rust's struct?

I need something to generate CSV headers (I use rust-csv) from structure field names.

struct Export {
    first_name: String,
    last_name: String,
    gender: String,
    date_of_birth: String,
    address: String
}

//... some code

let mut wrtr = Writer::from_file("/home/me/export.csv").unwrap().delimiter(b'\t');

wrtr.encode(/* WHAT TO WRITE HERE TO GET STRUCT NAMES as tuple of strings or somethings */).is_ok()

Solution

  • The current main method of metaprogramming in Rust is via macros. In this case, you can capture all the field names and then add a method that returns string forms of them:

    macro_rules! zoom_and_enhance {
        (struct $name:ident { $($fname:ident : $ftype:ty),* }) => {
            struct $name {
                $($fname : $ftype),*
            }
    
            impl $name {
                fn field_names() -> &'static [&'static str] {
                    static NAMES: &'static [&'static str] = &[$(stringify!($fname)),*];
                    NAMES
                }
            }
        }
    }
    
    zoom_and_enhance!{
    struct Export {
        first_name: String,
        last_name: String,
        gender: String,
        date_of_birth: String,
        address: String
    }
    }
    
    fn main() {
        println!("{:?}", Export::field_names());
    }
    

    For advanced macros, be sure to check out The Little Book of Rust Macros.