Я пытаюсь написать макрос Rust, который позволяет мне использовать имена полей и типы объявления структуры, но мне все еще нужно выделять структуру.Сохранение видимости поля структуры с помощью макроса
У меня есть работа с дополнительными атрибутами, видимостью структуры (спасибо The Little Book of Rust Macros), но не могу понять, как бороться с необязательным присутствием pub
в отдельных полях.
До сих пор я получил:
macro_rules! with_generic {
($(#[$struct_meta:meta])*
pub struct $name:ident { $($fname:ident : $ftype:ty), *}
) => {
with_generic![(pub) $(#[$struct_meta])* struct $name {$($fname: $ftype) ,*}];
};
($(#[$struct_meta:meta])*
struct $name:ident { $($fname:ident : $ftype:ty), *}
) => {
with_generic![() $(#[$struct_meta])* struct $name {$($fname: $ftype), *}];
};
(
($($vis:tt)*)
$(#[$struct_meta:meta])*
struct $name:ident { $($fname:ident : $ftype:ty), *}
) => {
// emit the struct here
$(#[$struct_meta])*
$($vis)* struct $name {
$($fname: $ftype,)*
}
// I work with fname and ftypes here
}
}
И это работает с чем-то вроде
with_generic! {
#[derive(PartialEq, Eq, Debug)]
pub struct Person {
first_name: String,
last_name: String
}
}
или
with_generic! {
#[derive(PartialEq, Eq, Debug)]
struct PrivatePerson {
first_name: String,
last_name: String
}
}
, но не работает с
with_generic! {
#[derive(PartialEq, Eq, Debug)]
struct MixedPerson {
pub first_name: String,
last_name: String
}
}
Я хотел бы получить некоторую помощь о том, как заставить макрос работать с этим последним случаем. Я чувствую, что, возможно, мне не хватает чего-то основного, такого как тип, используемый для привязки видимости. Если есть способ привязать все дерево структуры при получении имен полей и типов, это тоже будет хорошо.
Я также хотел бы узнать, как заставить его работать с структурами, имеющими параметры времени жизни, но, возможно, это должен быть отдельный вопрос.
«Я также хотел бы отметить, что есть еще один случай, когда ваш макрос еще не учитывает: атрибуты полей, которые необходимы для комментариев doc для их работы». Фу, спасибо, что я знал, что что-то забыл. Глядя на ваш код (btw ... amazing stuff), я теперь понимаю, что забыл * много * других вещей, например, где предложения. Вы правы, хотя, по сути, мне нужен пользовательский вывод: есть ли где-нибудь я могу узнать больше о том, как там работает макрос 1.1? – lloydmeta
@lloydmeta На данный момент я не знаю. Я бы просто пошел к источнику чего-то вроде «serde-dedive». –
https://doc.rust-lang.org/beta/book/procedural-macros.html – Shepmaster