Merge pull request #94 from TheBlueMatt/main
[ldk-c-bindings] / c-bindings-gen / src / types.rs
index 6089d6467626e2ef767a6f88117d5a291349b446..6564ac4756a8ba8c659c93d8b47011bbcc224916 100644 (file)
@@ -205,10 +205,10 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> {
        }
 
        /// Learn the generics in generics in the current context, given a TypeResolver.
-       pub fn learn_generics<'b, 'c>(&mut self, generics: &'a syn::Generics, types: &'b TypeResolver<'a, 'c>) -> bool {
+       pub fn learn_generics_with_impls<'b, 'c>(&mut self, generics: &'a syn::Generics, impld_generics: &'a syn::PathArguments, types: &'b TypeResolver<'a, 'c>) -> bool {
                let mut new_typed_generics = HashMap::new();
                // First learn simple generics...
-               for generic in generics.params.iter() {
+               for (idx, generic) in generics.params.iter().enumerate() {
                        match generic {
                                syn::GenericParam::Type(type_param) => {
                                        let mut non_lifetimes_processed = false;
@@ -260,6 +260,15 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> {
                                        if let Some(default) = type_param.default.as_ref() {
                                                assert!(type_param.bounds.is_empty());
                                                self.default_generics.insert(&type_param.ident, (default.clone(), parse_quote!(&#default), parse_quote!(&mut #default)));
+                                       } else if type_param.bounds.is_empty() {
+                                               if let syn::PathArguments::AngleBracketed(args) = impld_generics {
+                                                       match &args.args[idx] {
+                                                               syn::GenericArgument::Type(ty) => {
+                                                                       self.default_generics.insert(&type_param.ident, (ty.clone(), parse_quote!(&#ty), parse_quote!(&mut #ty)));
+                                                               }
+                                                               _ => unimplemented!(),
+                                                       }
+                                               }
                                        }
                                },
                                _ => {},
@@ -270,6 +279,7 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> {
                        for pred in wh.predicates.iter() {
                                if let syn::WherePredicate::Type(t) = pred {
                                        if let syn::Type::Path(p) = &t.bounded_ty {
+                                               if first_seg_self(&t.bounded_ty).is_some() && p.path.segments.len() == 1 { continue; }
                                                if p.qself.is_some() { return false; }
                                                if p.path.leading_colon.is_some() { return false; }
                                                let mut p_iter = p.path.segments.iter();
@@ -315,6 +325,11 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> {
                true
        }
 
+       /// Learn the generics in generics in the current context, given a TypeResolver.
+       pub fn learn_generics<'b, 'c>(&mut self, generics: &'a syn::Generics, types: &'b TypeResolver<'a, 'c>) -> bool {
+               self.learn_generics_with_impls(generics, &syn::PathArguments::None, types)
+       }
+
        /// Learn the associated types from the trait in the current context.
        pub fn learn_associated_types<'b, 'c>(&mut self, t: &'a syn::ItemTrait, types: &'b TypeResolver<'a, 'c>) {
                for item in t.items.iter() {
@@ -635,6 +650,8 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr
                                Some(format!("{}::{}{}", self.module_path, first_seg.ident, remaining))
                        } else if first_seg_is_stdlib(&first_seg_str) || self.dependencies.contains(&first_seg.ident) {
                                Some(first_seg_str + &remaining)
+                       } else if first_seg_str == "crate" {
+                               Some(self.crate_name.to_owned() + &remaining)
                        } else { None }
                }
        }
@@ -915,7 +932,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
 
                        "std::time::Duration"|"core::time::Duration" => Some("u64"),
                        "std::time::SystemTime" => Some("u64"),
-                       "std::io::Error"|"lightning::io::Error" => Some("crate::c_types::IOError"),
+                       "std::io::Error"|"lightning::io::Error"|"lightning::io::ErrorKind" => Some("crate::c_types::IOError"),
                        "core::fmt::Arguments" if is_ref => Some("crate::c_types::Str"),
 
                        "core::convert::Infallible" => Some("crate::c_types::NotConstructable"),
@@ -1000,7 +1017,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
 
                        "str" if is_ref => Some(""),
                        "alloc::string::String"|"String" => Some(""),
-                       "std::io::Error"|"lightning::io::Error" => Some(""),
+                       "std::io::Error"|"lightning::io::Error"|"lightning::io::ErrorKind" => Some(""),
                        // Note that we'll panic for String if is_ref, as we only have non-owned memory, we
                        // cannot create a &String.
 
@@ -1091,6 +1108,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                        "str" if is_ref => Some(".into_str()"),
                        "alloc::string::String"|"String" => Some(".into_string()"),
                        "std::io::Error"|"lightning::io::Error" => Some(".to_rust()"),
+                       "lightning::io::ErrorKind" => Some(".to_rust_kind()"),
 
                        "core::convert::Infallible" => Some("\")"),
 
@@ -1187,6 +1205,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                        "std::time::Duration"|"core::time::Duration" => Some(""),
                        "std::time::SystemTime" => Some(""),
                        "std::io::Error"|"lightning::io::Error" => Some("crate::c_types::IOError::from_rust("),
+                       "lightning::io::ErrorKind" => Some("crate::c_types::IOError::from_rust_kind("),
                        "core::fmt::Arguments" => Some("alloc::format!(\"{}\", "),
 
                        "core::convert::Infallible" => Some("panic!(\"Cannot construct an Infallible: "),
@@ -1266,7 +1285,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
 
                        "std::time::Duration"|"core::time::Duration" => Some(".as_secs()"),
                        "std::time::SystemTime" => Some(".duration_since(::std::time::SystemTime::UNIX_EPOCH).expect(\"Times must be post-1970\").as_secs()"),
-                       "std::io::Error"|"lightning::io::Error" => Some(")"),
+                       "std::io::Error"|"lightning::io::Error"|"lightning::io::ErrorKind" => Some(")"),
                        "core::fmt::Arguments" => Some(").into()"),
 
                        "core::convert::Infallible" => Some("\")"),