aws_sdk_compile_checks_macro/
lib.rs

1#![doc = include_str!("../README.md")]
2use proc_macro::TokenStream;
3
4use quote::quote;
5use syn::{parse_macro_input, ItemFn};
6
7use crate::attributes::Attributes;
8use crate::findings::UsageFinds;
9use crate::required_properties::{create_required_props_map, valid_sdks};
10
11mod attributes;
12mod required_properties;
13mod visitor;
14mod findings;
15
16/// Adding this attribute to a function or method will make it check for AWS SDK calls that are missing required properties
17/// (properties that, if missing, would cause a panic at runtime)
18/// Example:
19/// ```rust
20/// use aws_sdk_compile_checks_macro::required_props;
21///
22/// #[required_props]
23/// fn some_function() {
24///     // instantiate an AWS client
25///     // will check the calls it makes for missing required properties
26/// }
27/// ```
28#[proc_macro_attribute]
29pub fn required_props(attrs: TokenStream, input: TokenStream) -> TokenStream {
30    let attributes: Attributes = parse_macro_input!(attrs);
31    let item: ItemFn = parse_macro_input!(input);
32    let required_props = create_required_props_map();
33
34    let Attributes { sdks, span } = attributes;
35    match valid_sdks(&required_props, &sdks) {
36        Ok(_) => {}
37        Err(e) => {
38            return syn::Error::new(
39                span,
40                format!("some of the SDKs you specified do not exist in our list of supported SDKs: {}", e),
41            )
42            .to_compile_error()
43            .into();
44        }
45    }
46
47    let visitor = visitor::MethodVisitor::new(&item, required_props);
48    let improper = visitor.find_improper_usages(sdks);
49
50    let errors: Vec<proc_macro2::TokenStream> = improper
51        .into_iter()
52        .map(UsageFinds::into_compile_error)
53        .collect();
54
55    quote!(
56        #(#errors)*
57        #item
58    )
59    .into()
60}