Skip to content

Commit

Permalink
analysis: use collection types for return when possible
Browse files Browse the repository at this point in the history
  • Loading branch information
jf2048 committed May 5, 2023
1 parent 10dc6c2 commit bf1f19a
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/analysis/return_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ pub fn analyze(
let par = analysis::Parameter::from_return_value(env, lib_par, configured_functions);
if let Ok(rust_type) = RustType::builder(env, typ)
.direction(par.lib_par.direction)
.c_type(par.lib_par.c_type.clone())
.try_from_glib(&par.try_from_glib)
.try_build()
{
Expand All @@ -130,6 +131,7 @@ pub fn analyze(

commented = RustType::builder(env, typ)
.direction(func.ret.direction)
.c_type(par.lib_par.c_type.clone())
.try_from_glib(&par.try_from_glib)
.try_build_param()
.is_err();
Expand Down
65 changes: 63 additions & 2 deletions src/analysis/rust_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ pub struct RustTypeBuilder<'env> {
concurrency: library::Concurrency,
try_from_glib: TryFromGlib,
callback_parameters_config: CallbackParameters,
c_type: String,
}

impl<'env> RustTypeBuilder<'env> {
Expand All @@ -205,6 +206,7 @@ impl<'env> RustTypeBuilder<'env> {
concurrency: library::Concurrency::None,
try_from_glib: TryFromGlib::default(),
callback_parameters_config: Vec::new(),
c_type: String::default(),
}
}

Expand Down Expand Up @@ -238,6 +240,11 @@ impl<'env> RustTypeBuilder<'env> {
self
}

pub fn c_type(mut self, c_type: String) -> Self {
self.c_type = c_type;
self
}

pub fn callback_parameters_config(
mut self,
callback_parameters_config: &[CallbackParameter],
Expand Down Expand Up @@ -348,7 +355,8 @@ impl<'env> RustTypeBuilder<'env> {
if ConversionType::of(self.env, inner_tid) == ConversionType::Pointer =>
{
skip_option = true;
let inner_ref_mode = match self.env.type_(inner_tid) {
let inner_type = self.env.type_(inner_tid);
let inner_ref_mode = match inner_type {
Class(..) | Interface(..) => RefMode::None,
Record(record) => match RecordType::of(record) {
RecordType::Boxed => RefMode::None,
Expand All @@ -373,7 +381,59 @@ impl<'env> RustTypeBuilder<'env> {
if self.ref_mode.is_ref() {
format!("[{typ}]")
} else {
format!("Vec<{typ}>")
let is_obj = matches!(inner_type, Class(_) | Interface(_));
let is_ptr = is_obj
|| matches!(inner_type, Basic(Pointer))
|| (matches!(inner_type, Record(_))
&& self
.env
.config
.objects
.get(&inner_tid.full_name(&self.env.library))
.map(|o| !o.boxed_inline)
.unwrap_or(false));
let is_string = matches!(inner_type, Basic(Utf8));
match *type_ {
CArray(_) if is_ptr => {
format!("{}<{typ}>", use_glib_type(self.env, "PtrSlice"))
}
CArray(_)
if is_string
&& matches!(
self.c_type.as_str(),
"char**" | "gchar**"
) =>
{
use_glib_type(self.env, "StrV")
}
CArray(_)
if !matches!(
inner_type,
Basic(Utf8 | Filename | OsString | Boolean)
) =>
{
format!("{}<{typ}>", use_glib_type(self.env, "Slice"))
}
List(_) if is_ptr => {
format!("{}<{typ}>", use_glib_type(self.env, "List"))
}
List(_) if is_string => format!(
"{}<{}>",
use_glib_type(self.env, "List"),
use_glib_type(self.env, "GStringPtr")
),
SList(_) if is_ptr => {
format!("{}<{typ}>", use_glib_type(self.env, "SList"))
}
SList(_) if is_string => format!(
"{}<{}>",
use_glib_type(self.env, "SList"),
use_glib_type(self.env, "GStringPtr")
),
/* TODO: Handle Array and PtrArray when they gain type
* parameters */
_ => format!("Vec<{typ}>"),
}
}
})
})
Expand Down Expand Up @@ -623,6 +683,7 @@ impl<'env> RustTypeBuilder<'env> {
.direction(self.direction)
.nullable(self.nullable)
.ref_mode(self.ref_mode)
.c_type(self.c_type)
.scope(self.scope)
.try_from_glib(&self.try_from_glib)
.try_build();
Expand Down
1 change: 1 addition & 0 deletions src/codegen/parameter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ impl ToParameter for CParameter {
let type_name = RustType::builder(env, self.typ)
.direction(self.direction)
.nullable(self.nullable)
.c_type(self.c_type.clone())
.ref_mode(ref_mode)
.scope(self.scope)
.try_from_glib(&self.try_from_glib)
Expand Down
2 changes: 2 additions & 0 deletions src/codegen/return_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ impl ToReturnValue for library::Parameter {
.direction(self.direction)
.nullable(self.nullable)
.scope(self.scope)
.c_type(self.c_type.clone())
.try_from_glib(try_from_glib)
.try_build_param()
.into_string();
Expand Down Expand Up @@ -261,6 +262,7 @@ fn out_parameter_as_return(out: &analysis::Parameter, env: &Env) -> String {
let name = RustType::builder(env, out.lib_par.typ)
.direction(ParameterDirection::Return)
.nullable(out.lib_par.nullable)
.c_type(out.lib_par.c_type.clone())
.scope(out.lib_par.scope)
.try_from_glib(&out.try_from_glib)
.try_build_param()
Expand Down
1 change: 1 addition & 0 deletions src/codegen/translate_from_glib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ impl TranslateFromGlib for analysis::return_value::Info {
Some(tid) => {
let rust_type = RustType::builder(env, tid)
.direction(par.lib_par.direction)
.c_type(par.lib_par.c_type.clone())
.try_from_glib(&par.try_from_glib)
.try_build();
let from_glib_xxx = from_glib_xxx(par.lib_par.transfer, None);
Expand Down

0 comments on commit bf1f19a

Please sign in to comment.