Add function-call generic parameters when they're resovable
[ldk-c-bindings] / c-bindings-gen / src / main.rs
index da1ca4f8ecd99037896694479271a7366b40ab85..97f44a4c4c458e22ce017c0b8c53d8524077cea2 100644 (file)
@@ -33,7 +33,15 @@ mod blocks;
 use types::*;
 use blocks::*;
 
-const DEFAULT_IMPORTS: &'static str = "\nuse std::str::FromStr;\nuse std::ffi::c_void;\nuse core::convert::Infallible;\nuse bitcoin::hashes::Hash;\nuse crate::c_types::*;\n";
+const DEFAULT_IMPORTS: &'static str = "
+use alloc::str::FromStr;
+use core::ffi::c_void;
+use core::convert::Infallible;
+use bitcoin::hashes::Hash;
+use crate::c_types::*;
+#[cfg(feature=\"no-std\")]
+use alloc::{vec::Vec, boxed::Box};
+";
 
 // *************************************
 // *** Manually-expanded conversions ***
@@ -1639,10 +1647,20 @@ fn writeln_fn<'a, 'b, W: std::io::Write>(w: &mut W, f: &'a syn::ItemFn, types: &
        writeln_fn_docs(w, &f.attrs, "", types, Some(&gen_types), f.sig.inputs.iter(), &f.sig.output);
 
        write!(w, "#[no_mangle]\npub extern \"C\" fn {}(", f.sig.ident).unwrap();
+
+
        write_method_params(w, &f.sig, "", types, Some(&gen_types), false, true);
        write!(w, " {{\n\t").unwrap();
        write_method_var_decl_body(w, &f.sig, "", types, Some(&gen_types), false);
-       write!(w, "{}::{}(", types.module_path, f.sig.ident).unwrap();
+       write!(w, "{}::{}", types.module_path, f.sig.ident).unwrap();
+
+       let mut function_generic_args = Vec::new();
+       maybe_write_generics(&mut function_generic_args, &f.sig.generics, types, true);
+       if !function_generic_args.is_empty() {
+               write!(w, "::{}", String::from_utf8(function_generic_args).unwrap()).unwrap();
+       }
+       write!(w, "(").unwrap();
+
        write_method_call_params(w, &f.sig, "", types, Some(&gen_types), "", false);
        writeln!(w, "\n}}\n").unwrap();
 }
@@ -1726,6 +1744,12 @@ fn convert_file<'a, 'b>(libast: &'a FullLibraryAST, crate_types: &CrateTypes<'a>
                        writeln!(out, "#![allow(unused_braces)]").unwrap();
                        // TODO: We need to map deny(missing_docs) in the source crate(s)
                        //writeln!(out, "#![deny(missing_docs)]").unwrap();
+
+                       writeln!(out, "#![cfg_attr(not(feature = \"std\"), no_std)]").unwrap();
+                       writeln!(out, "#[cfg(not(any(feature = \"std\", feature = \"no-std\")))]").unwrap();
+                       writeln!(out, "compile_error!(\"at least one of the `std` or `no-std` features must be enabled\");").unwrap();
+                       writeln!(out, "extern crate alloc;").unwrap();
+
                        writeln!(out, "pub mod version;").unwrap();
                        writeln!(out, "pub mod c_types;").unwrap();
                        writeln!(out, "pub mod bitcoin;").unwrap();
@@ -1972,6 +1996,7 @@ fn main() {
 
        let mut derived_templates = std::fs::OpenOptions::new().write(true).create(true).truncate(true)
                .open(&args[2]).expect("Unable to open new header file");
+       writeln!(&mut derived_templates, "{}", DEFAULT_IMPORTS).unwrap();
        let mut header_file = std::fs::OpenOptions::new().write(true).create(true).truncate(true)
                .open(&args[3]).expect("Unable to open new header file");
        let mut cpp_header_file = std::fs::OpenOptions::new().write(true).create(true).truncate(true)