ditoslav
ditoslav

Reputation: 4872

How to disambiguate against types with Vec<T> in macro_rules in Rust?

Let's say I have

macro_rules! tipey {
    (Vec<$pt: ty>) => {2};
    ($pt: ty) => {1};
}

macro_rules! structy {
    (struct $i: ident { $($p: ident : $(Vec<)? $pt: ty $(>)?,)+ }) => {
        const v: &[usize] = &[ $(tipey!($pt)),+ ];
    };
}

structy!(
    struct ContentDetails {
        pattern: String,
        fields: Vec<String>,
    }
);

I want to somehow be able to disambiguate the type and know whether it is a Vec<> or a simple type. I'm only dealing with Vecs so no need to expand if not possible.

The issue I have is that if I match Vec<bool> against just $t: ty then I cannot split it up later to see if the $t was Vec<> or not but if I try to collect multiple tts or something else then parsing the list of properties breaks. I really want to avoid having to use proc macros

Upvotes: 0

Views: 105

Answers (1)

Peter Hall
Peter Hall

Reputation: 58735

This is going to be very unreliable for general types, and generic Rust syntax. But if you have a very narrow use-case then you can fix up your code something like this:

macro_rules! tipey {
    (Vec<$pt: tt>) => { 2 };
    ($pt: tt) => { 1 };
}

macro_rules! structy {
    (struct $i: ident { 
        $($p: ident: $pt: tt $(<$gt: tt>)?),+
        $(,)?
    }) => {
        const v: &[usize] = &[ $(tipey!( $pt $(<$gt>)?)),+ ];
    };
}

Upvotes: 1

Related Questions