@@ -453,6 +453,8 @@ fn println_opaque(ident: &syn::Ident, struct_name: &str, generics: &syn::Generic
453
453
write ! ( extra_headers, "struct ln{}Opaque;\n typedef struct ln{}Opaque LDKln{};\n " , ident, ident, ident) . unwrap ( ) ;
454
454
println_docs ( & attrs, "" ) ;
455
455
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) ;
456
458
}
457
459
458
460
fn 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
475
477
eprintln ! ( "exporting fields for {}" , struct_name) ;
476
478
if let syn:: Fields :: Named ( fields) = & s. fields {
477
479
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) ) ;
481
481
482
+ let mut all_fields_settable = true ;
482
483
for field in fields. named . iter ( ) {
483
484
if let syn:: Visibility :: Public ( _) = field. vis {
484
485
let export = export_status ( & field. attrs ) ;
485
486
match export {
486
487
ExportStatus :: Export => { } ,
487
- ExportStatus :: NoExport |ExportStatus :: TestOnly => continue ,
488
+ ExportStatus :: NoExport |ExportStatus :: TestOnly => {
489
+ all_fields_settable = false ;
490
+ continue
491
+ } ,
488
492
ExportStatus :: Rename ( _) => { unimplemented ! ( ) ; } ,
489
493
}
490
494
@@ -507,18 +511,46 @@ fn println_struct(s: &syn::ItemStruct, module_path: &str, types: &mut TypeResolv
507
511
print ! ( "#[no_mangle]\n pub extern \" C\" fn {}_set_{}(this_ptr: *mut {}, val: " , struct_name, ident, struct_name) ;
508
512
types. print_c_type ( & field. ty , Some ( & gen_types) ) ;
509
513
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
+ }
511
517
print ! ( "unsafe {{ &mut *((*this_ptr).inner as *mut ln{}) }}.{} = " , s. ident, ident) ;
512
518
types. print_from_c_conversion_prefix ( & field. ty , Some ( & gen_types) ) ;
513
519
print ! ( "val" ) ;
514
520
types. print_from_c_conversion_suffix ( & field. ty , Some ( & gen_types) ) ;
515
521
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 " ) ;
517
539
}
518
540
}
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 }}" ) ;
519
550
}
520
551
}
521
552
553
+
522
554
types. struct_imported ( & s. ident , struct_name. clone ( ) ) ;
523
555
}
524
556
0 commit comments