Skip to content

Commit c05663d

Browse files
committed
gen-rust: duration mapping and CStr
1 parent ee1684e commit c05663d

File tree

8 files changed

+245
-95
lines changed

8 files changed

+245
-95
lines changed

generators/rust-oo-bindgen/src/conversion.rs

Lines changed: 165 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1+
use oo_bindgen::callback::*;
12
use oo_bindgen::formatting::*;
23
use oo_bindgen::native_enum::*;
34
use oo_bindgen::native_function::*;
45
use oo_bindgen::native_struct::*;
5-
use oo_bindgen::callback::*;
66

77
pub(crate) trait RustType {
88
fn as_rust_type(&self) -> String;
99
fn as_c_type(&self) -> String;
1010
fn is_copyable(&self) -> bool;
11+
fn rust_requires_lifetime(&self) -> bool;
12+
fn c_requires_lifetime(&self) -> bool;
1113
fn conversion(&self) -> Option<Box<dyn TypeConverter>>;
1214
fn has_conversion(&self) -> bool {
1315
self.conversion().is_some()
@@ -28,13 +30,13 @@ impl RustType for Type {
2830
Type::Sint64 => "i64".to_string(),
2931
Type::Float => "f32".to_string(),
3032
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(),
3335
Type::StructRef(handle) => format!("Option<&{}>", handle.name),
34-
Type::Enum(handle) => format!("{}", handle.name),
36+
Type::Enum(handle) => handle.name.to_string(),
3537
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(),
3840
Type::Iterator(handle) => {
3941
let lifetime = if handle.has_lifetime_annotation {
4042
"<'a>"
@@ -44,10 +46,7 @@ impl RustType for Type {
4446
format!("*mut crate::{}{}", handle.name(), lifetime)
4547
}
4648
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(),
5150
}
5251
}
5352

@@ -100,7 +99,7 @@ impl RustType for Type {
10099
Type::Sint64 => true,
101100
Type::Float => true,
102101
Type::Double => true,
103-
Type::String => true, // Just copying the pointer
102+
Type::String => true, // Just copying the reference
104103
Type::Struct(_) => false,
105104
Type::StructRef(_) => true,
106105
Type::Enum(_) => true,
@@ -113,6 +112,58 @@ impl RustType for Type {
113112
}
114113
}
115114

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+
116167
fn conversion(&self) -> Option<Box<dyn TypeConverter>> {
117168
match self {
118169
Type::Bool => None,
@@ -126,7 +177,7 @@ impl RustType for Type {
126177
Type::Sint64 => None,
127178
Type::Float => None,
128179
Type::Double => None,
129-
Type::String => None,
180+
Type::String => Some(Box::new(StringConverter)),
130181
Type::Struct(_) => None,
131182
Type::StructRef(handle) => Some(Box::new(StructRefConverter(handle.clone()))),
132183
Type::Enum(handle) => Some(Box::new(EnumConverter(handle.clone()))),
@@ -135,7 +186,7 @@ impl RustType for Type {
135186
Type::OneTimeCallback(_) => None,
136187
Type::Iterator(_) => None,
137188
Type::Collection(_) => None,
138-
Type::Duration(_) => None,
189+
Type::Duration(mapping) => Some(Box::new(DurationConverter(*mapping))),
139190
}
140191
}
141192
}
@@ -165,6 +216,22 @@ impl RustType for ReturnType {
165216
}
166217
}
167218

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+
168235
fn conversion(&self) -> Option<Box<dyn TypeConverter>> {
169236
if let ReturnType::Type(return_type, _) = self {
170237
return_type.conversion()
@@ -177,6 +244,25 @@ impl RustType for ReturnType {
177244
pub(crate) trait TypeConverter {
178245
fn convert_to_c(&self, f: &mut dyn Printer, from: &str, to: &str) -> FormattingResult<()>;
179246
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+
}
180266
}
181267

182268
struct EnumConverter(NativeEnumHandle);
@@ -206,59 +292,97 @@ impl TypeConverter for StructRefConverter {
206292
}
207293
}
208294

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+
209324
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;
211327
fn has_conversion(&self) -> bool;
212328
}
213329

214330
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())
219333
}
220334

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+
}
227338

228-
false
339+
fn has_conversion(&self) -> bool {
340+
self.elements
341+
.iter()
342+
.any(|e| e.element_type.has_conversion())
229343
}
230344
}
231345

232346
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;
234349
}
235350

236351
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()
243358
}
244359
}
245360

246361
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;
248364
}
249365

250366
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| {
253369
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;
258372
}
259373
}
260-
}
374+
false
375+
})
376+
}
261377

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+
})
263387
}
264388
}

0 commit comments

Comments
 (0)