Skip to content

Commit

Permalink
Don't skip Option for nullable collections
Browse files Browse the repository at this point in the history
Nullable collection were represented as a `Vec<_>` or `[_]`, but an empty
collection is not the same as an undefined collection.

Fixes: gtk-rs#1133
See also: gtk-rs/gtk-rs-core#1257
  • Loading branch information
fengalin committed Dec 7, 2024
1 parent b665888 commit 09633ed
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 7 deletions.
13 changes: 11 additions & 2 deletions src/analysis/function_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ pub enum TransformationType {
array_name: String,
array_length_name: String,
array_length_type: String,
nullable: bool,
},
IntoRaw(String),
ToSome(String),
Expand Down Expand Up @@ -176,7 +177,7 @@ impl Parameters {
let transformation = Transformation {
ind_c,
ind_rust: None,
transformation_type: get_length_type(env, "", &c_par.name, c_par.typ),
transformation_type: get_length_type(env, "", &c_par.name, c_par.typ, c_par.nullable),
};
self.transformations.push(transformation);
}
Expand Down Expand Up @@ -301,7 +302,13 @@ pub fn analyze(
let transformation = Transformation {
ind_c,
ind_rust: None,
transformation_type: get_length_type(env, &array_name, &par.name, typ),
transformation_type: get_length_type(
env,
&array_name,
&par.name,
typ,
array_par.nullable,
),
};
parameters.transformations.push(transformation);
}
Expand Down Expand Up @@ -448,12 +455,14 @@ fn get_length_type(
array_name: &str,
length_name: &str,
length_typ: TypeId,
nullable_array: Nullable,
) -> TransformationType {
let array_length_type = RustType::try_new(env, length_typ).into_string();
TransformationType::Length {
array_name: array_name.to_string(),
array_length_name: length_name.to_string(),
array_length_type,
nullable: *nullable_array,
}
}

Expand Down
5 changes: 1 addition & 4 deletions src/analysis/rust_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,6 @@ impl<'env> RustTypeBuilder<'env> {
let ok = |s: &str| Ok(RustType::from(s));
let ok_and_use = |s: &str| Ok(RustType::new_and_use(&s));
let err = |s: &str| Err(TypeError::Unimplemented(s.into()));
let mut skip_option = false;
let type_ = self.env.library.type_(self.type_id);
let mut rust_type = match *type_ {
Basic(fund) => {
Expand Down Expand Up @@ -355,7 +354,6 @@ impl<'env> RustTypeBuilder<'env> {
List(inner_tid) | SList(inner_tid) | CArray(inner_tid) | PtrArray(inner_tid)
if ConversionType::of(self.env, inner_tid) == ConversionType::Pointer =>
{
skip_option = true;
let inner_ref_mode = match self.env.type_(inner_tid) {
Class(..) | Interface(..) => RefMode::None,
Record(record) => match RecordType::of(record) {
Expand Down Expand Up @@ -409,7 +407,6 @@ impl<'env> RustTypeBuilder<'env> {
};

if let Some(s) = array_type {
skip_option = true;
if self.ref_mode.is_ref() {
Ok(format!("[{s}]").into())
} else {
Expand Down Expand Up @@ -604,7 +601,7 @@ impl<'env> RustTypeBuilder<'env> {
}
}

if *self.nullable && !skip_option {
if *self.nullable {
match ConversionType::of(self.env, self.type_id) {
ConversionType::Pointer | ConversionType::Scalar => {
rust_type = rust_type.map_any(|rust_type| {
Expand Down
7 changes: 6 additions & 1 deletion src/codegen/function_body_chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -956,11 +956,16 @@ impl Builder {
if let TransformationType::Length {
ref array_name,
ref array_length_name,
nullable,
..
} = trans.transformation_type
{
if let In = self.parameters[trans.ind_c] {
let value = Chunk::Custom(format!("{array_name}.len() as _"));
let value = Chunk::Custom(if nullable {
format!("{array_name}.as_ref().map(|a| a.len()).unwrap_or(0)")
} else {
format!("{array_name}.len() as _")
});
chunks.push(Chunk::Let {
name: array_length_name.clone(),
is_mut: false,
Expand Down

0 comments on commit 09633ed

Please sign in to comment.