Skip to content

Commit c7a9f70

Browse files
committed
analysis: use collection types for return when possible
1 parent 0334ced commit c7a9f70

File tree

5 files changed

+67
-2
lines changed

5 files changed

+67
-2
lines changed

src/analysis/return_value.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ pub fn analyze(
122122
let par = analysis::Parameter::from_return_value(env, lib_par, configured_functions);
123123
if let Ok(rust_type) = RustType::builder(env, typ)
124124
.direction(par.lib_par.direction)
125+
.c_type(par.lib_par.c_type.clone())
125126
.try_from_glib(&par.try_from_glib)
126127
.try_build()
127128
{
@@ -130,6 +131,7 @@ pub fn analyze(
130131

131132
commented = RustType::builder(env, typ)
132133
.direction(func.ret.direction)
134+
.c_type(par.lib_par.c_type.clone())
133135
.try_from_glib(&par.try_from_glib)
134136
.try_build_param()
135137
.is_err();

src/analysis/rust_type.rs

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ pub struct RustTypeBuilder<'env> {
191191
concurrency: library::Concurrency,
192192
try_from_glib: TryFromGlib,
193193
callback_parameters_config: CallbackParameters,
194+
c_type: String,
194195
}
195196

196197
impl<'env> RustTypeBuilder<'env> {
@@ -205,6 +206,7 @@ impl<'env> RustTypeBuilder<'env> {
205206
concurrency: library::Concurrency::None,
206207
try_from_glib: TryFromGlib::default(),
207208
callback_parameters_config: Vec::new(),
209+
c_type: String::default(),
208210
}
209211
}
210212

@@ -238,6 +240,11 @@ impl<'env> RustTypeBuilder<'env> {
238240
self
239241
}
240242

243+
pub fn c_type(mut self, c_type: String) -> Self {
244+
self.c_type = c_type;
245+
self
246+
}
247+
241248
pub fn callback_parameters_config(
242249
mut self,
243250
callback_parameters_config: &[CallbackParameter],
@@ -348,7 +355,8 @@ impl<'env> RustTypeBuilder<'env> {
348355
if ConversionType::of(self.env, inner_tid) == ConversionType::Pointer =>
349356
{
350357
skip_option = true;
351-
let inner_ref_mode = match self.env.type_(inner_tid) {
358+
let inner_type = self.env.type_(inner_tid);
359+
let inner_ref_mode = match inner_type {
352360
Class(..) | Interface(..) => RefMode::None,
353361
Record(record) => match RecordType::of(record) {
354362
RecordType::Boxed => RefMode::None,
@@ -373,7 +381,57 @@ impl<'env> RustTypeBuilder<'env> {
373381
if self.ref_mode.is_ref() {
374382
format!("[{typ}]")
375383
} else {
376-
format!("Vec<{typ}>")
384+
let is_obj = matches!(inner_type, Class(_) | Interface(_));
385+
let is_ptr = is_obj
386+
|| matches!(inner_type, Basic(Pointer))
387+
|| (matches!(inner_type, Record(_))
388+
&& self
389+
.env
390+
.config
391+
.objects
392+
.get(&inner_tid.full_name(&self.env.library))
393+
.map(|o| !o.boxed_inline)
394+
.unwrap_or(false));
395+
let is_string = matches!(inner_type, Basic(Utf8));
396+
match *type_ {
397+
CArray(_) if is_ptr => {
398+
format!("{}<{typ}>", use_glib_type(self.env, "PtrSlice"))
399+
}
400+
CArray(_)
401+
if is_string
402+
&& matches!(
403+
self.c_type.as_str(),
404+
"char**" | "gchar**"
405+
) =>
406+
{
407+
use_glib_type(self.env, "StrV")
408+
}
409+
CArray(_)
410+
if !matches!(
411+
inner_type,
412+
Basic(Utf8 | Filename | OsString | Boolean)
413+
) =>
414+
{
415+
format!("{}<{typ}>", use_glib_type(self.env, "Slice"))
416+
}
417+
List(_) if is_ptr => {
418+
format!("{}<{typ}>", use_glib_type(self.env, "List"))
419+
}
420+
List(_) if is_string => format!(
421+
"{}<{}>",
422+
use_glib_type(self.env, "List"),
423+
use_glib_type(self.env, "GStringPtr")
424+
),
425+
SList(_) if is_ptr => {
426+
format!("{}<{typ}>", use_glib_type(self.env, "SList"))
427+
}
428+
SList(_) if is_string => format!(
429+
"{}<{}>",
430+
use_glib_type(self.env, "SList"),
431+
use_glib_type(self.env, "GStringPtr")
432+
),
433+
_ => format!("Vec<{typ}>"),
434+
}
377435
}
378436
})
379437
})
@@ -623,6 +681,7 @@ impl<'env> RustTypeBuilder<'env> {
623681
.direction(self.direction)
624682
.nullable(self.nullable)
625683
.ref_mode(self.ref_mode)
684+
.c_type(self.c_type)
626685
.scope(self.scope)
627686
.try_from_glib(&self.try_from_glib)
628687
.try_build();

src/codegen/parameter.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ impl ToParameter for CParameter {
2929
let type_name = RustType::builder(env, self.typ)
3030
.direction(self.direction)
3131
.nullable(self.nullable)
32+
.c_type(self.c_type.clone())
3233
.ref_mode(ref_mode)
3334
.scope(self.scope)
3435
.try_from_glib(&self.try_from_glib)

src/codegen/return_value.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ impl ToReturnValue for library::Parameter {
3131
.direction(self.direction)
3232
.nullable(self.nullable)
3333
.scope(self.scope)
34+
.c_type(self.c_type.clone())
3435
.try_from_glib(try_from_glib)
3536
.try_build_param()
3637
.into_string();
@@ -261,6 +262,7 @@ fn out_parameter_as_return(out: &analysis::Parameter, env: &Env) -> String {
261262
let name = RustType::builder(env, out.lib_par.typ)
262263
.direction(ParameterDirection::Return)
263264
.nullable(out.lib_par.nullable)
265+
.c_type(out.lib_par.c_type.clone())
264266
.scope(out.lib_par.scope)
265267
.try_from_glib(&out.try_from_glib)
266268
.try_build_param()

src/codegen/translate_from_glib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ impl TranslateFromGlib for analysis::return_value::Info {
8888
Some(tid) => {
8989
let rust_type = RustType::builder(env, tid)
9090
.direction(par.lib_par.direction)
91+
.c_type(par.lib_par.c_type.clone())
9192
.try_from_glib(&par.try_from_glib)
9293
.try_build();
9394
let from_glib_xxx = from_glib_xxx(par.lib_par.transfer, None);

0 commit comments

Comments
 (0)