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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//! Macro impl for invoking a predefined template `derive_adhoc!`
use super::prelude::*;
#[derive(Debug, Clone)]
struct TemplateInvocation {
driver: syn::Path,
options: UnprocessedOptions,
colon: Token![:],
template: TokenStream,
}
impl Parse for TemplateInvocation {
fn parse(input: ParseStream) -> syn::Result<Self> {
let driver = input.parse()?;
let options = UnprocessedOptions::parse(&input, OpContext::Template)?;
let colon = input.parse()?;
let template = input.parse()?;
Ok(TemplateInvocation {
driver,
options,
colon,
template,
})
}
}
/// This is `derive_adhoc!`
///
/// It parses
/// ```rust,ignore
/// StructName:
/// SOME_TOKENS
/// ```
/// and expand it to an invocation of
/// ```rust,ignore
/// derive_adhoc_driver_StructName
/// ```
/// as per NOTES.txt.
pub fn derive_adhoc_func_macro(
input: TokenStream,
) -> Result<TokenStream, syn::Error> {
let TemplateInvocation {
driver,
options,
colon,
template,
} = syn::parse2(input)?;
// eprintln!("---------- derive_adhoc got start ----------");
// eprintln!("{}\n{}", &driver.to_token_stream(), &template);
// eprintln!("---------- derive_adhoc got end ----------");
let driver_mac_name = {
let mut name = driver;
let last = name.segments.last_mut().ok_or_else(|| {
colon.error(
"expected non-empty path for driver struct name, found colon",
)
})?;
last.ident = format_ident!("derive_adhoc_driver_{}", &last.ident);
name
};
let output = quote! {
#driver_mac_name !{
{ #template }
{ ($) }
crate; [#options] ;
}
};
// eprintln!("---------- derive_adhoc! output start ----------");
// eprintln!("{}", &output);
// eprintln!("---------- derive_adhoc! output end ----------");
Ok(output)
}