hooks_macro_core/
detected.rs1use proc_macro2::{Span, TokenStream};
2use quote::{quote_spanned, ToTokens};
3
4pub struct DetectedHooksTokens {
5 pub fn_arg_data_pat: TokenStream,
6 pub fn_stmts_extract_data: Option<TokenStream>,
7}
8
9pub struct DetectedHook {
10 pub ident: syn::Ident,
11}
12
13pub fn detected_hooks_to_tokens(
14 mut used_hooks: Vec<DetectedHook>,
15 hooks_core_path: impl ToTokens,
16 span: Span,
17) -> DetectedHooksTokens {
18 match used_hooks.len() {
19 0 => DetectedHooksTokens {
20 fn_arg_data_pat: quote_spanned! {span=>
21 _: ::core::pin::Pin<&mut #hooks_core_path::HookTuple::<()>>
22 },
23 fn_stmts_extract_data: None,
24 },
25 1 => {
26 let DetectedHook { ident } = used_hooks.pop().unwrap();
27 DetectedHooksTokens {
28 fn_arg_data_pat: quote_spanned! {span=>
29 #ident: ::core::pin::Pin<&mut _>
30 },
31 fn_stmts_extract_data: None,
32 }
33 }
34 _ => {
35 let ident_hooks_data = syn::Ident::new("__hooks_hook_data", span);
36
37 let used_id = used_hooks.iter().map(|h| &h.ident);
38
39 let impl_extract_hooks_data = quote_spanned! {span=>
40 #hooks_core_path::__impl_pin_project_hook_tuple!(#ident_hooks_data, #(#used_id,)*);
42 };
43
44 DetectedHooksTokens {
45 fn_arg_data_pat: quote_spanned! {span=>
46 #ident_hooks_data: ::core::pin::Pin<&mut _>
47 },
48 fn_stmts_extract_data: Some(impl_extract_hooks_data),
49 }
50 }
51 }
52}