Я пытаюсь получить пользовательский атрибут для функции, которая анализирует аргументы атрибута в Queue
(структура), Exchange
(структура) и routing_key
(литерал). Они будут использоваться для объявления RabbitMq Queue
с маршрутизацией от Exchange
с routing_key
. Сама функция будет использоваться в качестве получателя сообщения. Эти детали не важны, но они являются причиной всего этого.
Я был в состоянии проанализировать аргументы как литералы так:
#[proc_macro_attribute]
pub fn consume(args: TokenStream, input: TokenStream) -> TokenStream {
let args = parse_macro_input!(args as AttributeArgs);
let arguments = args.iter().map(|arg| {
match arg {
NestedMeta::Lit(Lit::Str(lit)) => lit.value(),
_ => "".to_string()
}
}).collect::<Vec<String>>();
let queue = arguments.get(0);
let exchange = arguments.get(1);
let routing_key = arguments.get(2);
declare_queue(queue);
declare_exchange(exchange);
declare_binding(exchange, routing_key, queue);
input
}
Атрибут используется следующим образом:
#[consume("my.queue", "my.exchange", "my.routing.key")]
fn my_test(message: String) {
println!("Received: {}", message);
}
Отсутствует та часть, где функция использовалась в качестве потребителя. Проблема этого подхода заключается в том, что очереди и обмены могут иметь свойства. Поэтому, чтобы правильно их объявить, мне понадобится такой атрибут:
#[consume(Queue { name: "my.queue", properties: { durable: true, exclusive: false, auto_delete: false } }, Exchange {name: "my.exchange", proeprties { type: "topic", durable: true, auto_delete: false } }, "my.routing.key")]
fn my_test(message: String) {
println!("Received: {}", message);
}
Как мне разобрать эти аргументы как структуры? Есть ли лучший способ добиться того, что я пытаюсь сделать?