aws_smithy_runtime_api_macros/
lib.rs1#![cfg_attr(docsrs, feature(doc_cfg))]
8use proc_macro::TokenStream;
13use quote::quote;
14use syn::{parse_macro_input, ImplItem, ItemImpl};
15
16const KNOWN_HOOKS: &[&str] = &[
20 "read_before_execution",
21 "modify_before_serialization",
22 "read_before_serialization",
23 "read_after_serialization",
24 "modify_before_retry_loop",
25 "read_before_attempt",
26 "modify_before_signing",
27 "read_before_signing",
28 "read_after_signing",
29 "modify_before_transmit",
30 "read_before_transmit",
31 "read_after_transmit",
32 "modify_before_deserialization",
33 "read_before_deserialization",
34 "read_after_deserialization",
35 "modify_before_attempt_completion",
36 "read_after_attempt",
37 "modify_before_completion",
38 "read_after_execution",
39];
40
41const _: () = assert!(
42 KNOWN_HOOKS.len() <= 32,
43 "OverriddenHooks uses a u32 bitmask; widen to u64 in interceptors.rs if more hooks are needed"
44);
45
46#[proc_macro_attribute]
63pub fn dyn_dispatch_hint(_attr: TokenStream, item: TokenStream) -> TokenStream {
64 let mut impl_block = parse_macro_input!(item as ItemImpl);
65
66 let overridden: Vec<String> = impl_block
67 .items
68 .iter()
69 .filter_map(|item| {
70 if let ImplItem::Fn(method) = item {
71 let name = method.sig.ident.to_string();
72 if KNOWN_HOOKS.contains(&name.as_str()) {
73 Some(name)
74 } else {
75 None
76 }
77 } else {
78 None
79 }
80 })
81 .collect();
82
83 let flags: Vec<proc_macro2::TokenStream> = overridden
84 .iter()
85 .map(|name| {
86 let upper = name.to_uppercase();
87 let ident = syn::Ident::new(&upper, proc_macro2::Span::call_site());
88 quote! { ::aws_smithy_runtime_api::client::interceptors::OverriddenHooks::#ident }
89 })
90 .collect();
91
92 let body = if flags.is_empty() {
93 quote! { ::aws_smithy_runtime_api::client::interceptors::OverriddenHooks::none() }
94 } else {
95 quote! { #(#flags)|* }
96 };
97
98 let method: ImplItem = syn::parse_quote! {
99 fn overridden_hooks(&self) -> ::aws_smithy_runtime_api::client::interceptors::OverriddenHooks {
100 #body
101 }
102 };
103 impl_block.items.push(method);
104
105 quote! { #impl_block }.into()
106}