anchor-syn 1.2.0

Anchor syntax parsing and code generation tools
Documentation
use {
    super::{generics, ParsedGenerics},
    crate::AccountsStruct,
    quote::quote,
};

pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream {
    let name = &accs.ident;
    let ParsedGenerics {
        combined_generics,
        trait_generics: _,
        struct_generics,
        where_clause,
    } = generics(accs);

    let shorten_invariant_lifetime = if accs.generics.lt_token.is_some() {
        let non_lifetime_generics = struct_generics
            .iter()
            .skip_while(|g| matches!(g, syn::GenericParam::Lifetime(_)))
            .fold(quote! {}, |acc, g| quote! { #acc, #g });
        quote! {
            pub unsafe fn __shorten_invariant_lifetime<'__a, '__info: '__a>(
                value: &'__a mut #name<'__info #non_lifetime_generics>,
            ) -> &'__a mut #name<'__a #non_lifetime_generics> {
                unsafe { ::core::mem::transmute(value) }
            }
        }
    } else {
        quote! {
            pub fn __shorten_invariant_lifetime(value: &mut Self) -> &mut Self {
                value
            }
        }
    };

    quote! {
        #[automatically_derived]
        impl<#combined_generics> #name<#struct_generics> #where_clause {
            #[doc(hidden)]
            #[inline(always)]
            #shorten_invariant_lifetime
        }
    }
}