@@ -32,6 +32,261 @@ pub fn write_cpp_wrapper(cpp_header_file: &mut File, ty: &str, has_destructor: b
3232 writeln ! ( cpp_header_file, "}};" ) . unwrap ( ) ;
3333}
3434
35+ /// Writes out a C-callable concrete Result<A, B> struct and utility methods
36+ pub fn write_result_block < W : std:: io:: Write > ( w : & mut W , mangled_container : & str , ok_type : & str , err_type : & str , clonable : bool ) {
37+ writeln ! ( w, "#[repr(C)]" ) . unwrap ( ) ;
38+ writeln ! ( w, "pub union {}Ptr {{" , mangled_container) . unwrap ( ) ;
39+ if ok_type != "()" {
40+ writeln ! ( w, "\t pub result: *mut {}," , ok_type) . unwrap ( ) ;
41+ } else {
42+ writeln ! ( w, "\t /// Note that this value is always NULL, as there are no contents in the OK variant" ) . unwrap ( ) ;
43+ writeln ! ( w, "\t pub result: *mut std::ffi::c_void," ) . unwrap ( ) ;
44+ }
45+ if err_type != "()" {
46+ writeln ! ( w, "\t pub err: *mut {}," , err_type) . unwrap ( ) ;
47+ } else {
48+ writeln ! ( w, "\t /// Note that this value is always NULL, as there are no contents in the Err variant" ) . unwrap ( ) ;
49+ writeln ! ( w, "\t pub err: *mut std::ffi::c_void," ) . unwrap ( ) ;
50+ }
51+ writeln ! ( w, "}}" ) . unwrap ( ) ;
52+ writeln ! ( w, "#[repr(C)]" ) . unwrap ( ) ;
53+ writeln ! ( w, "pub struct {} {{" , mangled_container) . unwrap ( ) ;
54+ writeln ! ( w, "\t pub contents: {}Ptr," , mangled_container) . unwrap ( ) ;
55+ writeln ! ( w, "\t pub result_ok: bool," ) . unwrap ( ) ;
56+ writeln ! ( w, "}}" ) . unwrap ( ) ;
57+
58+ writeln ! ( w, "#[no_mangle]" ) . unwrap ( ) ;
59+ if ok_type != "()" {
60+ writeln ! ( w, "pub extern \" C\" fn {}_ok(o: {}) -> {} {{" , mangled_container, ok_type, mangled_container) . unwrap ( ) ;
61+ } else {
62+ writeln ! ( w, "pub extern \" C\" fn {}_ok() -> {} {{" , mangled_container, mangled_container) . unwrap ( ) ;
63+ }
64+ writeln ! ( w, "\t {} {{" , mangled_container) . unwrap ( ) ;
65+ writeln ! ( w, "\t \t contents: {}Ptr {{" , mangled_container) . unwrap ( ) ;
66+ if ok_type != "()" {
67+ writeln ! ( w, "\t \t \t result: Box::into_raw(Box::new(o))," ) . unwrap ( ) ;
68+ } else {
69+ writeln ! ( w, "\t \t \t result: std::ptr::null_mut()," ) . unwrap ( ) ;
70+ }
71+ writeln ! ( w, "\t \t }}," ) . unwrap ( ) ;
72+ writeln ! ( w, "\t \t result_ok: true," ) . unwrap ( ) ;
73+ writeln ! ( w, "\t }}" ) . unwrap ( ) ;
74+ writeln ! ( w, "}}" ) . unwrap ( ) ;
75+
76+ writeln ! ( w, "#[no_mangle]" ) . unwrap ( ) ;
77+ if err_type != "()" {
78+ writeln ! ( w, "pub extern \" C\" fn {}_err(e: {}) -> {} {{" , mangled_container, err_type, mangled_container) . unwrap ( ) ;
79+ } else {
80+ writeln ! ( w, "pub extern \" C\" fn {}_err() -> {} {{" , mangled_container, mangled_container) . unwrap ( ) ;
81+ }
82+ writeln ! ( w, "\t {} {{" , mangled_container) . unwrap ( ) ;
83+ writeln ! ( w, "\t \t contents: {}Ptr {{" , mangled_container) . unwrap ( ) ;
84+ if err_type != "()" {
85+ writeln ! ( w, "\t \t \t err: Box::into_raw(Box::new(e))," ) . unwrap ( ) ;
86+ } else {
87+ writeln ! ( w, "\t \t \t err: std::ptr::null_mut()," ) . unwrap ( ) ;
88+ }
89+ writeln ! ( w, "\t \t }}," ) . unwrap ( ) ;
90+ writeln ! ( w, "\t \t result_ok: false," ) . unwrap ( ) ;
91+ writeln ! ( w, "\t }}" ) . unwrap ( ) ;
92+ writeln ! ( w, "}}" ) . unwrap ( ) ;
93+
94+ writeln ! ( w, "#[no_mangle]" ) . unwrap ( ) ;
95+ writeln ! ( w, "pub extern \" C\" fn {}_free(_res: {}) {{ }}" , mangled_container, mangled_container) . unwrap ( ) ;
96+ writeln ! ( w, "impl Drop for {} {{" , mangled_container) . unwrap ( ) ;
97+ writeln ! ( w, "\t fn drop(&mut self) {{" ) . unwrap ( ) ;
98+ writeln ! ( w, "\t \t if self.result_ok {{" ) . unwrap ( ) ;
99+ if ok_type != "()" {
100+ writeln ! ( w, "\t \t \t if unsafe {{ !(self.contents.result as *mut ()).is_null() }} {{" ) . unwrap ( ) ;
101+ writeln ! ( w, "\t \t \t \t let _ = unsafe {{ Box::from_raw(self.contents.result) }};" ) . unwrap ( ) ;
102+ writeln ! ( w, "\t \t \t }}" ) . unwrap ( ) ;
103+ }
104+ writeln ! ( w, "\t \t }} else {{" ) . unwrap ( ) ;
105+ if err_type != "()" {
106+ writeln ! ( w, "\t \t \t if unsafe {{ !(self.contents.err as *mut ()).is_null() }} {{" ) . unwrap ( ) ;
107+ writeln ! ( w, "\t \t \t \t let _ = unsafe {{ Box::from_raw(self.contents.err) }};" ) . unwrap ( ) ;
108+ writeln ! ( w, "\t \t \t }}" ) . unwrap ( ) ;
109+ }
110+ writeln ! ( w, "\t \t }}" ) . unwrap ( ) ;
111+ writeln ! ( w, "\t }}" ) . unwrap ( ) ;
112+ writeln ! ( w, "}}" ) . unwrap ( ) ;
113+
114+ // TODO: Templates should use () now that they can, too
115+ let templ_ok_type = if ok_type != "()" { ok_type } else { "u8" } ;
116+ let templ_err_type = if err_type != "()" { err_type } else { "u8" } ;
117+
118+ writeln ! ( w, "impl From<crate::c_types::CResultTempl<{}, {}>> for {} {{" , templ_ok_type, templ_err_type, mangled_container) . unwrap ( ) ;
119+ writeln ! ( w, "\t fn from(mut o: crate::c_types::CResultTempl<{}, {}>) -> Self {{" , templ_ok_type, templ_err_type) . unwrap ( ) ;
120+ writeln ! ( w, "\t \t let contents = if o.result_ok {{" ) . unwrap ( ) ;
121+ if ok_type != "()" {
122+ writeln ! ( w, "\t \t \t let result = unsafe {{ o.contents.result }};" ) . unwrap ( ) ;
123+ writeln ! ( w, "\t \t \t unsafe {{ o.contents.result = std::ptr::null_mut() }};" ) . unwrap ( ) ;
124+ writeln ! ( w, "\t \t \t {}Ptr {{ result }}" , mangled_container) . unwrap ( ) ;
125+ } else {
126+ writeln ! ( w, "\t \t \t let _ = unsafe {{ Box::from_raw(o.contents.result) }};" ) . unwrap ( ) ;
127+ writeln ! ( w, "\t \t \t o.contents.result = std::ptr::null_mut();" ) . unwrap ( ) ;
128+ writeln ! ( w, "\t \t \t {}Ptr {{ result: std::ptr::null_mut() }}" , mangled_container) . unwrap ( ) ;
129+ }
130+ writeln ! ( w, "\t \t }} else {{" ) . unwrap ( ) ;
131+ if err_type != "()" {
132+ writeln ! ( w, "\t \t \t let err = unsafe {{ o.contents.err }};" ) . unwrap ( ) ;
133+ writeln ! ( w, "\t \t \t unsafe {{ o.contents.err = std::ptr::null_mut(); }}" ) . unwrap ( ) ;
134+ writeln ! ( w, "\t \t \t {}Ptr {{ err }}" , mangled_container) . unwrap ( ) ;
135+ } else {
136+ writeln ! ( w, "\t \t \t let _ = unsafe {{ Box::from_raw(o.contents.err) }};" ) . unwrap ( ) ;
137+ writeln ! ( w, "\t \t \t o.contents.err = std::ptr::null_mut();" ) . unwrap ( ) ;
138+ writeln ! ( w, "\t \t \t {}Ptr {{ err: std::ptr::null_mut() }}" , mangled_container) . unwrap ( ) ;
139+ }
140+ writeln ! ( w, "\t \t }};" ) . unwrap ( ) ;
141+ writeln ! ( w, "\t \t Self {{" ) . unwrap ( ) ;
142+ writeln ! ( w, "\t \t \t contents," ) . unwrap ( ) ;
143+ writeln ! ( w, "\t \t \t result_ok: o.result_ok," ) . unwrap ( ) ;
144+ writeln ! ( w, "\t \t }}" ) . unwrap ( ) ;
145+ writeln ! ( w, "\t }}" ) . unwrap ( ) ;
146+ writeln ! ( w, "}}" ) . unwrap ( ) ;
147+
148+ if clonable {
149+ writeln ! ( w, "impl Clone for {} {{" , mangled_container) . unwrap ( ) ;
150+ writeln ! ( w, "\t fn clone(&self) -> Self {{" ) . unwrap ( ) ;
151+ writeln ! ( w, "\t \t if self.result_ok {{" ) . unwrap ( ) ;
152+ writeln ! ( w, "\t \t \t Self {{ result_ok: true, contents: {}Ptr {{" , mangled_container) . unwrap ( ) ;
153+ if ok_type != "()" {
154+ writeln ! ( w, "\t \t \t \t result: Box::into_raw(Box::new(<{}>::clone(unsafe {{ &*self.contents.result }})))" , ok_type) . unwrap ( ) ;
155+ } else {
156+ writeln ! ( w, "\t \t \t \t result: std::ptr::null_mut()" ) . unwrap ( ) ;
157+ }
158+ writeln ! ( w, "\t \t \t }} }}" ) . unwrap ( ) ;
159+ writeln ! ( w, "\t \t }} else {{" ) . unwrap ( ) ;
160+ writeln ! ( w, "\t \t \t Self {{ result_ok: false, contents: {}Ptr {{" , mangled_container) . unwrap ( ) ;
161+ if err_type != "()" {
162+ writeln ! ( w, "\t \t \t \t err: Box::into_raw(Box::new(<{}>::clone(unsafe {{ &*self.contents.err }})))" , err_type) . unwrap ( ) ;
163+ } else {
164+ writeln ! ( w, "\t \t \t \t err: std::ptr::null_mut()" ) . unwrap ( ) ;
165+ }
166+ writeln ! ( w, "\t \t \t }} }}" ) . unwrap ( ) ;
167+ writeln ! ( w, "\t \t }}" ) . unwrap ( ) ;
168+ writeln ! ( w, "\t }}" ) . unwrap ( ) ;
169+ writeln ! ( w, "}}" ) . unwrap ( ) ;
170+ writeln ! ( w, "#[no_mangle]" ) . unwrap ( ) ;
171+ writeln ! ( w, "pub extern \" C\" fn {}_clone(orig: &{}) -> {} {{ orig.clone() }}" , mangled_container, mangled_container, mangled_container) . unwrap ( ) ;
172+ }
173+ }
174+
175+ /// Writes out a C-callable concrete Vec<A> struct and utility methods
176+ pub fn write_vec_block < W : std:: io:: Write > ( w : & mut W , mangled_container : & str , inner_type : & str , clonable : bool ) {
177+ writeln ! ( w, "#[repr(C)]" ) . unwrap ( ) ;
178+ writeln ! ( w, "pub struct {} {{" , mangled_container) . unwrap ( ) ;
179+ writeln ! ( w, "\t pub data: *mut {}," , inner_type) . unwrap ( ) ;
180+ writeln ! ( w, "\t pub datalen: usize" ) . unwrap ( ) ;
181+ writeln ! ( w, "}}" ) . unwrap ( ) ;
182+
183+ writeln ! ( w, "impl {} {{" , mangled_container) . unwrap ( ) ;
184+ writeln ! ( w, "\t #[allow(unused)] pub(crate) fn into_rust(&mut self) -> Vec<{}> {{" , inner_type) . unwrap ( ) ;
185+ writeln ! ( w, "\t \t if self.datalen == 0 {{ return Vec::new(); }}" ) . unwrap ( ) ;
186+ writeln ! ( w, "\t \t let ret = unsafe {{ Box::from_raw(std::slice::from_raw_parts_mut(self.data, self.datalen)) }}.into();" ) . unwrap ( ) ;
187+ writeln ! ( w, "\t \t self.data = std::ptr::null_mut();" ) . unwrap ( ) ;
188+ writeln ! ( w, "\t \t self.datalen = 0;" ) . unwrap ( ) ;
189+ writeln ! ( w, "\t \t ret" ) . unwrap ( ) ;
190+ writeln ! ( w, "\t }}" ) . unwrap ( ) ;
191+ writeln ! ( w, "\t #[allow(unused)] pub(crate) fn as_slice(&self) -> &[{}] {{" , inner_type) . unwrap ( ) ;
192+ writeln ! ( w, "\t \t unsafe {{ std::slice::from_raw_parts_mut(self.data, self.datalen) }}" ) . unwrap ( ) ;
193+ writeln ! ( w, "\t }}" ) . unwrap ( ) ;
194+ writeln ! ( w, "}}" ) . unwrap ( ) ;
195+
196+ writeln ! ( w, "impl From<Vec<{}>> for {} {{" , inner_type, mangled_container) . unwrap ( ) ;
197+ writeln ! ( w, "\t fn from(v: Vec<{}>) -> Self {{" , inner_type) . unwrap ( ) ;
198+ writeln ! ( w, "\t \t let datalen = v.len();" ) . unwrap ( ) ;
199+ writeln ! ( w, "\t \t let data = Box::into_raw(v.into_boxed_slice());" ) . unwrap ( ) ;
200+ writeln ! ( w, "\t \t Self {{ datalen, data: unsafe {{ (*data).as_mut_ptr() }} }}" ) . unwrap ( ) ;
201+ writeln ! ( w, "\t }}" ) . unwrap ( ) ;
202+ writeln ! ( w, "}}" ) . unwrap ( ) ;
203+
204+ writeln ! ( w, "#[no_mangle]" ) . unwrap ( ) ;
205+ writeln ! ( w, "pub extern \" C\" fn {}_free(_res: {}) {{ }}" , mangled_container, mangled_container) . unwrap ( ) ;
206+ writeln ! ( w, "impl Drop for {} {{" , mangled_container) . unwrap ( ) ;
207+ writeln ! ( w, "\t fn drop(&mut self) {{" ) . unwrap ( ) ;
208+ writeln ! ( w, "\t \t if self.datalen == 0 {{ return; }}" ) . unwrap ( ) ;
209+ writeln ! ( w, "\t \t unsafe {{ Box::from_raw(std::slice::from_raw_parts_mut(self.data, self.datalen)) }};" ) . unwrap ( ) ;
210+ writeln ! ( w, "\t }}" ) . unwrap ( ) ;
211+ writeln ! ( w, "}}" ) . unwrap ( ) ;
212+ if clonable {
213+ writeln ! ( w, "impl Clone for {} {{" , mangled_container) . unwrap ( ) ;
214+ writeln ! ( w, "\t fn clone(&self) -> Self {{" ) . unwrap ( ) ;
215+ writeln ! ( w, "\t \t let mut res = Vec::new();" ) . unwrap ( ) ;
216+ writeln ! ( w, "\t \t if self.datalen == 0 {{ return Self::from(res); }}" ) . unwrap ( ) ;
217+ writeln ! ( w, "\t \t res.extend_from_slice(unsafe {{ std::slice::from_raw_parts_mut(self.data, self.datalen) }});" ) . unwrap ( ) ;
218+ writeln ! ( w, "\t \t Self::from(res)" ) . unwrap ( ) ;
219+ writeln ! ( w, "\t }}" ) . unwrap ( ) ;
220+ writeln ! ( w, "}}" ) . unwrap ( ) ;
221+ }
222+ }
223+
224+ /// Writes out a C-callable concrete (A, B, ...) struct and utility methods
225+ pub fn write_tuple_block < W : std:: io:: Write > ( w : & mut W , mangled_container : & str , types : & [ String ] , clonable : bool ) {
226+ writeln ! ( w, "#[repr(C)]" ) . unwrap ( ) ;
227+ writeln ! ( w, "pub struct {} {{" , mangled_container) . unwrap ( ) ;
228+ for ( idx, ty) in types. iter ( ) . enumerate ( ) {
229+ writeln ! ( w, "\t pub {}: {}," , ( 'a' as u8 + idx as u8 ) as char , ty) . unwrap ( ) ;
230+ }
231+ writeln ! ( w, "}}" ) . unwrap ( ) ;
232+
233+ let mut tuple_str = "(" . to_owned ( ) ;
234+ for ( idx, ty) in types. iter ( ) . enumerate ( ) {
235+ if idx != 0 { tuple_str += ", " ; }
236+ tuple_str += ty;
237+ }
238+ tuple_str += ")" ;
239+
240+ writeln ! ( w, "impl From<{}> for {} {{" , tuple_str, mangled_container) . unwrap ( ) ;
241+ writeln ! ( w, "\t fn from (tup: {}) -> Self {{" , tuple_str) . unwrap ( ) ;
242+ writeln ! ( w, "\t \t Self {{" ) . unwrap ( ) ;
243+ for idx in 0 ..types. len ( ) {
244+ writeln ! ( w, "\t \t \t {}: tup.{}," , ( 'a' as u8 + idx as u8 ) as char , idx) . unwrap ( ) ;
245+ }
246+ writeln ! ( w, "\t \t }}" ) . unwrap ( ) ;
247+ writeln ! ( w, "\t }}" ) . unwrap ( ) ;
248+ writeln ! ( w, "}}" ) . unwrap ( ) ;
249+ writeln ! ( w, "impl {} {{" , mangled_container) . unwrap ( ) ;
250+ writeln ! ( w, "\t #[allow(unused)] pub(crate) fn to_rust(mut self) -> {} {{" , tuple_str) . unwrap ( ) ;
251+ write ! ( w, "\t \t (" ) . unwrap ( ) ;
252+ for idx in 0 ..types. len ( ) {
253+ write ! ( w, "{}self.{}" , if idx != 0 { ", " } else { "" } , ( 'a' as u8 + idx as u8 ) as char ) . unwrap ( ) ;
254+ }
255+ writeln ! ( w, ")" ) . unwrap ( ) ;
256+ writeln ! ( w, "\t }}" ) . unwrap ( ) ;
257+ writeln ! ( w, "}}" ) . unwrap ( ) ;
258+
259+ if clonable {
260+ writeln ! ( w, "impl Clone for {} {{" , mangled_container) . unwrap ( ) ;
261+ writeln ! ( w, "\t fn clone(&self) -> Self {{" ) . unwrap ( ) ;
262+ writeln ! ( w, "\t \t Self {{" ) . unwrap ( ) ;
263+ for idx in 0 ..types. len ( ) {
264+ writeln ! ( w, "\t \t \t {}: self.{}.clone()," , ( 'a' as u8 + idx as u8 ) as char , ( 'a' as u8 + idx as u8 ) as char ) . unwrap ( ) ;
265+ }
266+ writeln ! ( w, "\t \t }}" ) . unwrap ( ) ;
267+ writeln ! ( w, "\t }}" ) . unwrap ( ) ;
268+ writeln ! ( w, "}}" ) . unwrap ( ) ;
269+ writeln ! ( w, "#[no_mangle]" ) . unwrap ( ) ;
270+ writeln ! ( w, "pub extern \" C\" fn {}_clone(orig: &{}) -> {} {{ orig.clone() }}" , mangled_container, mangled_container, mangled_container) . unwrap ( ) ;
271+ }
272+
273+ write ! ( w, "#[no_mangle]\n pub extern \" C\" fn {}_new(" , mangled_container) . unwrap ( ) ;
274+ for ( idx, gen) in types. iter ( ) . enumerate ( ) {
275+ write ! ( w, "{}{}: " , if idx != 0 { ", " } else { "" } , ( 'a' as u8 + idx as u8 ) as char ) . unwrap ( ) ;
276+ //if !self.write_c_type_intern(&mut created_container, gen, generics, false, false, false) { return false; }
277+ write ! ( w, "{}" , gen ) . unwrap ( ) ;
278+ }
279+ writeln ! ( w, ") -> {} {{" , mangled_container) . unwrap ( ) ;
280+ write ! ( w, "\t {} {{ " , mangled_container) . unwrap ( ) ;
281+ for idx in 0 ..types. len ( ) {
282+ write ! ( w, "{}, " , ( 'a' as u8 + idx as u8 ) as char ) . unwrap ( ) ;
283+ }
284+ writeln ! ( w, "}}\n }}\n " ) . unwrap ( ) ;
285+
286+ writeln ! ( w, "#[no_mangle]" ) . unwrap ( ) ;
287+ writeln ! ( w, "pub extern \" C\" fn {}_free(_res: {}) {{ }}" , mangled_container, mangled_container) . unwrap ( ) ;
288+ }
289+
35290/// Prints the docs from a given attribute list unless its tagged no export
36291pub fn writeln_docs < W : std:: io:: Write > ( w : & mut W , attrs : & [ syn:: Attribute ] , prefix : & str ) {
37292 for attr in attrs. iter ( ) {
0 commit comments