/// 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.
/// 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);
}
/// 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);
}
}
}
+/// List of manually-generated types which are clonable
+fn initial_clonable_types() -> HashSet<String> {
+ 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
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,
}
}
// 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"),
"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"),
"[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(""),
"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"
"[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"),
"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()"),
"[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: "),
"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(&"),
"[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(" }"),
"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(")"),
}
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<String> {
+ 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 ***