Skip to content

Commit

Permalink
Merge pull request #742 from GuillaumeGomez/nullable-closure-params
Browse files Browse the repository at this point in the history
Handle nullable parameters for callbacks as well
  • Loading branch information
EPashkin committed Mar 13, 2019
2 parents 914ca73 + 017c498 commit 1ae7210
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 12 deletions.
37 changes: 29 additions & 8 deletions src/analysis/rust_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ pub fn rust_type(env: &Env, type_id: library::TypeId) -> Result {
library::Concurrency::None)
}

pub fn rust_type_nullable(env: &Env, type_id: library::TypeId, nullable: Nullable) -> Result {
rust_type_full(env, type_id, nullable, RefMode::None, ParameterScope::None,
library::Concurrency::None)
}

pub fn rust_type_with_scope(
env: &Env,
type_id: library::TypeId,
Expand Down Expand Up @@ -230,12 +235,19 @@ pub fn rust_type_full(
if p.closure.is_some() {
continue
}
match rust_type(env, p.typ) {
match rust_type_nullable(env, p.typ, p.nullable) {
Ok(x) => {
let is_fundamental = p.typ.is_fundamental_type(env);
let y = rust_type(env, p.typ).unwrap_or_else(|_| String::new());
s.push(format!("{}{}",
if is_fundamental { "" } else { "&" },
if x != "GString" { x } else { "&str".to_owned() }));
if y != "GString" {
x
} else if *p.nullable {
"Option<&str>".to_owned()
} else {
"&str".to_owned()
}));
}
e => {
err = true;
Expand All @@ -250,12 +262,21 @@ pub fn rust_type_full(
} else {
"Fn"
};
let mut ret = match rust_type(env, f.ret.typ) {
Ok(x) => format!("{}({}) -> {}{}",
closure_kind,
s.join(", "),
if x != "GString" { &x } else { "String" },
concurrency),
let mut ret = match rust_type_nullable(env, f.ret.typ, f.ret.nullable) {
Ok(x) => {
let y = rust_type(env, f.ret.typ).unwrap_or_else(|_| String::new());
format!("{}({}) -> {}{}",
closure_kind,
s.join(", "),
if y != "GString" {
&x
} else if *f.ret.nullable {
"Option<String>"
} else {
"String"
},
concurrency)
}
Err(TypeError::Unimplemented(ref x)) if x == "()" => {
format!("{}({}){}",
closure_kind,
Expand Down
22 changes: 18 additions & 4 deletions src/codegen/function_body_chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,9 +274,15 @@ impl Builder {
Ok(ref x) => x.clone(),
_ => String::new(),
};
let is_fundamental = add_chunk_for_type(env, par.typ, par, &mut body, &ty_name);
let nullable = trampoline.parameters.rust_parameters[par.ind_rust].nullable;
let is_fundamental = add_chunk_for_type(env, par.typ, par, &mut body, &ty_name,
nullable);
if ty_name == "GString" {
arguments.push(Chunk::Name(format!("{}.as_str()", par.name)));
if *nullable {
arguments.push(Chunk::Name(format!("{}.map(|x| x.as_str())", par.name)));
} else {
arguments.push(Chunk::Name(format!("{}.as_str()", par.name)));
}
continue;
}
arguments.push(Chunk::Name(format!("{}{}",
Expand Down Expand Up @@ -997,6 +1003,7 @@ fn add_chunk_for_type(
par: &trampoline_parameters::Transformation,
body: &mut Vec<Chunk>,
ty_name: &str,
nullable: library::Nullable,
) -> bool {
let type_ = env.type_(typ_);
match *type_ {
Expand All @@ -1006,18 +1013,25 @@ fn add_chunk_for_type(
body.push(Chunk::Custom(format!("let {0} = from_glib({0});", par.name)));
true
}
library::Type::Alias(ref x) => add_chunk_for_type(env, x.typ, par, body, ty_name),
library::Type::Alias(ref x) => add_chunk_for_type(env, x.typ, par, body, ty_name, nullable),
ref x => {
let (begin, end) = ::codegen::trampoline_from_glib::from_glib_xxx(par.transfer, true);
body.push(Chunk::Custom(format!("let {1}{3} = {0}{1}{2};",
begin,
par.name,
end,
if ty_name == "GString" {
": GString"
if *nullable {
": Option<GString>"
} else {
": GString"
}
} else {
""
})));
if ty_name == "GString" && *nullable {
body.push(Chunk::Custom(format!("let {0} = {0}.as_ref();", par.name)));
}
x.is_fundamental()
}
}
Expand Down

0 comments on commit 1ae7210

Please sign in to comment.