diplomat/
transparent_convert.rs

1use quote::quote;
2use syn::*;
3
4pub 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                unsafe {
25                    &*(from as *const #field1 as *const Self)
26                }
27            }
28        }
29    }
30}