mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-02-25 07:17:40 +01:00
[bindings] Move to manual write-out for Tuples, too
This commit is contained in:
parent
7dd9d6f40c
commit
faad5124cf
3 changed files with 89 additions and 67 deletions
|
@ -221,6 +221,72 @@ pub fn write_vec_block<W: std::io::Write>(w: &mut W, mangled_container: &str, in
|
|||
}
|
||||
}
|
||||
|
||||
/// Writes out a C-callable concrete (A, B, ...) struct and utility methods
|
||||
pub fn write_tuple_block<W: std::io::Write>(w: &mut W, mangled_container: &str, types: &[String], clonable: bool) {
|
||||
writeln!(w, "#[repr(C)]").unwrap();
|
||||
writeln!(w, "pub struct {} {{", mangled_container).unwrap();
|
||||
for (idx, ty) in types.iter().enumerate() {
|
||||
writeln!(w, "\tpub {}: {},", ('a' as u8 + idx as u8) as char, ty).unwrap();
|
||||
}
|
||||
writeln!(w, "}}").unwrap();
|
||||
|
||||
let mut tuple_str = "(".to_owned();
|
||||
for (idx, ty) in types.iter().enumerate() {
|
||||
if idx != 0 { tuple_str += ", "; }
|
||||
tuple_str += ty;
|
||||
}
|
||||
tuple_str += ")";
|
||||
|
||||
writeln!(w, "impl From<{}> for {} {{", tuple_str, mangled_container).unwrap();
|
||||
writeln!(w, "\tfn from (tup: {}) -> Self {{", tuple_str).unwrap();
|
||||
writeln!(w, "\t\tSelf {{").unwrap();
|
||||
for idx in 0..types.len() {
|
||||
writeln!(w, "\t\t\t{}: tup.{},", ('a' as u8 + idx as u8) as char, idx).unwrap();
|
||||
}
|
||||
writeln!(w, "\t\t}}").unwrap();
|
||||
writeln!(w, "\t}}").unwrap();
|
||||
writeln!(w, "}}").unwrap();
|
||||
writeln!(w, "impl {} {{", mangled_container).unwrap();
|
||||
writeln!(w, "\t#[allow(unused)] pub(crate) fn to_rust(mut self) -> {} {{", tuple_str).unwrap();
|
||||
write!(w, "\t\t(").unwrap();
|
||||
for idx in 0..types.len() {
|
||||
write!(w, "{}self.{}", if idx != 0 {", "} else {""}, ('a' as u8 + idx as u8) as char).unwrap();
|
||||
}
|
||||
writeln!(w, ")").unwrap();
|
||||
writeln!(w, "\t}}").unwrap();
|
||||
writeln!(w, "}}").unwrap();
|
||||
|
||||
if clonable {
|
||||
writeln!(w, "impl Clone for {} {{", mangled_container).unwrap();
|
||||
writeln!(w, "\tfn clone(&self) -> Self {{").unwrap();
|
||||
writeln!(w, "\t\tSelf {{").unwrap();
|
||||
for idx in 0..types.len() {
|
||||
writeln!(w, "\t\t\t{}: self.{}.clone(),", ('a' as u8 + idx as u8) as char, ('a' as u8 + idx as u8) as char).unwrap();
|
||||
}
|
||||
writeln!(w, "\t\t}}").unwrap();
|
||||
writeln!(w, "\t}}").unwrap();
|
||||
writeln!(w, "}}").unwrap();
|
||||
writeln!(w, "#[no_mangle]").unwrap();
|
||||
writeln!(w, "pub extern \"C\" fn {}_clone(orig: &{}) -> {} {{ orig.clone() }}", mangled_container, mangled_container, mangled_container).unwrap();
|
||||
}
|
||||
|
||||
write!(w, "#[no_mangle]\npub extern \"C\" fn {}_new(", mangled_container).unwrap();
|
||||
for (idx, gen) in types.iter().enumerate() {
|
||||
write!(w, "{}{}: ", if idx != 0 { ", " } else { "" }, ('a' as u8 + idx as u8) as char).unwrap();
|
||||
//if !self.write_c_type_intern(&mut created_container, gen, generics, false, false, false) { return false; }
|
||||
write!(w, "{}", gen).unwrap();
|
||||
}
|
||||
writeln!(w, ") -> {} {{", mangled_container).unwrap();
|
||||
write!(w, "\t{} {{ ", mangled_container).unwrap();
|
||||
for idx in 0..types.len() {
|
||||
write!(w, "{}, ", ('a' as u8 + idx as u8) as char).unwrap();
|
||||
}
|
||||
writeln!(w, "}}\n}}\n").unwrap();
|
||||
|
||||
writeln!(w, "#[no_mangle]").unwrap();
|
||||
writeln!(w, "pub extern \"C\" fn {}_free(_res: {}) {{ }}", mangled_container, mangled_container).unwrap();
|
||||
}
|
||||
|
||||
/// Prints the docs from a given attribute list unless its tagged no export
|
||||
pub fn writeln_docs<W: std::io::Write>(w: &mut W, attrs: &[syn::Attribute], prefix: &str) {
|
||||
for attr in attrs.iter() {
|
||||
|
|
|
@ -1786,9 +1786,11 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
|
|||
if tup.elems.is_empty() {
|
||||
write!(w, "u8").unwrap();
|
||||
} else {
|
||||
write!(w, "{}::C{}TupleTempl<", Self::container_templ_path(), tup.elems.len()).unwrap();
|
||||
self.write_template_generics(w, &mut tup.elems.iter(), generics, is_ref, in_crate);
|
||||
write!(w, ">").unwrap();
|
||||
let mut inner_args = Vec::new();
|
||||
for arg in tup.elems.iter() {
|
||||
inner_args.push(arg);
|
||||
}
|
||||
assert!(self.write_c_mangled_container_path(w, inner_args, generics, &format!("{}Tuple", tup.elems.len()), is_ref, false, false));
|
||||
}
|
||||
} else if let syn::Type::Path(p_arg) = t {
|
||||
let resolved_generic = self.resolve_path(&p_arg.path, generics);
|
||||
|
@ -1896,20 +1898,24 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
|
|||
if is_clonable {
|
||||
self.crate_types.clonable_types.insert(Self::generated_container_path().to_owned() + "::" + &mangled_container);
|
||||
}
|
||||
} else {
|
||||
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();
|
||||
|
||||
write!(&mut created_container, "#[no_mangle]\npub static {}_free: extern \"C\" fn({}) = ", mangled_container, mangled_container).unwrap();
|
||||
write!(&mut created_container, "{}::C{}Templ_free::<", 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();
|
||||
|
||||
if !self.write_template_constructor(&mut created_container, container_type, &mangled_container, &args, generics, is_ref) {
|
||||
return false;
|
||||
} else if container_type.ends_with("Tuple") {
|
||||
let mut tuple_args = Vec::new();
|
||||
let mut is_clonable = true;
|
||||
for arg in args.iter() {
|
||||
let mut ty: Vec<u8> = Vec::new();
|
||||
self.write_template_generics(&mut ty, &mut [arg].iter().map(|t| **t), generics, is_ref, true);
|
||||
let ty_str = String::from_utf8(ty).unwrap();
|
||||
if !self.is_clonable(&ty_str) {
|
||||
is_clonable = false;
|
||||
}
|
||||
tuple_args.push(ty_str);
|
||||
}
|
||||
write_tuple_block(&mut created_container, &mangled_container, &tuple_args, is_clonable);
|
||||
if is_clonable {
|
||||
self.crate_types.clonable_types.insert(Self::generated_container_path().to_owned() + "::" + &mangled_container);
|
||||
}
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
self.crate_types.templates_defined.insert(mangled_container.clone(), true);
|
||||
|
||||
|
@ -2008,7 +2014,6 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
|
|||
} else if let syn::Type::Path(p_arg) = arg {
|
||||
write_path!(p_arg, None);
|
||||
} else if let syn::Type::Reference(refty) = arg {
|
||||
if args.len() != 1 { return false; }
|
||||
if let syn::Type::Path(p_arg) = &*refty.elem {
|
||||
write_path!(p_arg, None);
|
||||
} else if let syn::Type::Slice(_) = &*refty.elem {
|
||||
|
@ -2016,6 +2021,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
|
|||
// make it a pointer so that its an option. Note that we cannot always convert
|
||||
// the Vec-as-slice (ie non-ref types) containers, so sometimes need to be able
|
||||
// to edit it, hence we use *mut here instead of *const.
|
||||
if args.len() != 1 { return false; }
|
||||
write!(w, "*mut ").unwrap();
|
||||
self.write_c_type(w, arg, None, true);
|
||||
} else { return false; }
|
||||
|
|
|
@ -298,56 +298,6 @@ impl<O, E> Drop for CResultTempl<O, E> {
|
|||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct C2TupleTempl<A, B> {
|
||||
pub a: A,
|
||||
pub b: B,
|
||||
}
|
||||
impl<A, B> From<(A, B)> for C2TupleTempl<A, B> {
|
||||
fn from(tup: (A, B)) -> Self {
|
||||
Self {
|
||||
a: tup.0,
|
||||
b: tup.1,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<A, B> C2TupleTempl<A, B> {
|
||||
pub(crate) fn to_rust(mut self) -> (A, B) {
|
||||
(self.a, self.b)
|
||||
}
|
||||
}
|
||||
pub extern "C" fn C2TupleTempl_free<A, B>(_res: C2TupleTempl<A, B>) { }
|
||||
impl <A: Clone, B: Clone> Clone for C2TupleTempl<A, B> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
a: self.a.clone(),
|
||||
b: self.b.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct C3TupleTempl<A, B, C> {
|
||||
pub a: A,
|
||||
pub b: B,
|
||||
pub c: C,
|
||||
}
|
||||
impl<A, B, C> From<(A, B, C)> for C3TupleTempl<A, B, C> {
|
||||
fn from(tup: (A, B, C)) -> Self {
|
||||
Self {
|
||||
a: tup.0,
|
||||
b: tup.1,
|
||||
c: tup.2,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<A, B, C> C3TupleTempl<A, B, C> {
|
||||
pub(crate) fn to_rust(mut self) -> (A, B, C) {
|
||||
(self.a, self.b, self.c)
|
||||
}
|
||||
}
|
||||
pub extern "C" fn C3TupleTempl_free<A, B, C>(_res: C3TupleTempl<A, B, C>) { }
|
||||
|
||||
/// Utility to make it easy to set a pointer to null and get its original value in line.
|
||||
pub(crate) trait TakePointer<T> {
|
||||
fn take_ptr(&mut self) -> T;
|
||||
|
|
Loading…
Add table
Reference in a new issue