Macro rules fill the rest of a vec with empty

Hello,

I want to fill the remaining capacity of a vec with an empty value:

#[derive(Debug)]
pub(crate) enum Args<A, B, C, D, E> {
    Args0(A),
    Args1(B),
    Args2(C),
    Args3(D),
    Args4(E),
}

struct Empty;

macro_rules! test {
    ($($value:expr),*) => {
        #[test]
        fn test() {
            test_func(InputArgs {
                args: {
                    let v = vec![Arg0($value0),Arg1($value1),...]; // pseudo code
                    // if $value count < 5 then fill with Empty struct 
                    // (ie: Arg2(Empty{}),Args3(Empty{}),Args4(Empty{}) 
                    // for this example with 2 values submitted)
                    v
                },
            });
            
        }
    };
}

It is difficult without an index.

Thank you in advance for your help.

Sorry this question isn’t addressing your stated macro problem yet, but… That's a somewhat weird data structure, isn’t it? Or does your use case involve different shaped vectors, too? If not, then:

An always-5-element Vec<Args<A, B, C, D, E> where the first element is the Args0(A) variant, the second element is the Args1(B) variant, and so on... well that’s just like a 5 field struct, no enum needed, isn’t it?

struct InputArgs<A, B, C, D, E> {
    args0: A,
    args1: B,
    args2: C,
    args3: D,
    args4: E,
}
2 Likes

Also, in an effort to avoid macros (particularly for the user) where they aren’t really necessary, you could just solve this with functions, right?

struct InputArgs<A = Empty, B = Empty, C = Empty, D = Empty, E = Empty> {
    args0: A,
    args1: B,
    args2: C,
    args3: D,
    args4: E,
}

struct Empty;

impl InputArgs {
    fn new_0() -> Self {
        Self {
            args0: Empty,
            args1: Empty,
            args2: Empty,
            args3: Empty,
            args4: Empty,
        }
    }
}
impl<A> InputArgs<A> {
    fn new_1(args0: A) -> Self {
        Self {
            args0,
            args1: Empty,
            args2: Empty,
            args3: Empty,
            args4: Empty,
        }
    }
}
impl<A, B> InputArgs<A, B> {
    fn new_2(args0: A, args1: B) -> Self {
        Self {
            args0,
            args1,
            args2: Empty,
            args3: Empty,
            args4: Empty,
        }
    }
}
// ...

Now, completing this is still a bit boilerplaty, but that’s then where a macro could help, I suppose, limiting the need for a macro to the API definition and keeping the use-site easier to reason about.

Edit: Re: “that’s then where a macro could help”, e.g. like this.

1 Like

I could create macro_rules! test_2Args ,macro_rules! test_3Args ,macro_rules! test_4Args and so on ...
But I was hoping to be able to provide only one macro.

Here's a macro for the original question: Rust Playground

1 Like

It's a sum type (enum) rather than a product type (struct), but my ptr-union crate might be an interesting case study. The impls are macro generated across each variant.

1 Like

Perfect answer with a better design expertise as a bonus :+1:
But I need to work with a vec of $value before filling with Empty (ie $($value:expr),*) the initial values submitted.
I must investigate how to get this repetition from your macro.
Many thanks anyway :grinning:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.