X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=c-bindings-gen%2Fsrc%2Ftypes.rs;h=f8ecc7ca843d275e53a33b2e30ebf3873f629151;hb=5d83aff2dd572685d7f76406422167e12c836b0e;hp=bbadd9d2c99550fa39b0460137941cba78879fca;hpb=350074fb39d33812f2e37c0c903b6910b584850f;p=ldk-c-bindings diff --git a/c-bindings-gen/src/types.rs b/c-bindings-gen/src/types.rs index bbadd9d..f8ecc7c 100644 --- a/c-bindings-gen/src/types.rs +++ b/c-bindings-gen/src/types.rs @@ -164,19 +164,20 @@ pub fn is_enum_opaque(e: &syn::ItemEnum) -> bool { /// concrete C container struct, etc). #[must_use] pub struct GenericTypes<'a, 'b> { + self_ty: Option<(String, &'a syn::Path)>, parent: Option<&'b GenericTypes<'b, 'b>>, typed_generics: HashMap<&'a syn::Ident, (String, Option<&'a syn::Path>)>, } impl<'a, 'p: 'a> GenericTypes<'a, 'p> { - pub fn new() -> Self { - Self { parent: None, typed_generics: HashMap::new(), } + pub fn new(self_ty: Option<(String, &'a syn::Path)>) -> Self { + Self { self_ty, parent: None, typed_generics: HashMap::new(), } } /// push a new context onto the stack, allowing for a new set of generics to be learned which /// will override any lower contexts, but which will still fall back to resoltion via lower /// contexts. pub fn push_ctx<'c>(&'c self) -> GenericTypes<'a, 'c> { - GenericTypes { parent: Some(self), typed_generics: HashMap::new(), } + GenericTypes { self_ty: None, parent: Some(self), typed_generics: HashMap::new(), } } /// Learn the generics in generics in the current context, given a TypeResolver. @@ -281,6 +282,11 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> { /// Attempt to resolve an Ident as a generic parameter and return the full path. pub fn maybe_resolve_ident<'b>(&'b self, ident: &syn::Ident) -> Option<&'b String> { + if let Some(ty) = &self.self_ty { + if format!("{}", ident) == "Self" { + return Some(&ty.0); + } + } if let Some(res) = self.typed_generics.get(ident).map(|(a, _)| a) { return Some(res); } @@ -294,6 +300,11 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> { /// and syn::Path. pub fn maybe_resolve_path<'b>(&'b self, path: &syn::Path) -> Option<(&'b String, &'a syn::Path)> { if let Some(ident) = path.get_ident() { + if let Some(ty) = &self.self_ty { + if format!("{}", ident) == "Self" { + return Some((&ty.0, ty.1)); + } + } if let Some(res) = self.typed_generics.get(ident).map(|(a, b)| (a, b.unwrap())) { return Some(res); } @@ -627,6 +638,13 @@ impl FullLibraryAST { } } +/// List of manually-generated types which are clonable +fn initial_clonable_types() -> HashSet { + let mut res = HashSet::new(); + res.insert("crate::c_types::u5".to_owned()); + res +} + /// Top-level struct tracking everything which has been defined while walking the crate. pub struct CrateTypes<'a> { /// This may contain structs or enums, but only when either is mapped as @@ -662,7 +680,7 @@ impl<'a> CrateTypes<'a> { opaques: HashMap::new(), mirrored_enums: HashMap::new(), traits: HashMap::new(), type_aliases: HashMap::new(), reverse_alias_map: HashMap::new(), templates_defined: RefCell::new(HashMap::default()), - clonable_types: RefCell::new(HashSet::new()), trait_impls: HashMap::new(), + clonable_types: RefCell::new(initial_clonable_types()), trait_impls: HashMap::new(), template_file: RefCell::new(template_file), lib_ast: &libast, } } @@ -771,6 +789,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { // for arrays are different (https://github.com/eqrion/cbindgen/issues/528) "[u8; 32]" if !is_ref => Some("crate::c_types::ThirtyTwoBytes"), + "[u8; 20]" if !is_ref => Some("crate::c_types::TwentyBytes"), "[u8; 16]" if !is_ref => Some("crate::c_types::SixteenBytes"), "[u8; 10]" if !is_ref => Some("crate::c_types::TenBytes"), "[u8; 4]" if !is_ref => Some("crate::c_types::FourBytes"), @@ -783,6 +802,8 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "std::time::Duration" => Some("u64"), "std::io::Error" => Some("crate::c_types::IOError"), + "bech32::u5" => Some("crate::c_types::u5"), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey"|"secp256k1::key::PublicKey" => Some("crate::c_types::PublicKey"), "bitcoin::secp256k1::Signature" => Some("crate::c_types::Signature"), @@ -836,6 +857,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "[u8; 32]" if is_ref => Some("unsafe { &*"), "[u8; 32]" if !is_ref => Some(""), + "[u8; 20]" if !is_ref => Some(""), "[u8; 16]" if !is_ref => Some(""), "[u8; 10]" if !is_ref => Some(""), "[u8; 4]" if !is_ref => Some(""), @@ -851,6 +873,8 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "std::time::Duration" => Some("std::time::Duration::from_secs("), + "bech32::u5" => Some(""), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey"|"secp256k1::key::PublicKey" if is_ref => Some("&"), "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey"|"secp256k1::key::PublicKey" @@ -897,6 +921,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "[u8; 32]" if is_ref => Some("}"), "[u8; 32]" if !is_ref => Some(".data"), + "[u8; 20]" if !is_ref => Some(".data"), "[u8; 16]" if !is_ref => Some(".data"), "[u8; 10]" if !is_ref => Some(".data"), "[u8; 4]" if !is_ref => Some(".data"), @@ -910,6 +935,8 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "std::time::Duration" => Some(")"), + "bech32::u5" => Some(".into()"), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey"|"secp256k1::key::PublicKey" => Some(".into_rust()"), "bitcoin::secp256k1::Signature" => Some(".into_rust()"), @@ -971,6 +998,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "[u8; 32]" if !is_ref => Some("crate::c_types::ThirtyTwoBytes { data: "), "[u8; 32]" if is_ref => Some(""), + "[u8; 20]" if !is_ref => Some("crate::c_types::TwentyBytes { data: "), "[u8; 16]" if !is_ref => Some("crate::c_types::SixteenBytes { data: "), "[u8; 10]" if !is_ref => Some("crate::c_types::TenBytes { data: "), "[u8; 4]" if !is_ref => Some("crate::c_types::FourBytes { data: "), @@ -985,6 +1013,8 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "std::time::Duration" => Some(""), "std::io::Error" if !is_ref => Some("crate::c_types::IOError::from_rust("), + "bech32::u5" => Some(""), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey"|"secp256k1::key::PublicKey" => Some("crate::c_types::PublicKey::from_rust(&"), "bitcoin::secp256k1::Signature" => Some("crate::c_types::Signature::from_rust(&"), @@ -1035,6 +1065,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "[u8; 32]" if !is_ref => Some(" }"), "[u8; 32]" if is_ref => Some(""), + "[u8; 20]" if !is_ref => Some(" }"), "[u8; 16]" if !is_ref => Some(" }"), "[u8; 10]" if !is_ref => Some(" }"), "[u8; 4]" if !is_ref => Some(" }"), @@ -1050,6 +1081,8 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "std::time::Duration" => Some(".as_secs()"), "std::io::Error" if !is_ref => Some(")"), + "bech32::u5" => Some(".into()"), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey"|"secp256k1::key::PublicKey" => Some(")"), "bitcoin::secp256k1::Signature" => Some(")"), @@ -2318,6 +2351,13 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { } self.write_c_mangled_container_path_intern(w, args, generics, ident, is_ref, is_mut, ptr_for_ref, false) } + pub fn get_c_mangled_container_type(&self, args: Vec<&syn::Type>, generics: Option<&GenericTypes>, template_name: &str) -> Option { + let mut out = Vec::new(); + if !self.write_c_mangled_container_path(&mut out, args, generics, template_name, false, false, false) { + return None; + } + Some(String::from_utf8(out).unwrap()) + } // ********************************** // *** C Type Equivalent Printing ***