Use trait, not impl, definition for X_as_Trait functions
[ldk-c-bindings] / c-bindings-gen / src / main.rs
index b9dba8c92e78188d3bb4abf4a80779fcb9ec2732..2aeadaffac2e3024d3c92172bc24d82b5b06ca47 100644 (file)
@@ -102,7 +102,7 @@ fn maybe_convert_trait_impl<W: std::io::Write>(w: &mut W, trait_path: &syn::Path
                        },
                        "lightning::util::ser::Readable"|"lightning::util::ser::ReadableArgs"|"lightning::util::ser::MaybeReadable" => {
                                // Create the Result<Object, DecodeError> syn::Type
-                               let mut res_ty: syn::Type = parse_quote!(Result<#for_ty, ::ln::msgs::DecodeError>);
+                               let mut res_ty: syn::Type = parse_quote!(Result<#for_ty, lightning::ln::msgs::DecodeError>);
 
                                writeln!(w, "#[no_mangle]").unwrap();
                                writeln!(w, "/// Read a {} from a byte array, created by {}_write", for_obj, for_obj).unwrap();
@@ -151,7 +151,7 @@ fn maybe_convert_trait_impl<W: std::io::Write>(w: &mut W, trait_path: &syn::Path
                                                } else { unreachable!(); }
                                        } else { unreachable!(); }
                                } else if t == "lightning::util::ser::MaybeReadable" {
-                                       res_ty = parse_quote!(Result<Option<#for_ty>, ::ln::msgs::DecodeError>);
+                                       res_ty = parse_quote!(Result<Option<#for_ty>, lightning::ln::msgs::DecodeError>);
                                }
                                write!(w, ") -> ").unwrap();
                                types.write_c_type(w, &res_ty, Some(generics), false);
@@ -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)
                                                        },
                                                        _ => {},
                                                }
@@ -735,6 +735,25 @@ fn writeln_struct<'a, 'b, W: std::io::Write>(w: &mut W, s: &'a syn::ItemStruct,
                                                write!(w, "inner_val").unwrap();
                                                types.write_to_c_conversion_inline_suffix(w, &ref_type, Some(&gen_types), true);
                                                writeln!(w, "\n}}").unwrap();
+                                       } else {
+                                               // If the type isn't reference-able, but is clonable, export a getter that just clones
+                                               if types.understood_c_type(&$field.ty, Some(&gen_types)) {
+                                                       let mut v = Vec::new();
+                                                       types.write_c_type(&mut v, &$field.ty, Some(&gen_types), true);
+                                                       let s = String::from_utf8(v).unwrap();
+                                                       if types.is_clonable(&s) {
+                                                               writeln_arg_docs(w, &$field.attrs, "", types, Some(&gen_types), vec![].drain(..), Some(&$field.ty));
+                                                               writeln!(w, "///\n/// Returns a copy of the field.").unwrap();
+                                                               write!(w, "#[no_mangle]\npub extern \"C\" fn {}_get_{}(this_ptr: &{}) -> {}", struct_name, $new_name, struct_name, s).unwrap();
+                                                               write!(w, " {{\n\tlet mut inner_val = this_ptr.get_native_mut_ref().{}.clone();\n\t", $real_name).unwrap();
+                                                               let local_var = types.write_to_c_conversion_new_var(w, &format_ident!("inner_val"), &$field.ty, Some(&gen_types), true);
+                                                               if local_var { write!(w, "\n\t").unwrap(); }
+                                                               types.write_to_c_conversion_inline_prefix(w, &$field.ty, Some(&gen_types), true);
+                                                               write!(w, "inner_val").unwrap();
+                                                               types.write_to_c_conversion_inline_suffix(w, &$field.ty, Some(&gen_types), true);
+                                                               writeln!(w, "\n}}").unwrap();
+                                                       }
+                                               }
                                        }
                                }
 
@@ -928,7 +947,7 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
                                                // mappings from a trai defined in a different file, we may mis-resolve or
                                                // fail to resolve the mapped types. Thus, we have to construct a new
                                                // resolver for the module that the trait was defined in here first.
-                                               let trait_resolver = get_module_type_resolver!(full_trait_path, types.crate_libs, types.crate_types);
+                                               let mut trait_resolver = get_module_type_resolver!(full_trait_path, types.crate_libs, types.crate_types);
                                                gen_types.learn_associated_types(trait_obj, &trait_resolver);
                                                let mut impl_associated_types = HashMap::new();
                                                for item in i.items.iter() {
@@ -1088,17 +1107,12 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
                                                                                _ => {}
                                                                        }
                                                                }
-                                                               if uncallable_function {
-                                                                       let mut trait_resolver = get_module_type_resolver!(full_trait_path, $types.crate_libs, $types.crate_types);
-                                                                       write_method_params(w, &$trait_meth.sig, "c_void", &mut trait_resolver, Some(&meth_gen_types), true, true);
-                                                               } else {
-                                                                       write_method_params(w, &$m.sig, "c_void", $types, Some(&meth_gen_types), true, true);
-                                                               }
+                                                               write_method_params(w, &$trait_meth.sig, "c_void", &mut trait_resolver, Some(&meth_gen_types), true, true);
                                                                write!(w, " {{\n\t").unwrap();
                                                                if uncallable_function {
                                                                        write!(w, "unreachable!();").unwrap();
                                                                } else {
-                                                                       write_method_var_decl_body(w, &$m.sig, "", $types, Some(&meth_gen_types), false);
+                                                                       write_method_var_decl_body(w, &$trait_meth.sig, "", &mut trait_resolver, Some(&meth_gen_types), false);
                                                                        let mut takes_self = false;
                                                                        for inp in $m.sig.inputs.iter() {
                                                                                if let syn::FnArg::Receiver(_) = inp {
@@ -1128,7 +1142,7 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
                                                                                },
                                                                                _ => {},
                                                                        }
-                                                                       write_method_call_params(w, &$m.sig, "", $types, Some(&meth_gen_types), &real_type, false);
+                                                                       write_method_call_params(w, &$trait_meth.sig, "", &mut trait_resolver, Some(&meth_gen_types), &real_type, false);
                                                                }
                                                                write!(w, "\n}}\n").unwrap();
                                                                if let syn::ReturnType::Type(_, rtype) = &$m.sig.output {
@@ -1166,7 +1180,6 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
                                                                        assert!(meth.default.is_some());
                                                                        let old_gen_types = gen_types;
                                                                        gen_types = GenericTypes::new(Some(resolved_path.clone()));
-                                                                       let mut trait_resolver = get_module_type_resolver!(full_trait_path, types.crate_libs, types.crate_types);
                                                                        impl_meth!(meth, meth, full_trait_path, trait_obj, "", &mut trait_resolver);
                                                                        gen_types = old_gen_types;
                                                                },