"bitcoin::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" if is_ref => Some("crate::chain::transaction::OutPoint"),
+ "bitcoin::blockdata::transaction::OutPoint" => Some("crate::chain::transaction::OutPoint"),
"bitcoin::blockdata::transaction::Transaction" => Some("crate::c_types::Transaction"),
"bitcoin::blockdata::transaction::TxOut" if !is_ref => Some("crate::c_types::TxOut"),
- "bitcoin::OutPoint" => Some("crate::chain::transaction::OutPoint"),
"bitcoin::network::constants::Network" => Some("crate::bitcoin::network::Network"),
"bitcoin::blockdata::block::BlockHeader" if is_ref => Some("*const [u8; 80]"),
"bitcoin::blockdata::block::Block" if is_ref => Some("crate::c_types::u8slice"),
"bitcoin::hash_types::Txid" if !is_ref => Some("crate::c_types::ThirtyTwoBytes"),
"bitcoin::hash_types::BlockHash" if is_ref => Some("*const [u8; 32]"),
"bitcoin::hash_types::BlockHash" if !is_ref => Some("crate::c_types::ThirtyTwoBytes"),
+ "bitcoin::secp256k1::Message" if !is_ref => Some("crate::c_types::ThirtyTwoBytes"),
"ln::channelmanager::PaymentHash" if is_ref => Some("*const [u8; 32]"),
"ln::channelmanager::PaymentHash" if !is_ref => Some("crate::c_types::ThirtyTwoBytes"),
"ln::channelmanager::PaymentPreimage" if is_ref => Some("*const [u8; 32]"),
// List of structs we map (possibly during processing of other files):
"ln::features::InitFeatures" if is_ref => Some(".inner) }"),
- "ln::features::InitFeatures" if !is_ref => Some(".take_ptr()) }"),
+ "ln::features::InitFeatures" if !is_ref => Some(".take_inner()) }"),
// List of traits we map (possibly during processing of other files):
"crate::util::logger::Logger" => Some(""),
"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" => Some("crate::c_types::Transaction::from_vec(local_"),
+ "bitcoin::blockdata::transaction::OutPoint" => Some("crate::c_types::bitcoin_to_C_outpoint("),
"bitcoin::blockdata::transaction::TxOut" if !is_ref => Some("crate::c_types::TxOut::from_rust("),
"bitcoin::blockdata::block::BlockHeader" if is_ref => Some("&local_"),
"bitcoin::blockdata::block::Block" if is_ref => Some("crate::c_types::u8slice::from_slice(&local_"),
"bitcoin::hash_types::Txid" if is_ref => Some(""),
"bitcoin::hash_types::BlockHash" if is_ref => Some(""),
"bitcoin::hash_types::BlockHash" => Some("crate::c_types::ThirtyTwoBytes { data: "),
+ "bitcoin::secp256k1::Message" if !is_ref => Some("crate::c_types::ThirtyTwoBytes { data: "),
"ln::channelmanager::PaymentHash" if is_ref => Some("&"),
"ln::channelmanager::PaymentHash" if !is_ref => Some("crate::c_types::ThirtyTwoBytes { data: "),
"ln::channelmanager::PaymentPreimage" 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" => Some(")"),
+ "bitcoin::blockdata::transaction::OutPoint" => Some(")"),
"bitcoin::blockdata::transaction::TxOut" if !is_ref => Some(")"),
"bitcoin::blockdata::block::BlockHeader" if is_ref => Some(""),
"bitcoin::blockdata::block::Block" if is_ref => Some(")"),
"bitcoin::hash_types::Txid" if is_ref => Some(".as_inner()"),
"bitcoin::hash_types::BlockHash" if is_ref => Some(".as_inner()"),
"bitcoin::hash_types::BlockHash" => Some(".into_inner() }"),
+ "bitcoin::secp256k1::Message" if !is_ref => Some(".as_ref().clone() }"),
"ln::channelmanager::PaymentHash" if is_ref => Some(".0"),
"ln::channelmanager::PaymentHash" => Some(".0 }"),
"ln::channelmanager::PaymentPreimage" if is_ref => Some(".0"),
/// Returns the module path in the generated mapping crate to the containers which we generate
/// when writing to CrateTypes::template_file.
- fn generated_container_path() -> &'static str {
+ pub fn generated_container_path() -> &'static str {
"crate::c_types::derived"
}
/// Returns the module path in the generated mapping crate to the container templates, which
match full_path {
"Result" if !is_ref => {
Some(("match ",
- vec![(".result_ok { true => Ok(".to_string(), format!("(*unsafe {{ Box::from_raw({}.contents.result.take_ptr()) }})", var_name)),
- ("), false => Err(".to_string(), format!("(*unsafe {{ Box::from_raw({}.contents.err.take_ptr()) }})", var_name))],
+ vec![(".result_ok { true => Ok(".to_string(), format!("(*unsafe {{ Box::from_raw(<*mut _>::take_ptr(&mut {}.contents.result)) }})", var_name)),
+ ("), false => Err(".to_string(), format!("(*unsafe {{ Box::from_raw(<*mut _>::take_ptr(&mut {}.contents.err)) }})", var_name))],
")}"))
},
"Vec"|"Slice" if !is_ref => {
self.declared.get(ident)
}
/// Returns true if the object at the given path is mapped as X { inner: *mut origX, .. }.
- fn c_type_has_inner_from_path(&self, full_path: &str) -> bool{
+ pub fn c_type_has_inner_from_path(&self, full_path: &str) -> bool{
self.crate_types.opaques.get(full_path).is_some()
}
pub fn write_rust_type<W: std::io::Write>(&self, w: &mut W, generics: Option<&GenericTypes>, t: &syn::Type) {
match t {
syn::Type::Path(p) => {
- if p.qself.is_some() || p.path.leading_colon.is_some() {
+ if p.qself.is_some() {
unimplemented!();
}
self.write_rust_path(w, generics, &p.path);
|w, decl_type, _full_path, is_ref, _is_mut| match decl_type {
DeclType::StructImported if is_ref && ptr_for_ref => write!(w, ").inner }}").unwrap(),
DeclType::StructImported if is_ref => write!(w, ".inner }}").unwrap(),
- DeclType::StructImported if !is_ref => write!(w, ".take_ptr()) }}").unwrap(),
+ DeclType::StructImported if !is_ref => write!(w, ".take_inner()) }}").unwrap(),
DeclType::MirroredEnum if is_ref => write!(w, ".to_native()").unwrap(),
DeclType::MirroredEnum => write!(w, ".into_native()").unwrap(),
DeclType::Trait(_) => {},
// *** C Container Type Equivalent and alias Printing ***
// ******************************************************
- fn write_template_constructor<W: std::io::Write>(&mut self, w: &mut W, container_type: &str, mangled_container: &str, args: &Vec<&syn::Type>, generics: Option<&GenericTypes>, is_ref: bool) {
+ fn write_template_constructor<W: std::io::Write>(&mut self, w: &mut W, container_type: &str, mangled_container: &str, args: &Vec<&syn::Type>, generics: Option<&GenericTypes>, is_ref: bool) -> bool {
if container_type == "Result" {
assert_eq!(args.len(), 2);
macro_rules! write_fn {
write!(w, "#[no_mangle]\npub extern \"C\" fn {}_new(", mangled_container).unwrap();
for (idx, gen) in args.iter().enumerate() {
write!(w, "{}{}: ", if idx != 0 { ", " } else { "" }, ('a' as u8 + idx as u8) as char).unwrap();
- assert!(self.write_c_type_intern(w, gen, None, false, false, false));
+ if !self.write_c_type_intern(w, gen, None, false, false, false) { return false; }
}
writeln!(w, ") -> {} {{", mangled_container).unwrap();
write!(w, "\t{} {{ ", mangled_container).unwrap();
} else {
writeln!(w, "").unwrap();
}
+ true
}
fn write_template_generics<'b, W: std::io::Write>(&self, w: &mut W, args: &mut dyn Iterator<Item=&'b syn::Type>, generics: Option<&GenericTypes>, is_ref: bool, in_crate: bool) {
}
}
}
- fn check_create_container(&mut self, mangled_container: String, container_type: &str, args: Vec<&syn::Type>, generics: Option<&GenericTypes>, is_ref: bool) {
+ fn check_create_container(&mut self, mangled_container: String, container_type: &str, args: Vec<&syn::Type>, generics: Option<&GenericTypes>, is_ref: bool) -> bool {
if !self.crate_types.templates_defined.get(&mangled_container).is_some() {
- self.crate_types.templates_defined.insert(mangled_container.clone(), true);
let mut created_container: Vec<u8> = Vec::new();
- write!(&mut created_container, "#[no_mangle]\npub type {} = ", mangled_container).unwrap();
+ write!(&mut created_container, "pub type {} = ", mangled_container).unwrap();
write!(&mut created_container, "{}::C{}Templ<", Self::container_templ_path(), container_type).unwrap();
self.write_template_generics(&mut created_container, &mut args.iter().map(|t| *t), generics, is_ref, true);
writeln!(&mut created_container, ">;").unwrap();
self.write_template_generics(&mut created_container, &mut args.iter().map(|t| *t), generics, is_ref, true);
writeln!(&mut created_container, ">;").unwrap();
- self.write_template_constructor(&mut created_container, container_type, &mangled_container, &args, generics, is_ref);
+ if !self.write_template_constructor(&mut created_container, container_type, &mangled_container, &args, generics, is_ref) {
+ return false;
+ }
+ self.crate_types.templates_defined.insert(mangled_container.clone(), true);
self.crate_types.template_file.write(&created_container).unwrap();
}
+ true
}
fn path_to_generic_args(path: &syn::Path) -> Vec<&syn::Type> {
if let syn::PathArguments::AngleBracketed(args) = &path.segments.iter().next().unwrap().arguments {
for arg in args.iter() {
macro_rules! write_path {
($p_arg: expr, $extra_write: expr) => {
- let subtype = self.resolve_path(&$p_arg.path, generics);
- if self.is_transparent_container(ident, is_ref) {
- // We dont (yet) support primitives or containers inside transparent
- // containers, so check for that first:
- if self.is_primitive(&subtype) { return false; }
- if self.is_known_container(&subtype, is_ref) { return false; }
- if !in_type {
- if self.c_type_has_inner_from_path(&subtype) {
- if !self.write_c_path_intern(w, &$p_arg.path, generics, is_ref, is_mut, ptr_for_ref) { return false; }
+ if let Some(subtype) = self.maybe_resolve_path(&$p_arg.path, generics) {
+ if self.is_transparent_container(ident, is_ref) {
+ // We dont (yet) support primitives or containers inside transparent
+ // containers, so check for that first:
+ if self.is_primitive(&subtype) { return false; }
+ if self.is_known_container(&subtype, is_ref) { return false; }
+ if !in_type {
+ if self.c_type_has_inner_from_path(&subtype) {
+ if !self.write_c_path_intern(w, &$p_arg.path, generics, is_ref, is_mut, ptr_for_ref) { return false; }
+ } else {
+ // Option<T> needs to be converted to a *mut T, ie mut ptr-for-ref
+ if !self.write_c_path_intern(w, &$p_arg.path, generics, true, true, true) { return false; }
+ }
} else {
- // Option<T> needs to be converted to a *mut T, ie mut ptr-for-ref
- if !self.write_c_path_intern(w, &$p_arg.path, generics, true, true, true) { return false; }
+ if $p_arg.path.segments.len() == 1 {
+ write!(w, "{}", $p_arg.path.segments.iter().next().unwrap().ident).unwrap();
+ } else {
+ return false;
+ }
}
- } else {
- if $p_arg.path.segments.len() == 1 {
- write!(w, "{}", $p_arg.path.segments.iter().next().unwrap().ident).unwrap();
- } else {
+ } else if self.is_known_container(&subtype, is_ref) || self.is_transparent_container(&subtype, is_ref) {
+ if !self.write_c_mangled_container_path_intern(w, Self::path_to_generic_args(&$p_arg.path), generics,
+ &subtype, is_ref, is_mut, ptr_for_ref, true) {
return false;
}
- }
- } else if self.is_known_container(&subtype, is_ref) || self.is_transparent_container(&subtype, is_ref) {
- if !self.write_c_mangled_container_path_intern(w, Self::path_to_generic_args(&$p_arg.path), generics,
- &subtype, is_ref, is_mut, ptr_for_ref, true) {
- return false;
- }
- self.write_c_mangled_container_path_intern(&mut mangled_type, Self::path_to_generic_args(&$p_arg.path),
- generics, &subtype, is_ref, is_mut, ptr_for_ref, true);
- if let Some(w2) = $extra_write as Option<&mut Vec<u8>> {
- self.write_c_mangled_container_path_intern(w2, Self::path_to_generic_args(&$p_arg.path),
+ self.write_c_mangled_container_path_intern(&mut mangled_type, Self::path_to_generic_args(&$p_arg.path),
generics, &subtype, is_ref, is_mut, ptr_for_ref, true);
+ if let Some(w2) = $extra_write as Option<&mut Vec<u8>> {
+ self.write_c_mangled_container_path_intern(w2, Self::path_to_generic_args(&$p_arg.path),
+ generics, &subtype, is_ref, is_mut, ptr_for_ref, true);
+ }
+ } else {
+ let id = &&$p_arg.path.segments.iter().rev().next().unwrap().ident;
+ write!(w, "{}", id).unwrap();
+ write!(mangled_type, "{}", id).unwrap();
+ if let Some(w2) = $extra_write as Option<&mut Vec<u8>> {
+ write!(w2, "{}", id).unwrap();
+ }
}
- } else {
- let id = &&$p_arg.path.segments.iter().rev().next().unwrap().ident;
- write!(w, "{}", id).unwrap();
- write!(mangled_type, "{}", id).unwrap();
- if let Some(w2) = $extra_write as Option<&mut Vec<u8>> {
- write!(w2, "{}", id).unwrap();
- }
- }
+ } else { return false; }
}
}
if let syn::Type::Tuple(tuple) = arg {
write!(w, "Z").unwrap();
write!(mangled_type, "Z").unwrap();
write!(mangled_tuple_type, "Z").unwrap();
- self.check_create_container(String::from_utf8(mangled_tuple_type).unwrap(),
- &format!("{}Tuple", tuple.elems.len()), tuple.elems.iter().collect(), generics, is_ref);
+ if !self.check_create_container(String::from_utf8(mangled_tuple_type).unwrap(),
+ &format!("{}Tuple", tuple.elems.len()), tuple.elems.iter().collect(), generics, is_ref) {
+ return false;
+ }
}
} else if let syn::Type::Path(p_arg) = arg {
write_path!(p_arg, None);
write!(mangled_type, "Z").unwrap();
// Make sure the type is actually defined:
- self.check_create_container(String::from_utf8(mangled_type).unwrap(), ident, args, generics, is_ref);
- true
+ self.check_create_container(String::from_utf8(mangled_type).unwrap(), ident, args, generics, is_ref)
}
fn write_c_mangled_container_path<W: std::io::Write>(&mut self, w: &mut W, args: Vec<&syn::Type>, generics: Option<&GenericTypes>, ident: &str, is_ref: bool, is_mut: bool, ptr_for_ref: bool) -> bool {
if !self.is_transparent_container(ident, is_ref) {
format!("CVec_{}Z", id)
} else { return false; };
write!(w, "{}::{}", Self::generated_container_path(), mangled_container).unwrap();
- self.check_create_container(mangled_container, "Vec", vec![&*r.elem], generics, false);
- true
+ self.check_create_container(mangled_container, "Vec", vec![&*r.elem], generics, false)
} else { false }
} else if let syn::Type::Tuple(_) = &*s.elem {
let mut args = syn::punctuated::Punctuated::new();