Merge pull request #61 from TheBlueMatt/main
[ldk-c-bindings] / c-bindings-gen / src / types.rs
index 007441ed5625e4f4bba85aa5ea7057c822a253c7..346f588221fa91e0d50a8ee75014f3d60775e799 100644 (file)
@@ -110,8 +110,7 @@ pub fn export_status(attrs: &[syn::Attribute]) -> ExportStatus {
                                                                        }
                                                                        if all_test { return ExportStatus::TestOnly; }
                                                                }
-                                                       } else if i == "test" || i == "feature" {
-                                                               // If its cfg(feature(...)) we assume its test-only
+                                                       } else if i == "test" {
                                                                return ExportStatus::TestOnly;
                                                        }
                                                }
@@ -724,6 +723,7 @@ fn initial_clonable_types() -> HashSet<String> {
        let mut res = HashSet::new();
        res.insert("crate::c_types::u5".to_owned());
        res.insert("crate::c_types::ThirtyTwoBytes".to_owned());
+       res.insert("crate::c_types::SecretKey".to_owned());
        res.insert("crate::c_types::PublicKey".to_owned());
        res.insert("crate::c_types::Transaction".to_owned());
        res.insert("crate::c_types::TxOut".to_owned());
@@ -828,7 +828,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
        // *************************************************
 
        /// Returns true we if can just skip passing this to C entirely
-       fn skip_path(&self, full_path: &str) -> bool {
+       pub fn skip_path(&self, full_path: &str) -> bool {
                full_path == "bitcoin::secp256k1::Secp256k1" ||
                full_path == "bitcoin::secp256k1::Signing" ||
                full_path == "bitcoin::secp256k1::Verification"
@@ -1134,7 +1134,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                        "std::time::Duration"|"core::time::Duration" => Some(""),
                        "std::time::SystemTime" => Some(""),
                        "std::io::Error" if !is_ref => Some("crate::c_types::IOError::from_rust("),
-                       "core::fmt::Arguments" => Some("format!(\"{}\", "),
+                       "core::fmt::Arguments" => Some("alloc::format!(\"{}\", "),
 
                        "core::convert::Infallible" => Some("panic!(\"Cannot construct an Infallible: "),
 
@@ -1297,6 +1297,22 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                        assert!(args.next().is_none());
                        match inner {
                                syn::Type::Reference(_) => true,
+                               syn::Type::Array(a) => {
+                                       if let syn::Expr::Lit(l) = &a.len {
+                                               if let syn::Lit::Int(i) = &l.lit {
+                                                       if i.base10_digits().parse::<usize>().unwrap() >= 32 {
+                                                               let mut buf = Vec::new();
+                                                               self.write_rust_type(&mut buf, generics, &a.elem);
+                                                               let ty = String::from_utf8(buf).unwrap();
+                                                               ty == "u8"
+                                                       } else {
+                                                               // Blindly assume that if we're trying to create an empty value for an
+                                                               // array < 32 entries that all-0s may be a valid state.
+                                                               unimplemented!();
+                                                       }
+                                               } else { unimplemented!(); }
+                                       } else { unimplemented!(); }
+                               },
                                syn::Type::Path(p) => {
                                        if let Some(resolved) = self.maybe_resolve_path(&p.path, generics) {
                                                if self.c_type_has_inner_from_path(&resolved) { return true; }
@@ -2611,8 +2627,15 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                                if !self.is_primitive(&resolved) { return false; }
                                                if let syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(len), .. }) = &a.len {
                                                        if self.c_type_from_path(&format!("[{}; {}]", resolved, len.base10_digits()), is_ref, ptr_for_ref).is_none() { return false; }
-                                                       write!(w, "_{}{}", resolved, len.base10_digits()).unwrap();
-                                                       write!(mangled_type, "_{}{}", resolved, len.base10_digits()).unwrap();
+                                                       if in_type || args.len() != 1 {
+                                                               write!(w, "_{}{}", resolved, len.base10_digits()).unwrap();
+                                                               write!(mangled_type, "_{}{}", resolved, len.base10_digits()).unwrap();
+                                                       } else {
+                                                               let arrty = format!("[{}; {}]", resolved, len.base10_digits());
+                                                               let realty = self.c_type_from_path(&arrty, is_ref, ptr_for_ref).unwrap_or(&arrty);
+                                                               write!(w, "{}", realty).unwrap();
+                                                               write!(mangled_type, "{}", realty).unwrap();
+                                                       }
                                                } else { return false; }
                                        } else { return false; }
                                },