Search code examples
rustmacrosdefault

Rust - Mix default macro and personal default implementation


I want to know if it's possible to let Rust define the default implementation for my structure with the macro #[derive(Default)] but define some default values for some fields.

I want to do this to avoid to define the default values of all fields when Rust could do it.

Thanks for your time


Solution

  • As far as I know derive(Default) is all-or-nothing.

    However, you can initialize Defaultable fields using field: Default::default() (which may already be simple enough). You could use this fact to write a macro that takes all Defaultable fields and initializes them, e.g.:

    macro_rules! defaultable{
        (
            $t: ty,
            @default($($default_field:ident,)*)
            @custom($($custom_field:ident = $custom_value:expr,)*)
        )
        => {
        impl Default for $t {
            fn default() -> Self {
                Self {
                    $($default_field: Default::default(),)*
                    $($custom_field: $custom_value,)*
                }
            }
        }
    }}
    
    struct S {
        n1: usize,
        n2: usize,
        b: bool,
        non_default: usize,
    }
    
    defaultable!(S, @default(n1, n2, b,) @custom(non_default=42,));
    
    fn main() {
        let s : S = Default::default();
        println!("{}", s.non_default);
    }