@@ -453,6 +453,8 @@ fn println_opaque(ident: &syn::Ident, struct_name: &str, generics: &syn::Generic
453453 write ! ( extra_headers, "struct ln{}Opaque;\n typedef struct ln{}Opaque LDKln{};\n " , ident, ident, ident) . unwrap ( ) ;
454454 println_docs ( & attrs, "" ) ;
455455 println ! ( "#[repr(C)]\n pub struct {} {{\n \t pub(crate) inner: *const ln{},\n }}\n " , struct_name, ident) ;
456+ println ! ( "#[no_mangle]\n pub extern \" C\" fn {}_free(this_ptr: {}) {{" , struct_name, struct_name) ;
457+ println ! ( "\t let _ = unsafe {{ Box::from_raw(this_ptr.inner as *mut ln{}) }};\n }}" , struct_name) ;
456458}
457459
458460fn println_struct ( s : & syn:: ItemStruct , module_path : & str , types : & mut TypeResolver , extra_headers : & mut File ) {
@@ -475,16 +477,18 @@ fn println_struct(s: &syn::ItemStruct, module_path: &str, types: &mut TypeResolv
475477 eprintln ! ( "exporting fields for {}" , struct_name) ;
476478 if let syn:: Fields :: Named ( fields) = & s. fields {
477479 let mut gen_types = GenericTypes :: new ( ) ;
478- if !gen_types. learn_generics ( & s. generics , types) {
479- eprintln ! ( "Not implementing anything for struct {} due to not understood generics" , struct_name) ;
480- }
480+ assert ! ( gen_types. learn_generics( & s. generics, types) ) ;
481481
482+ let mut all_fields_settable = true ;
482483 for field in fields. named . iter ( ) {
483484 if let syn:: Visibility :: Public ( _) = field. vis {
484485 let export = export_status ( & field. attrs ) ;
485486 match export {
486487 ExportStatus :: Export => { } ,
487- ExportStatus :: NoExport |ExportStatus :: TestOnly => continue ,
488+ ExportStatus :: NoExport |ExportStatus :: TestOnly => {
489+ all_fields_settable = false ;
490+ continue
491+ } ,
488492 ExportStatus :: Rename ( _) => { unimplemented ! ( ) ; } ,
489493 }
490494
@@ -507,18 +511,46 @@ fn println_struct(s: &syn::ItemStruct, module_path: &str, types: &mut TypeResolv
507511 print ! ( "#[no_mangle]\n pub extern \" C\" fn {}_set_{}(this_ptr: *mut {}, val: " , struct_name, ident, struct_name) ;
508512 types. print_c_type ( & field. ty , Some ( & gen_types) ) ;
509513 print ! ( ") {{\n \t " ) ;
510- types. print_from_c_conversion_new_var ( & ident, & field. ty , Some ( & gen_types) ) ;
514+ if types. print_from_c_conversion_new_var ( & ident, & field. ty , Some ( & gen_types) ) {
515+ print ! ( "\n \t " ) ;
516+ }
511517 print ! ( "unsafe {{ &mut *((*this_ptr).inner as *mut ln{}) }}.{} = " , s. ident, ident) ;
512518 types. print_from_c_conversion_prefix ( & field. ty , Some ( & gen_types) ) ;
513519 print ! ( "val" ) ;
514520 types. print_from_c_conversion_suffix ( & field. ty , Some ( & gen_types) ) ;
515521 println ! ( ";\n }}" ) ;
516- }
522+ } else { all_fields_settable = false ; }
523+ } else { all_fields_settable = false ; }
524+ } else { all_fields_settable = false ; }
525+ }
526+
527+ if all_fields_settable {
528+ // Build a constructor!
529+ print ! ( "#[no_mangle]\n pub extern \" C\" fn {}_new(" , struct_name) ;
530+ for ( idx, field) in fields. named . iter ( ) . enumerate ( ) {
531+ if idx != 0 { print ! ( ", " ) ; }
532+ print ! ( "{}_arg: " , field. ident. as_ref( ) . unwrap( ) ) ;
533+ types. print_c_type ( & field. ty , Some ( & gen_types) ) ;
534+ }
535+ print ! ( ") -> {} {{\n \t " , struct_name) ;
536+ for field in fields. named . iter ( ) {
537+ if types. print_from_c_conversion_new_var ( & field. ident . as_ref ( ) . unwrap ( ) , & field. ty , Some ( & gen_types) ) {
538+ print ! ( "\n \t " ) ;
517539 }
518540 }
541+ println ! ( "{} {{ inner: Box::into_raw(Box::new(ln{} {{" , struct_name, s. ident) ;
542+ for field in fields. named . iter ( ) {
543+ print ! ( "\t \t {}: " , field. ident. as_ref( ) . unwrap( ) ) ;
544+ types. print_from_c_conversion_prefix ( & field. ty , Some ( & gen_types) ) ;
545+ print ! ( "{}_arg" , field. ident. as_ref( ) . unwrap( ) ) ;
546+ types. print_from_c_conversion_suffix ( & field. ty , Some ( & gen_types) ) ;
547+ println ! ( "," ) ;
548+ }
549+ println ! ( "\t }}))}}\n }}" ) ;
519550 }
520551 }
521552
553+
522554 types. struct_imported ( & s. ident , struct_name. clone ( ) ) ;
523555}
524556
0 commit comments