• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use quote::quote;
2 use syn::*;
3 
gen_transparent_convert(s: ItemStruct) -> proc_macro2::TokenStream4 pub fn gen_transparent_convert(s: ItemStruct) -> proc_macro2::TokenStream {
5     let mut fields = s.fields.iter();
6     let field1 = if let Some(field1) = fields.next() {
7         &field1.ty
8     } else {
9         panic!("#[diplomat::transparent_convert] only allowed on structs with a single field")
10     };
11 
12     if fields.next().is_some() {
13         panic!("#[diplomat::transparent_convert] only allowed on structs with a single field")
14     }
15     let struct_name = &s.ident;
16     let (impl_generics, ty_generics, _) = s.generics.split_for_impl();
17     let mut impl_generics: Generics = parse_quote!(#impl_generics);
18     let custom_lifetime: GenericParam = parse_quote!('transparent_convert_outer);
19     impl_generics.params.push(custom_lifetime);
20     quote! {
21         impl #impl_generics #struct_name #ty_generics {
22             // can potentially add transparent_convert_owned, _mut later
23             pub(crate) fn transparent_convert(from: &'transparent_convert_outer #field1) -> &'transparent_convert_outer Self {
24                 // Safety: This is safe because the caller of gen_transparent_convert
25                 // adds a repr(transparent) to the struct.
26                 unsafe {
27                     &*(from as *const #field1 as *const Self)
28                 }
29             }
30         }
31     }
32 }
33