self.clonable_types.borrow_mut().insert(object);
}
pub fn is_clonable(&self, object: &str) -> bool {
- object.starts_with("&'static ") ||
self.clonable_types.borrow().contains(object)
}
pub fn write_new_template(&self, mangled_container: String, has_destructor: bool, created_container: &[u8]) {
"core::convert::Infallible" => Some("crate::c_types::NotConstructable"),
+ "bitcoin::bech32::Error"|"bech32::Error"
+ if !is_ref => Some("crate::c_types::Bech32Error"),
+ "bitcoin::secp256k1::Error"|"secp256k1::Error"
+ if !is_ref => Some("crate::c_types::Secp256k1Error"),
+
+ "core::num::ParseIntError" => Some("crate::c_types::Error"),
+ "core::str::Utf8Error" => Some("crate::c_types::Error"),
+
"bitcoin::bech32::u5"|"bech32::u5" => Some("crate::c_types::u5"),
"core::num::NonZeroU8" => Some("u8"),
if is_ref => Some("*const [u8; 32]"),
"bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey"
if !is_ref => Some("crate::c_types::SecretKey"),
- "bitcoin::secp256k1::Error"|"secp256k1::Error"
- if !is_ref => Some("crate::c_types::Secp256k1Error"),
"bitcoin::blockdata::script::Script" if is_ref => Some("crate::c_types::u8slice"),
"bitcoin::blockdata::script::Script" if !is_ref => Some("crate::c_types::derived::CVec_u8Z"),
"bitcoin::blockdata::transaction::OutPoint" => Some("crate::lightning::chain::transaction::OutPoint"),
"core::convert::Infallible" => Some("panic!(\"You must never construct a NotConstructable! : "),
+ "bitcoin::bech32::Error"|"bech32::Error" if !is_ref => Some(""),
+ "bitcoin::secp256k1::Error"|"secp256k1::Error" if !is_ref => Some(""),
+
+ "core::num::ParseIntError" => Some("u8::from_str_radix(\" a\", 10).unwrap_err() /*"),
+ "core::str::Utf8Error" => Some("core::str::from_utf8(&[0xff]).unwrap_err() /*"),
+
"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("),
"core::convert::Infallible" => Some("\")"),
+ "bitcoin::bech32::Error"|"bech32::Error" if !is_ref => Some(".into_rust()"),
+ "bitcoin::secp256k1::Error"|"secp256k1::Error" if !is_ref => Some(".into_rust()"),
+
+ "core::num::ParseIntError" => Some("*/"),
+ "core::str::Utf8Error" => Some("*/"),
+
"std::time::Duration"|"core::time::Duration" => Some(")"),
"std::time::SystemTime" => Some("))"),
"core::convert::Infallible" => Some("panic!(\"Cannot construct an Infallible: "),
+ "bitcoin::bech32::Error"|"bech32::Error"
+ if !is_ref => Some("crate::c_types::Bech32Error::from_rust("),
+ "bitcoin::secp256k1::Error"|"secp256k1::Error"
+ if !is_ref => Some("crate::c_types::Secp256k1Error::from_rust("),
+
+ "core::num::ParseIntError" => Some("crate::c_types::Error { _dummy: 0 } /*"),
+ "core::str::Utf8Error" => Some("crate::c_types::Error { _dummy: 0 } /*"),
+
"bitcoin::bech32::u5"|"bech32::u5" => Some(""),
"bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey"|"secp256k1::key::PublicKey"
if is_ref => Some(""),
"bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey"
if !is_ref => Some("crate::c_types::SecretKey::from_rust("),
- "bitcoin::secp256k1::Error"|"secp256k1::Error"
- if !is_ref => Some("crate::c_types::Secp256k1Error::from_rust("),
"bitcoin::blockdata::script::Script" if is_ref => Some("crate::c_types::u8slice::from_slice(&"),
"bitcoin::blockdata::script::Script" if !is_ref => Some(""),
"bitcoin::blockdata::transaction::Transaction"|"bitcoin::Transaction" if is_ref => Some("crate::c_types::Transaction::from_bitcoin("),
"core::convert::Infallible" => Some("\")"),
+ "bitcoin::secp256k1::Error"|"bech32::Error"
+ if !is_ref => Some(")"),
+ "bitcoin::secp256k1::Error"|"secp256k1::Error"
+ if !is_ref => Some(")"),
+
+ "core::num::ParseIntError" => Some("*/"),
+ "core::str::Utf8Error" => Some("*/"),
+
"bitcoin::bech32::u5"|"bech32::u5" => Some(".into()"),
"bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey"|"secp256k1::key::PublicKey"
if !is_ref => Some(")"),
"bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey"
if is_ref => Some(".as_ref()"),
- "bitcoin::secp256k1::Error"|"secp256k1::Error"
- if !is_ref => Some(")"),
"bitcoin::blockdata::script::Script" if is_ref => Some("[..])"),
"bitcoin::blockdata::script::Script" if !is_ref => Some(".into_bytes().into()"),
"bitcoin::blockdata::transaction::Transaction"|"bitcoin::Transaction" => Some(")"),
}
},
"Option" => {
+ let mut is_contained_ref = false;
let contained_struct = if let Some(syn::Type::Path(p)) = single_contained {
Some(self.resolve_path(&p.path, generics))
} else if let Some(syn::Type::Reference(r)) = single_contained {
+ is_contained_ref = true;
if let syn::Type::Path(p) = &*r.elem {
Some(self.resolve_path(&p.path, generics))
} else { None }
} else { None };
if let Some(inner_path) = contained_struct {
+ let only_contained_has_inner = self.c_type_has_inner_from_path(&inner_path);
if self.c_type_has_inner_from_path(&inner_path) {
let is_inner_ref = if let Some(syn::Type::Reference(_)) = single_contained { true } else { false };
if is_ref {
], " }", ContainerPrefixLocation::OutsideConv));
}
} else if self.is_primitive(&inner_path) || self.c_type_from_path(&inner_path, false, false).is_none() {
- 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!("{}.unwrap()", var_access))
- ], ") }", ContainerPrefixLocation::PerConv));
+ if self.is_primitive(&inner_path) || (!is_contained_ref && !is_ref) || only_contained_has_inner {
+ 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!("{}.unwrap()", var_access))
+ ], ") }", ContainerPrefixLocation::PerConv));
+ } else {
+ 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(/* WARNING: CLONING CONVERSION HERE! &Option<Enum> is otherwise un-expressable. */", inner_name, inner_name),
+ format!("{}.clone().unwrap()", var_access))
+ ], ") }", ContainerPrefixLocation::PerConv));
+ }
} else {
// If c_type_from_path is some (ie there's a manual mapping for the inner
// type), lean on write_empty_rust_val, below.
// Returns prefix + Vec<(prefix, var-name-to-inline-convert)> + suffix
// expecting one element in the vec per generic type, each of which is inline-converted
-> Option<(&'b str, Vec<(String, String)>, &'b str, ContainerPrefixLocation)> {
+ let mut only_contained_has_inner = false;
+ let only_contained_resolved = if let Some(syn::Type::Path(p)) = single_contained {
+ let res = self.resolve_path(&p.path, generics);
+ only_contained_has_inner = self.c_type_has_inner_from_path(&res);
+ Some(res)
+ } else { None };
match full_path {
"Result" if !is_ref => {
Some(("match ",
("), false => Err(".to_string(), format!("(*unsafe {{ Box::from_raw(<*mut _>::take_ptr(&mut {}.contents.err)) }})", var_access))],
")}", ContainerPrefixLocation::PerConv))
},
- "Slice" if is_ref => {
+ "Slice" if is_ref && only_contained_has_inner => {
Some(("Vec::new(); for mut item in ", vec![(format!(".as_slice().iter() {{ local_{}.push(", var_name), "item".to_string())], "); }", ContainerPrefixLocation::PerConv))
},
"Vec"|"Slice" => {
Some(("Vec::new(); for mut item in ", vec![(format!(".into_rust().drain(..) {{ local_{}.push(", var_name), "item".to_string())], "); }", ContainerPrefixLocation::PerConv))
},
"Option" => {
- if let Some(syn::Type::Path(p)) = single_contained {
- let inner_path = self.resolve_path(&p.path, generics);
- if self.is_primitive(&inner_path) {
+ if let Some(resolved) = only_contained_resolved {
+ if self.is_primitive(&resolved) {
return Some(("if ", vec![(".is_some() { Some(".to_string(), format!("{}.take()", var_access))], ") } else { None }", ContainerPrefixLocation::NoPrefix))
- } else if self.c_type_has_inner_from_path(&inner_path) {
+ } else if only_contained_has_inner {
if is_ref {
return Some(("if ", vec![(".inner.is_null() { None } else { Some((*".to_string(), format!("{}", var_access))], ").clone()) }", ContainerPrefixLocation::PerConv))
} else {
}
}
- if let Some((prefix, conversions, suffix, prefix_location)) = container_lookup(&$container_type, is_ref && ty_has_inner, only_contained_type, ident, var) {
+ if let Some((prefix, conversions, suffix, prefix_location)) = container_lookup(&$container_type, is_ref, only_contained_type, ident, var) {
assert_eq!(conversions.len(), $args_len);
write!(w, "let mut local_{}{} = ", ident,
if (!to_c && needs_ref_map) || (to_c && $container_type == "Option" && contains_slice) {"_base"} else { "" }).unwrap();
}
pub fn write_to_c_conversion_new_var_inner<W: std::io::Write>(&self, w: &mut W, ident: &syn::Ident, var_access: &str, t: &syn::Type, generics: Option<&GenericTypes>, ptr_for_ref: bool, from_ownable_ref: bool) -> bool {
- self.write_conversion_new_var_intern(w, ident, var_access, t, generics, false, ptr_for_ref, true, from_ownable_ref,
+ self.write_conversion_new_var_intern(w, ident, var_access, t, generics, from_ownable_ref, ptr_for_ref, true, from_ownable_ref,
&|a, b| self.to_c_conversion_new_var_from_path(a, b),
&|a, b, c, d, e| self.to_c_conversion_container_new_var(generics, a, b, c, d, e),
// We force ptr_for_ref here since we can't generate a ref on one line and use it later
if !c_ty {
self.write_rust_path(w, generics, path);
} else {
- write!(w, "{}", full_path).unwrap();
+ // We shouldn't be mapping references in types, so panic here
+ unimplemented!();
}
} else if is_ref {
write!(w, "&{}{}{}", if is_mut { "mut " } else { "" }, crate_pfx, full_path).unwrap();