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 79
|
//! Macro impl for adhoc template application `derive_deftly_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::TemplateAdhoc)?;
let colon = input.parse()?;
let template = input.parse()?;
Ok(TemplateInvocation {
driver,
options,
colon,
template,
})
}
}
/// This is `derive_deftly_adhoc!`
///
/// It parses
/// ```rust,ignore
/// StructName:
/// SOME_TOKENS
/// ```
/// and expand it to an invocation of
/// ```rust,ignore
/// derive_deftly_driver_StructName
/// ```
/// as per NOTES.txt.
pub fn derive_deftly_adhoc(
input: TokenStream,
) -> Result<TokenStream, syn::Error> {
let TemplateInvocation {
driver,
options,
colon,
template,
} = syn::parse2(input)?;
dprint_block!(
[&driver.to_token_stream(), &template],
"derive_deftly_adhoc! input",
);
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_deftly_driver_{}", &last.ident);
name
};
let output = quote! {
#driver_mac_name !{
{ #template }
{ ($) }
( crate; [#options] ; )
[] []
}
};
dprint_block!(&output, "derive_deftly_adhoc! output");
Ok(output)
}
|