Support `use crate::*` statements
[ldk-c-bindings] / c-bindings-gen / src / types.rs
index 5d36ed5795eb9b6ff1860a9b9c802d9edfd003fe..18f6a0c051671b374e1a60ae87e3449855bd024b 100644 (file)
@@ -371,8 +371,8 @@ impl<'a, 'b, 'c: 'a + 'b> ResolveType<'c> for Option<&GenericTypes<'a, 'b>> {
                                }
                                _ => {},
                        }
-               }
-               ty
+                       us.parent.resolve_type(ty)
+               } else { ty }
        }
 }
 
@@ -410,6 +410,10 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr
                                        for module in super_mod.split("::") {
                                                path.push(syn::PathSegment { ident: syn::Ident::new(module, Span::call_site()), arguments: syn::PathArguments::None });
                                        }
+                               } else if partial_path == "" && format!("{}", $ident) == "crate" {
+                                       new_path = format!("{}{}", crate_name, $path_suffix);
+                                       let crate_name_ident = format_ident!("{}", crate_name);
+                                       path.push(parse_quote!(#crate_name_ident));
                                } else if partial_path == "" && !dependencies.contains(&$ident) {
                                        new_path = format!("{}::{}{}", crate_name, $ident, $path_suffix);
                                        let crate_name_ident = format_ident!("{}", crate_name);
@@ -906,11 +910,10 @@ 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" if is_ref => Some("*const [u8; 32]"),
-                       "lightning::ln::PaymentHash" if !is_ref => Some("crate::c_types::ThirtyTwoBytes"),
-                       "lightning::ln::PaymentPreimage" if is_ref => Some("*const [u8; 32]"),
-                       "lightning::ln::PaymentPreimage" if !is_ref => Some("crate::c_types::ThirtyTwoBytes"),
-                       "lightning::ln::PaymentSecret" => Some("crate::c_types::ThirtyTwoBytes"),
+                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+                               if is_ref => Some("*const [u8; 32]"),
+                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+                               if !is_ref => Some("crate::c_types::ThirtyTwoBytes"),
 
                        // Override the default since Records contain an fmt with a lifetime:
                        "lightning::util::logger::Record" => Some("*const std::os::raw::c_char"),
@@ -997,7 +1000,9 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                        "lightning::ln::PaymentHash" if is_ref => Some("&::lightning::ln::PaymentHash(unsafe { *"),
                        "lightning::ln::PaymentPreimage" if !is_ref => Some("::lightning::ln::PaymentPreimage("),
                        "lightning::ln::PaymentPreimage" if is_ref => Some("&::lightning::ln::PaymentPreimage(unsafe { *"),
-                       "lightning::ln::PaymentSecret" => Some("::lightning::ln::PaymentSecret("),
+                       "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 { *"),
 
                        // List of traits we map (possibly during processing of other files):
                        "crate::util::logger::Logger" => Some(""),
@@ -1064,11 +1069,10 @@ 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" if !is_ref => Some(".data)"),
-                       "lightning::ln::PaymentHash" if is_ref => Some(" })"),
-                       "lightning::ln::PaymentPreimage" if !is_ref => Some(".data)"),
-                       "lightning::ln::PaymentPreimage" if is_ref => Some(" })"),
-                       "lightning::ln::PaymentSecret" => Some(".data)"),
+                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+                               if !is_ref => Some(".data)"),
+                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+                               if is_ref => Some(" })"),
 
                        // List of traits we map (possibly during processing of other files):
                        "crate::util::logger::Logger" => Some(""),
@@ -1156,11 +1160,10 @@ 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" if is_ref => Some("&"),
-                       "lightning::ln::PaymentHash" if !is_ref => Some("crate::c_types::ThirtyTwoBytes { data: "),
-                       "lightning::ln::PaymentPreimage" if is_ref => Some("&"),
-                       "lightning::ln::PaymentPreimage" => Some("crate::c_types::ThirtyTwoBytes { data: "),
-                       "lightning::ln::PaymentSecret" => Some("crate::c_types::ThirtyTwoBytes { data: "),
+                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+                               if is_ref => Some("&"),
+                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+                               if !is_ref => Some("crate::c_types::ThirtyTwoBytes { data: "),
 
                        // Override the default since Records contain an fmt with a lifetime:
                        "lightning::util::logger::Record" => Some("local_"),
@@ -1229,11 +1232,10 @@ 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" if is_ref => Some(".0"),
-                       "lightning::ln::PaymentHash" => Some(".0 }"),
-                       "lightning::ln::PaymentPreimage" if is_ref => Some(".0"),
-                       "lightning::ln::PaymentPreimage" => Some(".0 }"),
-                       "lightning::ln::PaymentSecret" => Some(".0 }"),
+                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+                               if is_ref => Some(".0"),
+                       "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+                               if !is_ref => Some(".0 }"),
 
                        // Override the default since Records contain an fmt with a lifetime:
                        "lightning::util::logger::Record" => Some(".as_ptr()"),
@@ -1373,6 +1375,14 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                        }
                                }
                                if let Some(t) = single_contained {
+                                       if let syn::Type::Reference(syn::TypeReference { elem, .. }) = t {
+                                               if let syn::Type::Slice(_) = &**elem {
+                                                       return Some(("if ", vec![
+                                                                       (".is_none() { SmartPtr::null() } else { SmartPtr::from_obj(".to_string(),
+                                                                        format!("({}.unwrap())", var_access))
+                                                               ], ") }", ContainerPrefixLocation::PerConv));
+                                               }
+                                       }
                                        let mut v = Vec::new();
                                        self.write_empty_rust_val(generics, &mut v, t);
                                        let s = String::from_utf8(v).unwrap();
@@ -2106,7 +2116,8 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
 
                                if let Some((prefix, conversions, suffix, prefix_location)) = container_lookup(&$container_type, is_ref && ty_has_inner, only_contained_type, ident, var) {
                                        assert_eq!(conversions.len(), $args_len);
-                                       write!(w, "let mut local_{}{} = ", ident, if !to_c && needs_ref_map {"_base"} else { "" }).unwrap();
+                                       write!(w, "let mut local_{}{} = ", ident,
+                                               if (!to_c && needs_ref_map) || (to_c && $container_type == "Option" && contains_slice) {"_base"} else { "" }).unwrap();
                                        if prefix_location == ContainerPrefixLocation::OutsideConv {
                                                var_prefix(w, $args_iter().next().unwrap(), generics, is_ref, ptr_for_ref, true);
                                        }
@@ -2131,7 +2142,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                                        write!(w, "ObjOps::heap_alloc(").unwrap();
                                                }
 
-                                               write!(w, "{}{}", if contains_slice { "local_" } else { "" }, if new_var { new_var_name } else { var_access }).unwrap();
+                                               write!(w, "{}{}", if contains_slice && !to_c { "local_" } else { "" }, if new_var { new_var_name } else { var_access }).unwrap();
                                                if prefix_location == ContainerPrefixLocation::PerConv {
                                                        var_suffix(w, conv_ty, generics, is_ref && ty_has_inner, ptr_for_ref, false);
                                                } else if !is_ref && !needs_ref_map && to_c && only_contained_has_inner {
@@ -2150,6 +2161,8 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                                        write!(w, ".map(|a| &a[..])").unwrap();
                                                }
                                                write!(w, ";").unwrap();
+                                       } else if to_c && $container_type == "Option" && contains_slice {
+                                               write!(w, " let mut local_{} = *local_{}_base;", ident, ident).unwrap();
                                        }
                                        return true;
                                }