#can I expand $($(rest),)*into an array of labels?

1 messages · Page 1 of 1 (latest)

slim lintel
#

Using macro expansion, I can expand the captured elements into an array:

let array = &[ $($rest),* ]

However, can I expand the captured elements' labels into an array? I know stringify!($foo) allowes me to get the label of $foo, what about an array of all of the labels?

Something like:

let array = &[ $( $stringify!(rest) ),* ]
minor bobcat
slim lintel
#

oh I get

#

error: variable 'rest' is still repeating at this depth

#

so maybe that's because of how I am capturing it

#
macro_rules! print_log {
    ($label:expr $(, $($rest:expr),* )? ) => {
        ...
    }
}
#

maybe the $(, is getting in the way?

#

I need to include a separator because Rust won't allow two expr to follow each other

#

but I need to capture the first separately

#

full macro:

#
#[macro_export]
macro_rules! print_log {
    ($label:expr $(, $($rest:expr),* )? ) => {
        ::log::info!(
            "({}) {}",
            $label,
            logify(&[ stringify!($rest)* ], &[ ($($rest),*) ])
        );
    };
}```
minor bobcat
#
logify(&[$(stringify!($rest)),*], ...)
slim lintel
#

nope still getting error: variable 'rest' is still repeating at this depth

#

with this

#[macro_export]
macro_rules! print_log {
    ($label:expr $(, $($rest:expr),* )? ) => {
        ::log::info!(
            "({}) {}",
            $label,
            logify(&[ $(stringify!($rest)),* ], &[ $( $rest ),* ])
        );
    };
}
#

I can post the full example but it depends on the logtest create to test the log output, don't know if it will be able to eval

minor bobcat
#

Wait, i just noticed that you have a nested repetition

slim lintel
#

you mean I am expanding twice?

minor bobcat
#

Or rather it's nested in a $( ... )?

#

So that has to be part of your expansion

slim lintel
#

I can't see it

#

the two arrays are consecutive, not nested

#

should expand to logify(&[...], &[...])

minor bobcat
#

You have

$(
   $(
      $rest: expr
    ),*
)?
slim lintel
#

oh in the capture expression yeah

minor bobcat
#

So you expansion should reflect that

#

But I don't think you need that additional wrapping

#

The 0 case is already handled by *

slim lintel
#

right I am not sure that is the best way to include the comma at the start, e.g. why can't I remove it at the end and get rid of that nesting level
tried it but didn't work

#

ok let me see

minor bobcat
#

You can allow an optional comma with $(,)?

slim lintel
#

that is not accepted

#

because it's two expr

minor bobcat
#

Right, so it would probably be mandatory, hmm

slim lintel
#

I actually need a string literal in the fist and variables on the rest, so maybe I can write it like that in the capture and it will stop complainng, but I don't thing we have that level of sensibility over expressions

minor bobcat
#

I'm not the best at macros, consider reposting in #macros if no one else chips in here

slim lintel
#

I don't get why $(,($rest:expr))* doesn't work

#

print_log!("hello", i); returns "error: no rules expected the token i"

#

wait that would still be nested tho

#

this

#

($label:expr ,($rest:expr)* )

minor bobcat
#

Maybe your initial matcher was correct

#

Try expanding it correctly, with the added $(...)? Around

#

It would just make an empty array for the second parameter of logify which sounds like what you'd want maybe

slim lintel
#

($label:expr, ($rest:expr),* ) this should work?

#

implying I will always have some rest parameters

#

but it still errors out the same way as above

#

oh Im missing a &

#

hey that works!

#

it's fine too I can get the $label only behaviour in a separate

#

matcher clause

#

thanks @minor bobcat

#

last thing I'm struggling with is avoid polluting the public namespace with the logify() function that is only to be used inside this macro

#

I can make it public and then reference it via $crate::utils::lang::logify inside the macro, but this will make it available for autocompletion everytime I type log which is annoying

minor bobcat
#

mhh, that's a good question. I think there may be visibility tricks for this but I'm not sure

#

I'd suggest #macros again ;)

slim lintel
#

maybe prepending it with __ is good enough