1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
use crate::helpers::*; impl ::quote::ToTokens for crate::Data { fn to_tokens(&self, tokens: &mut ::proc_macro2::TokenStream) { let ffi_name = self.ident.clone().prefix("FFI"); if self.opaque { self.opaque_to_tokens(ffi_name, tokens) } else { match &self.data { ::darling::ast::Data::Struct(fds) => self.struct_to_tokens(ffi_name, fds, tokens), ::darling::ast::Data::Enum(vars) => self.enum_to_tokens(ffi_name, vars, tokens), } } } } impl crate::Data { pub(crate) fn validate(self) -> Self { if let ::darling::ast::Data::Enum(_) = &self.data { if self.constructor.is_some() { panic!("in enums, please specifies constructors per-variant"); } } self } fn opaque_to_tokens(&self, ffi_name: ::syn::Ident, tokens: &mut ::proc_macro2::TokenStream) { let orig_name = &self.ident; tokens.extend(::quote::quote! { pub struct #ffi_name(#orig_name); }); } fn enum_to_tokens( &self, ffi_name: ::syn::Ident, variants: &Vec<crate::Variant>, tokens: &mut ::proc_macro2::TokenStream, ) { let variants: Vec<_> = variants.iter().map(|v| v.fold()).collect(); tokens.extend(::quote::quote! { #[repr(u16)] pub enum #ffi_name { #(#variants),* } }); } fn struct_to_tokens( &self, ffi_name: ::syn::Ident, fields: &::darling::ast::Fields<crate::Field>, tokens: &mut ::proc_macro2::TokenStream, ) { let ffi_fields: Vec<::syn::Field> = fields.iter().map(|f| f.fold()).collect(); tokens.extend(match fields.style { ::darling::ast::Style::Tuple => ::quote::quote! { #[repr(C)] pub struct #ffi_name(#(#ffi_fields),*); }, ::darling::ast::Style::Struct => ::quote::quote! { #[repr(C)] pub struct #ffi_name { #(#ffi_fields),* } }, ::darling::ast::Style::Unit => ::quote::quote! { #[repr(C)] pub struct #ffi_name; }, }); } }