1
+ use oo_bindgen:: callback:: * ;
1
2
use oo_bindgen:: formatting:: * ;
2
3
use oo_bindgen:: native_enum:: * ;
3
4
use oo_bindgen:: native_function:: * ;
4
5
use oo_bindgen:: native_struct:: * ;
5
- use oo_bindgen:: callback:: * ;
6
6
7
7
pub ( crate ) trait RustType {
8
8
fn as_rust_type ( & self ) -> String ;
9
9
fn as_c_type ( & self ) -> String ;
10
10
fn is_copyable ( & self ) -> bool ;
11
+ fn rust_requires_lifetime ( & self ) -> bool ;
12
+ fn c_requires_lifetime ( & self ) -> bool ;
11
13
fn conversion ( & self ) -> Option < Box < dyn TypeConverter > > ;
12
14
fn has_conversion ( & self ) -> bool {
13
15
self . conversion ( ) . is_some ( )
@@ -28,13 +30,13 @@ impl RustType for Type {
28
30
Type :: Sint64 => "i64" . to_string ( ) ,
29
31
Type :: Float => "f32" . to_string ( ) ,
30
32
Type :: Double => "f64" . to_string ( ) ,
31
- Type :: String => "*const std::os::raw::c_char " . to_string ( ) ,
32
- Type :: Struct ( handle) => format ! ( "{}" , handle. name( ) ) ,
33
+ Type :: String => "&'a std::ffi::CStr " . to_string ( ) ,
34
+ Type :: Struct ( handle) => handle. name ( ) . to_string ( ) ,
33
35
Type :: StructRef ( handle) => format ! ( "Option<&{}>" , handle. name) ,
34
- Type :: Enum ( handle) => format ! ( "{}" , handle. name) ,
36
+ Type :: Enum ( handle) => handle. name . to_string ( ) ,
35
37
Type :: ClassRef ( handle) => format ! ( "*mut crate::{}" , handle. name) ,
36
- Type :: Interface ( handle) => format ! ( "{}" , handle. name) ,
37
- Type :: OneTimeCallback ( handle) => format ! ( "{}" , handle. name) ,
38
+ Type :: Interface ( handle) => handle. name . to_string ( ) ,
39
+ Type :: OneTimeCallback ( handle) => handle. name . to_string ( ) ,
38
40
Type :: Iterator ( handle) => {
39
41
let lifetime = if handle. has_lifetime_annotation {
40
42
"<'a>"
@@ -44,10 +46,7 @@ impl RustType for Type {
44
46
format ! ( "*mut crate::{}{}" , handle. name( ) , lifetime)
45
47
}
46
48
Type :: Collection ( handle) => format ! ( "*mut crate::{}" , handle. name( ) ) ,
47
- Type :: Duration ( mapping) => match mapping {
48
- DurationMapping :: Milliseconds | DurationMapping :: Seconds => "u64" . to_string ( ) ,
49
- DurationMapping :: SecondsFloat => "f32" . to_string ( ) ,
50
- } ,
49
+ Type :: Duration ( _) => "std::time::Duration" . to_string ( ) ,
51
50
}
52
51
}
53
52
@@ -100,7 +99,7 @@ impl RustType for Type {
100
99
Type :: Sint64 => true ,
101
100
Type :: Float => true ,
102
101
Type :: Double => true ,
103
- Type :: String => true , // Just copying the pointer
102
+ Type :: String => true , // Just copying the reference
104
103
Type :: Struct ( _) => false ,
105
104
Type :: StructRef ( _) => true ,
106
105
Type :: Enum ( _) => true ,
@@ -113,6 +112,58 @@ impl RustType for Type {
113
112
}
114
113
}
115
114
115
+ fn rust_requires_lifetime ( & self ) -> bool {
116
+ match self {
117
+ Type :: Bool => false ,
118
+ Type :: Uint8 => false ,
119
+ Type :: Sint8 => false ,
120
+ Type :: Uint16 => false ,
121
+ Type :: Sint16 => false ,
122
+ Type :: Uint32 => false ,
123
+ Type :: Sint32 => false ,
124
+ Type :: Uint64 => false ,
125
+ Type :: Sint64 => false ,
126
+ Type :: Float => false ,
127
+ Type :: Double => false ,
128
+ Type :: String => true ,
129
+ Type :: Struct ( _) => false ,
130
+ Type :: StructRef ( _) => false ,
131
+ Type :: Enum ( _) => false ,
132
+ Type :: ClassRef ( _) => false ,
133
+ Type :: Interface ( _) => false ,
134
+ Type :: OneTimeCallback ( _) => false ,
135
+ Type :: Iterator ( _) => true ,
136
+ Type :: Collection ( _) => false ,
137
+ Type :: Duration ( _) => false ,
138
+ }
139
+ }
140
+
141
+ fn c_requires_lifetime ( & self ) -> bool {
142
+ match self {
143
+ Type :: Bool => false ,
144
+ Type :: Uint8 => false ,
145
+ Type :: Sint8 => false ,
146
+ Type :: Uint16 => false ,
147
+ Type :: Sint16 => false ,
148
+ Type :: Uint32 => false ,
149
+ Type :: Sint32 => false ,
150
+ Type :: Uint64 => false ,
151
+ Type :: Sint64 => false ,
152
+ Type :: Float => false ,
153
+ Type :: Double => false ,
154
+ Type :: String => false ,
155
+ Type :: Struct ( _) => false ,
156
+ Type :: StructRef ( _) => false ,
157
+ Type :: Enum ( _) => false ,
158
+ Type :: ClassRef ( _) => false ,
159
+ Type :: Interface ( _) => false ,
160
+ Type :: OneTimeCallback ( _) => false ,
161
+ Type :: Iterator ( _) => true ,
162
+ Type :: Collection ( _) => false ,
163
+ Type :: Duration ( _) => false ,
164
+ }
165
+ }
166
+
116
167
fn conversion ( & self ) -> Option < Box < dyn TypeConverter > > {
117
168
match self {
118
169
Type :: Bool => None ,
@@ -126,7 +177,7 @@ impl RustType for Type {
126
177
Type :: Sint64 => None ,
127
178
Type :: Float => None ,
128
179
Type :: Double => None ,
129
- Type :: String => None ,
180
+ Type :: String => Some ( Box :: new ( StringConverter ) ) ,
130
181
Type :: Struct ( _) => None ,
131
182
Type :: StructRef ( handle) => Some ( Box :: new ( StructRefConverter ( handle. clone ( ) ) ) ) ,
132
183
Type :: Enum ( handle) => Some ( Box :: new ( EnumConverter ( handle. clone ( ) ) ) ) ,
@@ -135,7 +186,7 @@ impl RustType for Type {
135
186
Type :: OneTimeCallback ( _) => None ,
136
187
Type :: Iterator ( _) => None ,
137
188
Type :: Collection ( _) => None ,
138
- Type :: Duration ( _ ) => None ,
189
+ Type :: Duration ( mapping ) => Some ( Box :: new ( DurationConverter ( * mapping ) ) ) ,
139
190
}
140
191
}
141
192
}
@@ -165,6 +216,22 @@ impl RustType for ReturnType {
165
216
}
166
217
}
167
218
219
+ fn rust_requires_lifetime ( & self ) -> bool {
220
+ if let ReturnType :: Type ( return_type, _) = self {
221
+ return_type. rust_requires_lifetime ( )
222
+ } else {
223
+ false
224
+ }
225
+ }
226
+
227
+ fn c_requires_lifetime ( & self ) -> bool {
228
+ if let ReturnType :: Type ( return_type, _) = self {
229
+ return_type. c_requires_lifetime ( )
230
+ } else {
231
+ false
232
+ }
233
+ }
234
+
168
235
fn conversion ( & self ) -> Option < Box < dyn TypeConverter > > {
169
236
if let ReturnType :: Type ( return_type, _) = self {
170
237
return_type. conversion ( )
@@ -177,6 +244,25 @@ impl RustType for ReturnType {
177
244
pub ( crate ) trait TypeConverter {
178
245
fn convert_to_c ( & self , f : & mut dyn Printer , from : & str , to : & str ) -> FormattingResult < ( ) > ;
179
246
fn convert_from_c ( & self , f : & mut dyn Printer , from : & str , to : & str ) -> FormattingResult < ( ) > ;
247
+ fn is_unsafe ( & self ) -> bool {
248
+ false
249
+ }
250
+ }
251
+
252
+ struct StringConverter ;
253
+
254
+ impl TypeConverter for StringConverter {
255
+ fn convert_to_c ( & self , f : & mut dyn Printer , from : & str , to : & str ) -> FormattingResult < ( ) > {
256
+ f. writeln ( & format ! ( "{}{}.as_ptr()" , to, from) )
257
+ }
258
+
259
+ fn convert_from_c ( & self , f : & mut dyn Printer , from : & str , to : & str ) -> FormattingResult < ( ) > {
260
+ f. writeln ( & format ! ( "{}std::ffi::CStr::from_ptr({})" , to, from) )
261
+ }
262
+
263
+ fn is_unsafe ( & self ) -> bool {
264
+ true
265
+ }
180
266
}
181
267
182
268
struct EnumConverter ( NativeEnumHandle ) ;
@@ -206,59 +292,97 @@ impl TypeConverter for StructRefConverter {
206
292
}
207
293
}
208
294
295
+ struct DurationConverter ( DurationMapping ) ;
296
+
297
+ impl TypeConverter for DurationConverter {
298
+ fn convert_to_c ( & self , f : & mut dyn Printer , from : & str , to : & str ) -> FormattingResult < ( ) > {
299
+ match self . 0 {
300
+ DurationMapping :: Milliseconds => {
301
+ f. writeln ( & format ! ( "{}{}.as_millis() as u64" , to, from) )
302
+ }
303
+ DurationMapping :: Seconds => f. writeln ( & format ! ( "{}{}.as_secs()" , to, from) ) ,
304
+ DurationMapping :: SecondsFloat => f. writeln ( & format ! ( "{}{}.as_secs_f32()" , to, from) ) ,
305
+ }
306
+ }
307
+
308
+ fn convert_from_c ( & self , f : & mut dyn Printer , from : & str , to : & str ) -> FormattingResult < ( ) > {
309
+ match self . 0 {
310
+ DurationMapping :: Milliseconds => {
311
+ f. writeln ( & format ! ( "{}std::time::Duration::from_millis({})" , to, from) )
312
+ }
313
+ DurationMapping :: Seconds => {
314
+ f. writeln ( & format ! ( "{}std::time::Duration::from_secs({})" , to, from) )
315
+ }
316
+ DurationMapping :: SecondsFloat => f. writeln ( & format ! (
317
+ "{}std::time::Duration::from_secs_f32({})" ,
318
+ to, from
319
+ ) ) ,
320
+ }
321
+ }
322
+ }
323
+
209
324
pub ( crate ) trait RustStruct {
210
- fn requires_lifetime_annotation ( & self ) -> bool ;
325
+ fn rust_requires_lifetime ( & self ) -> bool ;
326
+ fn c_requires_lifetime ( & self ) -> bool ;
211
327
fn has_conversion ( & self ) -> bool ;
212
328
}
213
329
214
330
impl RustStruct for NativeStructHandle {
215
- fn requires_lifetime_annotation ( & self ) -> bool {
216
- self . elements
217
- . iter ( )
218
- . any ( |e| e. requires_lifetime_annotation ( ) )
331
+ fn rust_requires_lifetime ( & self ) -> bool {
332
+ self . elements . iter ( ) . any ( |e| e. rust_requires_lifetime ( ) )
219
333
}
220
334
221
- fn has_conversion ( & self ) -> bool {
222
- for element in & self . elements {
223
- if element. element_type . has_conversion ( ) {
224
- return true ;
225
- }
226
- }
335
+ fn c_requires_lifetime ( & self ) -> bool {
336
+ self . elements . iter ( ) . any ( |e| e. c_requires_lifetime ( ) )
337
+ }
227
338
228
- false
339
+ fn has_conversion ( & self ) -> bool {
340
+ self . elements
341
+ . iter ( )
342
+ . any ( |e| e. element_type . has_conversion ( ) )
229
343
}
230
344
}
231
345
232
346
pub ( crate ) trait RustStructField {
233
- fn requires_lifetime_annotation ( & self ) -> bool ;
347
+ fn rust_requires_lifetime ( & self ) -> bool ;
348
+ fn c_requires_lifetime ( & self ) -> bool ;
234
349
}
235
350
236
351
impl RustStructField for NativeStructElement {
237
- fn requires_lifetime_annotation ( & self ) -> bool {
238
- if let Type :: Iterator ( handle ) = & self . element_type {
239
- handle . has_lifetime_annotation
240
- } else {
241
- false
242
- }
352
+ fn rust_requires_lifetime ( & self ) -> bool {
353
+ self . element_type . rust_requires_lifetime ( )
354
+ }
355
+
356
+ fn c_requires_lifetime ( & self ) -> bool {
357
+ self . element_type . c_requires_lifetime ( )
243
358
}
244
359
}
245
360
246
361
pub ( crate ) trait RustCallbackFunction {
247
- fn requires_lifetime_annotation ( & self ) -> bool ;
362
+ fn rust_requires_lifetime ( & self ) -> bool ;
363
+ fn c_requires_lifetime ( & self ) -> bool ;
248
364
}
249
365
250
366
impl RustCallbackFunction for CallbackFunction {
251
- fn requires_lifetime_annotation ( & self ) -> bool {
252
- for param in & self . parameters {
367
+ fn rust_requires_lifetime ( & self ) -> bool {
368
+ self . parameters . iter ( ) . any ( |param| {
253
369
if let CallbackParameter :: Parameter ( param) = param {
254
- if let Type :: Iterator ( handle) = & param. param_type {
255
- if handle. has_lifetime_annotation {
256
- return true
257
- }
370
+ if param. param_type . rust_requires_lifetime ( ) {
371
+ return true ;
258
372
}
259
373
}
260
- }
374
+ false
375
+ } )
376
+ }
261
377
262
- false
378
+ fn c_requires_lifetime ( & self ) -> bool {
379
+ self . parameters . iter ( ) . any ( |param| {
380
+ if let CallbackParameter :: Parameter ( param) = param {
381
+ if param. param_type . c_requires_lifetime ( ) {
382
+ return true ;
383
+ }
384
+ }
385
+ false
386
+ } )
263
387
}
264
388
}
0 commit comments