[bindings] Update eq/clone trait fns to take object, not this_arg
[rust-lightning] / c-bindings-gen / src / main.rs
index 4edad55d1fb9ff9ae071802e76ba5287e77b46dc..4193f6d36206c14bc47c3aa733b23b355f5e529e 100644 (file)
@@ -226,7 +226,8 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                        generated_fields.push("clone".to_owned());
                },
                ("std::cmp::Eq", _) => {
-                       writeln!(w, "\tpub eq: extern \"C\" fn (this_arg: *const c_void, other_arg: *const c_void) -> bool,").unwrap();
+                       writeln!(w, "\tpub eq: extern \"C\" fn (this_arg: *const c_void, other_arg: &{}) -> bool,", trait_name).unwrap();
+                       writeln!(extra_headers, "typedef struct LDK{} LDK{};", trait_name, trait_name).unwrap();
                        generated_fields.push("eq".to_owned());
                },
                ("std::hash::Hash", _) => {
@@ -251,21 +252,25 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                ("std::cmp::Eq", _) => {
                        writeln!(w, "impl std::cmp::Eq for {} {{}}", trait_name).unwrap();
                        writeln!(w, "impl std::cmp::PartialEq for {} {{", trait_name).unwrap();
-                       writeln!(w, "\tfn eq(&self, o: &Self) -> bool {{ (self.eq)(self.this_arg, o.this_arg) }}\n}}").unwrap();
+                       writeln!(w, "\tfn eq(&self, o: &Self) -> bool {{ (self.eq)(self.this_arg, o) }}\n}}").unwrap();
                },
                ("std::hash::Hash", _) => {
                        writeln!(w, "impl std::hash::Hash for {} {{", trait_name).unwrap();
                        writeln!(w, "\tfn hash<H: std::hash::Hasher>(&self, hasher: &mut H) {{ hasher.write_u64((self.hash)(self.this_arg)) }}\n}}").unwrap();
                },
                ("Clone", _) => {
-                       writeln!(w, "impl Clone for {} {{", trait_name).unwrap();
-                       writeln!(w, "\tfn clone(&self) -> Self {{").unwrap();
-                       writeln!(w, "\t\tSelf {{").unwrap();
-                       writeln!(w, "\t\tthis_arg: if let Some(f) = self.clone {{ (f)(self.this_arg) }} else {{ self.this_arg }},").unwrap();
+                       writeln!(w, "#[no_mangle]").unwrap();
+                       writeln!(w, "pub extern \"C\" fn {}_clone(orig: &{}) -> {} {{", trait_name, trait_name, trait_name).unwrap();
+                       writeln!(w, "\t{} {{", trait_name).unwrap();
+                       writeln!(w, "\t\tthis_arg: if let Some(f) = orig.clone {{ (f)(orig.this_arg) }} else {{ orig.this_arg }},").unwrap();
                        for field in generated_fields.iter() {
-                               writeln!(w, "\t\t\t{}: self.{}.clone(),", field, field).unwrap();
+                               writeln!(w, "\t\t{}: orig.{}.clone(),", field, field).unwrap();
                        }
-                       writeln!(w, "\t\t}}\n\t}}\n}}").unwrap();
+                       writeln!(w, "\t}}\n}}").unwrap();
+                       writeln!(w, "impl Clone for {} {{", trait_name).unwrap();
+                       writeln!(w, "\tfn clone(&self) -> Self {{").unwrap();
+                       writeln!(w, "\t\t{}_clone(self)", trait_name).unwrap();
+                       writeln!(w, "\t}}\n}}").unwrap();
                },
                (s, i) => {
                        if s != "util::events::MessageSendEventsProvider" { unimplemented!(); }
@@ -450,6 +455,10 @@ fn writeln_opaque<W: std::io::Write>(w: &mut W, ident: &syn::Ident, struct_name:
                                                                        writeln!(w, "pub(crate) extern \"C\" fn {}_clone_void(this_ptr: *const c_void) -> *mut c_void {{", struct_name).unwrap();
                                                                        writeln!(w, "\tBox::into_raw(Box::new(unsafe {{ (*(this_ptr as *mut native{})).clone() }})) as *mut c_void", struct_name).unwrap();
                                                                        writeln!(w, "}}").unwrap();
+                                                                       writeln!(w, "#[no_mangle]").unwrap();
+                                                                       writeln!(w, "pub extern \"C\" fn {}_clone(orig: &{}) -> {} {{", struct_name, struct_name, struct_name).unwrap();
+                                                                       writeln!(w, "\t{} {{ inner: Box::into_raw(Box::new(unsafe {{ &*orig.inner }}.clone())), is_owned: true }}", struct_name).unwrap();
+                                                                       writeln!(w, "}}").unwrap();
                                                                        break 'attr_loop;
                                                                }
                                                        }
@@ -991,6 +1000,10 @@ fn writeln_enum<'a, 'b, W: std::io::Write>(w: &mut W, e: &'a syn::ItemEnum, type
        if needs_free {
                writeln!(w, "#[no_mangle]\npub extern \"C\" fn {}_free(this_ptr: {}) {{ }}", e.ident, 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();
        write_cpp_wrapper(cpp_headers, &format!("{}", e.ident), needs_free);
 }