use quote::quote; use syn::*; pub fn gen_transparent_convert(s: ItemStruct) -> proc_macro2::TokenStream { let mut fields = s.fields.iter(); let field1 = if let Some(field1) = fields.next() { &field1.ty } else { panic!("#[diplomat::transparent_convert] only allowed on structs with a single field") }; if fields.next().is_some() { panic!("#[diplomat::transparent_convert] only allowed on structs with a single field") } let struct_name = &s.ident; let (impl_generics, ty_generics, _) = s.generics.split_for_impl(); let mut impl_generics: Generics = parse_quote!(#impl_generics); let custom_lifetime: GenericParam = parse_quote!('transparent_convert_outer); impl_generics.params.push(custom_lifetime); quote! { impl #impl_generics #struct_name #ty_generics { // can potentially add transparent_convert_owned, _mut later pub(crate) fn transparent_convert(from: &'transparent_convert_outer #field1) -> &'transparent_convert_outer Self { unsafe { &*(from as *const #field1 as *const Self) } } } } }