Pass `with_ref_lifetime` through to rust-type-printing from C-path printing
[ldk-c-bindings] / c-bindings-gen / src / main.rs
index 76938baf2cf7ab44a0cf89b1b65713672d3112e6..42fd470da778207a5dcd039c56dc869e670b3c1d 100644 (file)
@@ -163,7 +163,7 @@ fn maybe_convert_trait_impl<W: std::io::Write>(w: &mut W, trait_path: &syn::Path
 
                                write!(w, "\tlet res: ").unwrap();
                                // At least in one case we need type annotations here, so provide them.
-                               types.write_rust_type(w, Some(generics), &res_ty);
+                               types.write_rust_type(w, Some(generics), &res_ty, false);
 
                                if t == "lightning::util::ser::ReadableArgs" {
                                        writeln!(w, " = crate::c_types::deserialize_obj_arg(ser, arg_conv);").unwrap();
@@ -484,7 +484,7 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                                                                                }
                                                                                _ => panic!("5"),
                                                                        }
-                                                                       $type_resolver.write_rust_type(w, Some(&gen_types), &*arg.ty);
+                                                                       $type_resolver.write_rust_type(w, Some(&gen_types), &*arg.ty, false);
                                                                }
                                                        }
                                                }
@@ -492,7 +492,7 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                                                match &m.sig.output {
                                                        syn::ReturnType::Type(_, rtype) => {
                                                                write!(w, " -> ").unwrap();
-                                                               $type_resolver.write_rust_type(w, Some(&gen_types), &*rtype)
+                                                               $type_resolver.write_rust_type(w, Some(&gen_types), &*rtype, false)
                                                        },
                                                        _ => {},
                                                }
@@ -1594,8 +1594,37 @@ fn writeln_enum<'a, 'b, W: std::io::Write>(w: &mut W, e: &'a syn::ItemEnum, type
 
        let mut needs_free = false;
        let mut constr = Vec::new();
+       let mut is_clonable = true;
 
-       writeln!(w, "#[must_use]\n#[derive(Clone)]\n#[repr(C)]\npub enum {} {{", e.ident).unwrap();
+       for var in e.variants.iter() {
+               if let syn::Fields::Named(fields) = &var.fields {
+                       needs_free = true;
+                       for field in fields.named.iter() {
+                               if export_status(&field.attrs) == ExportStatus::TestOnly { continue; }
+
+                               let mut ty_checks = Vec::new();
+                               types.write_c_type(&mut ty_checks, &field.ty, Some(&gen_types), false);
+                               if !types.is_clonable(&String::from_utf8(ty_checks).unwrap()) {
+                                       is_clonable = false;
+                               }
+                       }
+               } else if let syn::Fields::Unnamed(fields) = &var.fields {
+                       for field in fields.unnamed.iter() {
+                               let mut ty_checks = Vec::new();
+                               types.write_c_type(&mut ty_checks, &field.ty, Some(&gen_types), false);
+                               let ty = String::from_utf8(ty_checks).unwrap();
+                               if ty != "" && !types.is_clonable(&ty) {
+                                       is_clonable = false;
+                               }
+                       }
+               }
+       }
+
+       if is_clonable {
+               writeln!(w, "#[derive(Clone)]").unwrap();
+               types.crate_types.set_clonable(format!("{}::{}", types.module_path, e.ident));
+       }
+       writeln!(w, "#[must_use]\n#[repr(C)]\npub enum {} {{", e.ident).unwrap();
        for var in e.variants.iter() {
                assert_eq!(export_status(&var.attrs), ExportStatus::Export); // We can't partially-export a mirrored enum
                writeln_docs(w, &var.attrs, "\t");
@@ -1803,9 +1832,13 @@ fn writeln_enum<'a, 'b, W: std::io::Write>(w: &mut W, e: &'a syn::ItemEnum, type
                }
        }
 
-       write_conv!(format!("to_native(&self) -> native{}", e.ident), false, true);
+       if is_clonable {
+               write_conv!(format!("to_native(&self) -> native{}", e.ident), false, true);
+       }
        write_conv!(format!("into_native(self) -> native{}", e.ident), false, false);
-       write_conv!(format!("from_native(native: &native{}) -> Self", e.ident), true, true);
+       if is_clonable {
+               write_conv!(format!("from_native(native: &native{}) -> Self", e.ident), true, true);
+       }
        write_conv!(format!("native_into(native: native{}) -> Self", e.ident), true, false);
        writeln!(w, "}}").unwrap();
 
@@ -1813,11 +1846,13 @@ fn writeln_enum<'a, 'b, W: std::io::Write>(w: &mut W, e: &'a syn::ItemEnum, type
                writeln!(w, "/// Frees any resources used by the {}", e.ident).unwrap();
                writeln!(w, "#[no_mangle]\npub extern \"C\" fn {}_free(this_ptr: {}) {{ }}", e.ident, e.ident).unwrap();
        }
-       writeln!(w, "/// Creates a copy of the {}", e.ident).unwrap();
-       writeln!(w, "#[no_mangle]").unwrap();
-       writeln!(w, "pub extern \"C\" fn {}_clone(orig: &{}) -> {} {{", e.ident, e.ident, e.ident).unwrap();
-       writeln!(w, "\torig.clone()").unwrap();
-       writeln!(w, "}}").unwrap();
+       if is_clonable {
+               writeln!(w, "/// Creates a copy of the {}", e.ident).unwrap();
+               writeln!(w, "#[no_mangle]").unwrap();
+               writeln!(w, "pub extern \"C\" fn {}_clone(orig: &{}) -> {} {{", e.ident, e.ident, e.ident).unwrap();
+               writeln!(w, "\torig.clone()").unwrap();
+               writeln!(w, "}}").unwrap();
+       }
        w.write_all(&constr).unwrap();
        write_cpp_wrapper(cpp_headers, &format!("{}", e.ident), needs_free, None);
 }