Merge pull request #54 from TheBlueMatt/main
[ldk-c-bindings] / c-bindings-gen / src / types.rs
index 0b3aaf32ca6a3f2b74a50ff4788709eb667b2dcd..57b06070a66d269b8f01177f45fd2cccdc2badc3 100644 (file)
@@ -921,9 +921,11 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                        "bitcoin::hash_types::Txid"|"bitcoin::hash_types::BlockHash"|"bitcoin_hashes::sha256::Hash"
                                if !is_ref => Some("crate::c_types::ThirtyTwoBytes"),
                        "bitcoin::secp256k1::Message" if !is_ref => Some("crate::c_types::ThirtyTwoBytes"),
-                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"
+                       |"lightning::ln::channelmanager::PaymentId"|"lightning::chain::keysinterface::KeyMaterial"
                                if is_ref => Some("*const [u8; 32]"),
-                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"
+                       |"lightning::ln::channelmanager::PaymentId"|"lightning::chain::keysinterface::KeyMaterial"
                                if !is_ref => Some("crate::c_types::ThirtyTwoBytes"),
 
                        "lightning::io::Read" => Some("crate::c_types::u8slice"),
@@ -964,7 +966,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
 
                        "core::convert::Infallible" => Some("panic!(\"You must never construct a NotConstructable! : "),
 
-                       "std::time::Duration"|"core::time::Duration" => Some("std::time::Duration::from_secs("),
+                       "std::time::Duration"|"core::time::Duration" => Some("core::time::Duration::from_secs("),
                        "std::time::SystemTime" => Some("(::std::time::SystemTime::UNIX_EPOCH + std::time::Duration::from_secs("),
 
                        "bech32::u5" => Some(""),
@@ -1011,6 +1013,8 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                        "lightning::ln::PaymentSecret" if !is_ref => Some("::lightning::ln::PaymentSecret("),
                        "lightning::ln::channelmanager::PaymentId" if !is_ref => Some("::lightning::ln::channelmanager::PaymentId("),
                        "lightning::ln::channelmanager::PaymentId" if is_ref=> Some("&::lightning::ln::channelmanager::PaymentId( unsafe { *"),
+                       "lightning::chain::keysinterface::KeyMaterial" if !is_ref => Some("::lightning::chain::keysinterface::KeyMaterial("),
+                       "lightning::chain::keysinterface::KeyMaterial" if is_ref=> Some("&::lightning::chain::keysinterface::KeyMaterial( unsafe { *"),
 
                        // List of traits we map (possibly during processing of other files):
                        "lightning::io::Read" => Some("&mut "),
@@ -1075,9 +1079,11 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                        "bitcoin::hash_types::Txid" if is_ref => Some(" }[..]).unwrap()"),
                        "bitcoin::hash_types::Txid" => Some(".data[..]).unwrap()"),
                        "bitcoin::hash_types::BlockHash" if !is_ref => Some(".data[..]).unwrap()"),
-                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"
+                       |"lightning::ln::channelmanager::PaymentId"|"lightning::chain::keysinterface::KeyMaterial"
                                if !is_ref => Some(".data)"),
-                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"
+                       |"lightning::ln::channelmanager::PaymentId"|"lightning::chain::keysinterface::KeyMaterial"
                                if is_ref => Some(" })"),
 
                        // List of traits we map (possibly during processing of other files):
@@ -1162,9 +1168,11 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                        "bitcoin::hash_types::Txid"|"bitcoin::hash_types::BlockHash"|"bitcoin_hashes::sha256::Hash"
                                if !is_ref => Some("crate::c_types::ThirtyTwoBytes { data: "),
                        "bitcoin::secp256k1::Message" if !is_ref => Some("crate::c_types::ThirtyTwoBytes { data: "),
-                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"
+                       |"lightning::ln::channelmanager::PaymentId"|"lightning::chain::keysinterface::KeyMaterial"
                                if is_ref => Some("&"),
-                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"
+                       |"lightning::ln::channelmanager::PaymentId"|"lightning::chain::keysinterface::KeyMaterial"
                                if !is_ref => Some("crate::c_types::ThirtyTwoBytes { data: "),
 
                        "lightning::io::Read" => Some("crate::c_types::u8slice::from_vec(&crate::c_types::reader_to_vec("),
@@ -1232,9 +1240,11 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                        "bitcoin::hash_types::Txid"|"bitcoin::hash_types::BlockHash"|"bitcoin_hashes::sha256::Hash"
                                if !is_ref => Some(".into_inner() }"),
                        "bitcoin::secp256k1::Message" if !is_ref => Some(".as_ref().clone() }"),
-                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"
+                       |"lightning::ln::channelmanager::PaymentId"|"lightning::chain::keysinterface::KeyMaterial"
                                if is_ref => Some(".0"),
-                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"
+                       |"lightning::ln::channelmanager::PaymentId"|"lightning::chain::keysinterface::KeyMaterial"
                                if !is_ref => Some(".0 }"),
 
                        "lightning::io::Read" => Some("))"),
@@ -1259,7 +1269,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
        /// TODO: We should never need to use this!
        fn real_rust_type_mapping<'equiv>(&self, thing: &'equiv str) -> &'equiv str {
                match thing {
-                       "lightning::io::Read" => "std::io::Read",
+                       "lightning::io::Read" => "crate::c_types::io::Read",
                        _ => thing,
                }
        }
@@ -1355,12 +1365,12 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                                let is_inner_ref = if let Some(syn::Type::Reference(_)) = single_contained { true } else { false };
                                                if is_ref {
                                                        return Some(("if ", vec![
-                                                               (".is_none() { std::ptr::null() } else { ObjOps::nonnull_ptr_to_inner(".to_owned(),
+                                                               (".is_none() { core::ptr::null() } else { ObjOps::nonnull_ptr_to_inner(".to_owned(),
                                                                        format!("({}{}.unwrap())", var_access, if is_inner_ref { "" } else { ".as_ref()" }))
                                                                ], ") }", ContainerPrefixLocation::OutsideConv));
                                                } else {
                                                        return Some(("if ", vec![
-                                                               (".is_none() { std::ptr::null_mut() } else { ".to_owned(), format!("({}.unwrap())", var_access))
+                                                               (".is_none() { core::ptr::null_mut() } else { ".to_owned(), format!("({}.unwrap())", var_access))
                                                                ], " }", ContainerPrefixLocation::OutsideConv));
                                                }
                                        } else if self.is_primitive(&inner_path) || self.c_type_from_path(&inner_path, false, false).is_none() {
@@ -1376,6 +1386,14 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                        }
                                }
                                if let Some(t) = single_contained {
+                                       if let syn::Type::Tuple(syn::TypeTuple { elems, .. }) = t {
+                                               assert!(elems.is_empty());
+                                               let inner_name = self.get_c_mangled_container_type(vec![single_contained.unwrap()], generics, "Option").unwrap();
+                                               return Some(("if ", vec![
+                                                       (format!(".is_none() {{ {}::None }} else {{ {}::Some /*",
+                                                               inner_name, inner_name), format!(""))
+                                                       ], " */}", ContainerPrefixLocation::PerConv));
+                                       }
                                        if let syn::Type::Reference(syn::TypeReference { elem, .. }) = t {
                                                if let syn::Type::Slice(_) = &**elem {
                                                        return Some(("if ", vec![
@@ -1686,7 +1704,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                        syn::Type::Path(p) => {
                                let resolved = self.resolve_path(&p.path, generics);
                                if self.crate_types.opaques.get(&resolved).is_some() {
-                                       write!(w, "crate::{} {{ inner: std::ptr::null_mut(), is_owned: true }}", resolved).unwrap();
+                                       write!(w, "crate::{} {{ inner: core::ptr::null_mut(), is_owned: true }}", resolved).unwrap();
                                } else {
                                        // Assume its a manually-mapped C type, where we can just define an null() fn
                                        write!(w, "{}::null()", self.c_type_from_path(&resolved, false, false).unwrap()).unwrap();
@@ -1762,7 +1780,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                        syn::Type::Slice(_) => {
                                // Option<[]> always implies that we want to treat len() == 0 differently from
                                // None, so we always map an Option<[]> into a pointer.
-                               write!(w, " == std::ptr::null_mut()").unwrap();
+                               write!(w, " == core::ptr::null_mut()").unwrap();
                                EmptyValExpectedTy::ReferenceAsPointer
                        },
                        _ => unimplemented!(),
@@ -2383,7 +2401,13 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                }
                                if !self.write_c_type_intern(w, t, generics, false, false, false, false) { return false; }
                        } else {
-                               assert!(!is_ref); // We don't currently support outer reference types for non-primitive inners
+                               // We don't currently support outer reference types for non-primitive inners,
+                               // except for the empty tuple.
+                               if let syn::Type::Tuple(t_arg) = t {
+                                       assert!(t_arg.elems.len() == 0 || !is_ref);
+                               } else {
+                                       assert!(!is_ref);
+                               }
                                if !self.write_c_type_intern(w, t, generics, false, false, false, false) { return false; }
                        }
                }