Skip to content

Commit c6d2697

Browse files
committed
[bindings] Add support for mapping Write as a supertrait
1 parent dcfd95a commit c6d2697

File tree

1 file changed

+50
-4
lines changed

1 file changed

+50
-4
lines changed

c-bindings-gen/src/main.rs

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ fn convert_macro<W: std::io::Write>(w: &mut W, macro_path: &syn::Path, stream: &
4242
writeln!(w, "\tcrate::c_types::serialize_obj(unsafe {{ &(*(*obj).inner) }})").unwrap();
4343
writeln!(w, "}}").unwrap();
4444
writeln!(w, "#[no_mangle]").unwrap();
45+
writeln!(w, "pub(crate) extern \"C\" fn {}_write_void(obj: *const c_void) -> crate::c_types::derived::CVec_u8Z {{", struct_for).unwrap();
46+
writeln!(w, "\tcrate::c_types::serialize_obj(unsafe {{ &*(obj as *const native{}) }})", struct_for).unwrap();
47+
writeln!(w, "}}").unwrap();
48+
writeln!(w, "#[no_mangle]").unwrap();
4549
writeln!(w, "pub extern \"C\" fn {}_read(ser: crate::c_types::u8slice) -> {} {{", struct_for, struct_for).unwrap();
4650
writeln!(w, "\tif let Ok(res) = crate::c_types::deserialize_obj(ser) {{").unwrap();
4751
writeln!(w, "\t\t{} {{ inner: Box::into_raw(Box::new(res)), is_owned: true }}", struct_for).unwrap();
@@ -65,6 +69,10 @@ fn maybe_convert_trait_impl<W: std::io::Write>(w: &mut W, trait_path: &syn::Path
6569
writeln!(w, "pub extern \"C\" fn {}_write(obj: *const {}) -> crate::c_types::derived::CVec_u8Z {{", for_obj, for_obj).unwrap();
6670
writeln!(w, "\tcrate::c_types::serialize_obj(unsafe {{ &(*(*obj).inner) }})").unwrap();
6771
writeln!(w, "}}").unwrap();
72+
writeln!(w, "#[no_mangle]").unwrap();
73+
writeln!(w, "pub(crate) extern \"C\" fn {}_write_void(obj: *const c_void) -> crate::c_types::derived::CVec_u8Z {{", for_obj).unwrap();
74+
writeln!(w, "\tcrate::c_types::serialize_obj(unsafe {{ &*(obj as *const native{}) }})", for_obj).unwrap();
75+
writeln!(w, "}}").unwrap();
6876
},
6977
"util::ser::Readable" => {
7078
writeln!(w, "#[no_mangle]").unwrap();
@@ -80,6 +88,28 @@ fn maybe_convert_trait_impl<W: std::io::Write>(w: &mut W, trait_path: &syn::Path
8088
}
8189
}
8290

91+
/// Convert "TraitA : TraitB" to a single function name and return type.
92+
///
93+
/// This is (obviously) somewhat over-specialized and only useful for TraitB's that only require a
94+
/// single function (eg for serialization).
95+
fn convert_trait_impl_field(trait_path: &str) -> (String, &'static str) {
96+
match trait_path {
97+
"util::ser::Writeable" => ("write".to_owned(), "crate::c_types::derived::CVec_u8Z"),
98+
_ => unimplemented!(),
99+
}
100+
}
101+
102+
/// Companion to convert_trait_impl_field, write an assignment for the function defined by it for
103+
/// `for_obj` which implements the the trait at `trait_path`.
104+
fn write_trait_impl_field_assign<W: std::io::Write>(w: &mut W, trait_path: &str, for_obj: &syn::Ident) {
105+
match trait_path {
106+
"util::ser::Writeable" => {
107+
writeln!(w, "\t\twrite: {}_write_void,", for_obj).unwrap();
108+
},
109+
_ => unimplemented!(),
110+
}
111+
}
112+
83113
/// Write out the impl block for a defined trait struct which has a supertrait
84114
fn do_write_impl_trait<W: std::io::Write>(w: &mut W, trait_path: &str, trait_name: &syn::Ident, for_obj: &str) {
85115
match trait_path {
@@ -89,6 +119,13 @@ fn do_write_impl_trait<W: std::io::Write>(w: &mut W, trait_path: &str, trait_nam
89119
writeln!(w, "\t\t<crate::{} as lightning::{}>::get_and_clear_pending_msg_events(&self.{})", trait_path, trait_path, trait_name).unwrap();
90120
writeln!(w, "\t}}\n}}").unwrap();
91121
},
122+
"util::ser::Writeable" => {
123+
writeln!(w, "impl lightning::{} for {} {{", trait_path, for_obj).unwrap();
124+
writeln!(w, "\tfn write<W: lightning::util::ser::Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {{").unwrap();
125+
writeln!(w, "\t\tlet vec = (self.write)(self.this_arg);").unwrap();
126+
writeln!(w, "\t\tw.write_all(vec.as_slice())").unwrap();
127+
writeln!(w, "\t}}\n}}").unwrap();
128+
},
92129
_ => panic!(),
93130
}
94131
}
@@ -227,10 +264,15 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
227264
},
228265
("Send", _) => {}, ("Sync", _) => {},
229266
(s, i) => {
230-
// For in-crate supertraits, just store a C-mapped copy of the supertrait as a member.
231-
if types.crate_types.traits.get(s).is_none() { unimplemented!(); }
232-
writeln!(w, "\tpub {}: crate::{},", i, s).unwrap();
233-
generated_fields.push(format!("{}", i));
267+
generated_fields.push(if types.crate_types.traits.get(s).is_none() {
268+
let (name, ret) = convert_trait_impl_field(s);
269+
writeln!(w, "\tpub {}: extern \"C\" fn (this_arg: *const c_void) -> {},", name, ret).unwrap();
270+
name
271+
} else {
272+
// For in-crate supertraits, just store a C-mapped copy of the supertrait as a member.
273+
writeln!(w, "\tpub {}: crate::{},", i, s).unwrap();
274+
format!("{}", i)
275+
});
234276
}
235277
) );
236278
writeln!(w, "\tpub free: Option<extern \"C\" fn(this_arg: *mut c_void)>,").unwrap();
@@ -670,6 +712,8 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
670712
("Clone", _) => {
671713
writeln!(w, "\t\tclone: Some({}_clone_void),", ident).unwrap();
672714
},
715+
("Sync", _) => {}, ("Send", _) => {},
716+
("std::marker::Sync", _) => {}, ("std::marker::Send", _) => {},
673717
(s, t) => {
674718
if let Some(supertrait_obj) = types.crate_types.traits.get(s) {
675719
writeln!(w, "\t\t{}: crate::{} {{", t, s).unwrap();
@@ -684,6 +728,8 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
684728
}
685729
}
686730
write!(w, "\t\t}},\n").unwrap();
731+
} else {
732+
write_trait_impl_field_assign(w, s, ident);
687733
}
688734
}
689735
) );

0 commit comments

Comments
 (0)