@@ -32,6 +32,261 @@ pub fn write_cpp_wrapper(cpp_header_file: &mut File, ty: &str, has_destructor: b
32
32
writeln ! ( cpp_header_file, "}};" ) . unwrap ( ) ;
33
33
}
34
34
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
+
35
290
/// Prints the docs from a given attribute list unless its tagged no export
36
291
pub fn writeln_docs < W : std:: io:: Write > ( w : & mut W , attrs : & [ syn:: Attribute ] , prefix : & str ) {
37
292
for attr in attrs. iter ( ) {
0 commit comments