Список syn :: Idents, разделенный запятыми - PullRequest
0 голосов
/ 07 мая 2020

Я хочу добавить несколько syn::Ident, чтобы сформировать &'static str. Все Ident должны быть объединены, чтобы сформировать разделенные запятыми и преобразованные в строку (потому что так я получаю строковое представление Ident) &'static str.

У меня здесь неработающий проект: https://github.com/Jasperav/comma_separated (внутри папки example есть неудачный тест).

Это мой тест:

#[test]
fn test_another_struct() {
    assert_eq!("name, another_name", AnotherStruct::useless())
}

Он терпит неудачу из-за этого:

Ожидается: nameanother_name Фактическое: name, another_name

Это мой код, пытающийся создать список, разделенный запятыми (внутри lib.rs):

let idents = vec![
    syn::Ident::new("name", Span::call_site()),
    syn::Ident::new("another_name", Span::call_site())
];

proc_macro::TokenStream::from(quote! {
    impl #struct_name {
        fn useless() -> &'static str {
            concat!(#(stringify!(#idents)),*)
        }
    }
})

Я не понимаю, почему он не работает. В моем макросе 1 ,, это значит: разделять все запятыми, верно?

1 Ответ

1 голос
/ 07 мая 2020

Если вы cargo expand свой код, вы поймете, что расширились до этого:

(предположим, struct_name равно Foo)

impl Foo {
    fn useless() -> &'static str {
        concat!(stringify!(name), stringify!(another_name))
    }
}

stringify! преобразует идентификатор непосредственно в строку, поэтому возвращаемое значение эквивалентно

concat!("name", "another_name")

Здесь запятая является разделителем для синтаксиса, а не строковым литералом, поэтому вы получите nameanother_name.

Принимая во внимание только ваш код, приведенный выше, наиболее удобным исправлением является формулирование необработанной строки внутри кода proc_macro вместо использования stringify! и concat!, что позволяет использовать API, такие как slice::join.

...