#rust #rust-proc-macros
Вопрос:
Мне нужно иметь возможность извлекать дизель-манипулятор типа, в идеале таким образом, чтобы можно было воспроизводить атрибуты data_loader для преобразования в несколько типов.
#[derive(Loadable)]
#[data_loader(handler = DieselHandler<FooLoader>)]
Если я использую handler: syn::Type
, возникает ошибка:
граница признака
syn::Type: FromMeta
не удовлетворена признакFromMeta
не реализован дляsyn::Type
Как я могу передать тип здесь и, возможно, даже проверить структуру оболочки?
#[derive(Debug, FromDeriveInput)]
#[darling(attributes(data_loader))]
struct LoadByArgs {
#[darling(default)]
internal: bool,
handler: ????,
}
#[proc_macro_derive(Loadable, attributes(data_loader))]
pub fn load_by(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let LoadByArgs {
internal, handler
} = FromDeriveInput::from_derive_input(amp;input).expect("can't parse attribute");
let expanded = quote! {
...
};
proc_macro::TokenStream::from(expanded)
}
Комментарии:
1. Я не добился большого успеха в этом, не выражая типы в виде строк. т.
#[data_loader(handler = "DieselHandler<FooLoader>")]
е..handler
затем может быть asyn::Path
в вашем коде.2. Я думаю, это потому, что darling уже некоторое время не обновлялся, и раньше это было синтаксическим ограничением.
3. Я надеялся сделать это без кавычек и в идеале с таким синтаксисом, как
#[data_loader(DieselHandler<FooLoader>)]
. Знаете ли вы о милой альтернативе, которая помогла бы здесь? Я никогда раньше не пытался написать процедурный макрос, поэтому я все еще собираю вещи4. Нет, я ничего не видел. Но дорогая действительно делает жизнь намного проще, когда у тебя есть атрибуты. Это спасло меня от 100 строк очень грязного кода.
5. Да, я определенно вижу ценность и действительно не хочу писать ничего из этого от руки. Надеюсь, дорогая добавит поддержку или, возможно, примеры, если это уже возможно
Ответ №1:
darling
требует кавычек при написании #[attr(foo = "bar")]
, потому syn
что не считает форму без кавычек допустимой Meta
, и Meta
это основа darling
всего API.
Это согласуется с serde
тем , что я по-прежнему рассматриваю как наиболее близкое к стандарту для API-интерфейсов proc-macro в Rust.
Вы можете использовать darling::util::PathList
, если хотите написать что-то подобное #[data_loader(DieselHandler)]
. Технически параметры типа являются частью пути, поэтому DieselHandler<FooLoader>
должны работать на бумаге.