Skip to content

Commit 92f61cf

Browse files
committed
Add default _new for all-pub structs and _free for all structs
1 parent 88435fe commit 92f61cf

File tree

14 files changed

+600
-47
lines changed

14 files changed

+600
-47
lines changed

c-bindings-gen/src/main.rs

+38-6
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,8 @@ fn println_opaque(ident: &syn::Ident, struct_name: &str, generics: &syn::Generic
453453
write!(extra_headers, "struct ln{}Opaque;\ntypedef struct ln{}Opaque LDKln{};\n", ident, ident, ident).unwrap();
454454
println_docs(&attrs, "");
455455
println!("#[repr(C)]\npub struct {} {{\n\tpub(crate) inner: *const ln{},\n}}\n", struct_name, ident);
456+
println!("#[no_mangle]\npub extern \"C\" fn {}_free(this_ptr: {}) {{", struct_name, struct_name);
457+
println!("\tlet _ = unsafe {{ Box::from_raw(this_ptr.inner as *mut ln{}) }};\n}}", struct_name);
456458
}
457459

458460
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
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]\npub 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]\npub 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

Comments
 (0)