1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
use darling::FromDeriveInput;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};
#[derive(FromDeriveInput)]
#[darling(attributes(local_queue))]
#[darling(default)]
struct LocalQueueOpt {
buffer_size: usize,
}
impl Default for LocalQueueOpt {
fn default() -> Self {
LocalQueueOpt { buffer_size: 2048 }
}
}
#[proc_macro_derive(LocalQueue, attributes(local_queue))]
pub fn derive_local_queue(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let ident = &input.ident;
let LocalQueueOpt { buffer_size } = match FromDeriveInput::from_derive_input(&input) {
Ok(attr) => attr,
Err(err) => {
return err.write_errors().into();
}
};
let expanded = quote! {
stack_queue::sa::const_assert!(#buffer_size >= stack_queue::MIN_BUFFER_LEN);
stack_queue::sa::const_assert!(#buffer_size <= stack_queue::MAX_BUFFER_LEN);
impl stack_queue::LocalQueue<#buffer_size> for #ident {
fn queue() -> &'static std::thread::LocalKey<stack_queue::StackQueue<Self, #buffer_size>> {
thread_local! {
static QUEUE: stack_queue::StackQueue<#ident, #buffer_size> = stack_queue::StackQueue::default();
}
&QUEUE
}
}
};
expanded.into()
}