Search code examples
rustrust-macros

Macro that makes struct based on struct field's types


I am trying to make a macro that generates a struct with a new function implementation. The new function needs to call functions based on the type of the field and use the return value as the field value.

The new implementation should end up working like this:

struct foo {
    test: i32,
    other: String,
}

impl foo {
    fn new() -> Self {
        foo {
           test: get_i32(),
           other: get_string(),
        }
    }
}

This is the current code I have:

macro_rules! test {
    (struct $name:ident { $($fname:ident : $ftype:ty),* }) => {
        #[derive(Debug)]
        pub struct $name {
            $(pub $fname : $ftype),*
        }

        impl $name {
            fn new(mut v: Vec<u8>) -> Self {
                $name {
                    $($fname : ),*
                }
            }
        }
    };
}

I have tried putting a match statement but it gives incompatible arms types error.

impl $name {
    fn new(mut v: Vec<u8>) -> Self {
        $name {
            $($fname : match &stringify!($ftype)[..] {
                "i32" => get_i32(),
                "String" => get_string(),
            }),*
        }
    }
}

Thank you.


Solution

  • I managed to use another function that returns any to get it to work.

    macro_rules! test {
        (struct $name:ident { $($fname:ident : $ftype:ty),* }) => {
            #[derive(Debug)]
            pub struct $name {
                $(pub $fname : $ftype),*
            }
    
            impl $name {
                fn new(mut v: Vec<u8>) -> Self {
                    $name {
                        $($fname : get_feild::<$ftype>(stringify!($ftype)).downcast_ref::<$ftype>().unwrap().clone()),*
                    }
                }
            }
        };
    }
    
    fn get_feild<T>(t: &str) -> Box<dyn std::any::Any> {
        match t {
            "i32" => Box::new(get_i32()),
            "String" => Box::new(get_string()),
            _ => panic!("UNKNOWN TYPE"),
        }
    }