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]
52pub fn known_hooks(_input: TokenStream) -> TokenStream {
53 let names = KNOWN_HOOKS.iter();
54 quote::quote! { &[#(#names),*] }.into()
55}
56
57#[proc_macro_attribute]
74pub fn dyn_dispatch_hint(_attr: TokenStream, item: TokenStream) -> TokenStream {
75 let mut impl_block = parse_macro_input!(item as ItemImpl);
76
77 let overridden: Vec<String> = impl_block
78 .items
79 .iter()
80 .filter_map(|item| {
81 if let ImplItem::Fn(method) = item {
82 let name = method.sig.ident.to_string();
83 if KNOWN_HOOKS.contains(&name.as_str()) {
84 Some(name)
85 } else {
86 None
87 }
88 } else {
89 None
90 }
91 })
92 .collect();
93
94 let flags: Vec<proc_macro2::TokenStream> = overridden
95 .iter()
96 .map(|name| {
97 let upper = name.to_uppercase();
98 let ident = syn::Ident::new(&upper, proc_macro2::Span::call_site());
99 quote! { ::aws_smithy_runtime_api::client::interceptors::OverriddenHooks::#ident }
100 })
101 .collect();
102
103 let body = if flags.is_empty() {
104 quote! { ::aws_smithy_runtime_api::client::interceptors::OverriddenHooks::none() }
105 } else {
106 quote! { #(#flags)|* }
107 };
108
109 let method: ImplItem = syn::parse_quote! {
110 fn overridden_hooks(&self) -> ::aws_smithy_runtime_api::client::interceptors::OverriddenHooks {
111 #body
112 }
113 };
114 impl_block.items.push(method);
115
116 quote! { #impl_block }.into()
117}