Поскольку атрибуты доступны только для чтения во время компиляции, вам необходимо написать процедурный макрос для решения такой проблемы.
Вы можете найти информацию со следующими обозначениями в вашем макросе.
- Имя поля с
ident
- Атрибут содержимого с
meta
После того, как вы найдете имя поля и свою мету, вы можете сопоставить строковый результат с заданным входным параметром в макросе, как показано ниже:
macro_rules! my_macro {
(struct $name:ident {
$(#[$field_attribute:meta] $field_name:ident: $field_type:ty,)*
}) => {
struct $name {
$(#[$field_attribute] $field_name: $field_type,)*
}
impl $name {
fn get_field_attribute(field_name_prm : &str) -> &'static str {
let fields = vec![$(stringify!($field_name,$field_attribute)),*];
let mut ret_val = "Field Not Found";
fields.iter().for_each(|field_str| {
let parts : Vec<&str> = field_str.split(' ').collect();
if parts[0] == field_name_prm{
ret_val = parts[2];
}
});
ret_val
}
}
}
}
my_macro! {
struct S {
#[serde(default)]
field1: String,
#[serde(default)]
field2: String,
}
}
Обратите внимание, что предполагается, что каждое поле вструктура имеет атрибут.И каждое объявление поля заканчивается ,
, включая последнее поле.Но с некоторыми изменениями в регулярном выражении вы можете сделать его доступным и для необязательных атрибутов.
Здесь рабочее решение в Playground
Для получения дополнительной информации о обозначениях здесь ссылка
Также вы можете быстро просмотреть процедурные макросы здесь