use super::*;
#[derive(Debug)]
pub(crate) struct GeneratedApiMethod {
pub signature: String,
pub implementation: String,
}
pub(crate) fn generate_api_func(
func: &IrFunc,
ir_file: &IrFile,
common_api2wire_body: &str,
) -> GeneratedApiFunc {
let raw_func_param_list = func
.inputs
.iter()
.map(|input| {
format!(
"{}{} {}",
input.ty.dart_required_modifier(),
input.ty.dart_api_type(),
input.name.dart_style()
)
})
.collect::<Vec<_>>();
let full_func_param_list = [raw_func_param_list, vec!["dynamic hint".to_owned()]].concat();
let prepare_args = func
.inputs
.iter()
.enumerate()
.map(|(index, input)| {
if let Primitive(IrTypePrimitive::Bool) = input.ty {
format!("var arg{index} = {};", input.name.dart_style())
} else {
let func = format!("api2wire_{}", input.ty.safe_ident());
format!(
"var arg{index} = {}{}({});",
if common_api2wire_body.contains(&func) {
""
} else {
"_platform."
},
func,
&input.name.dart_style()
)
}
})
.collect::<Vec<_>>();
let wire_param_list = [
if func.mode.has_port_argument() {
vec!["port_".to_owned()]
} else {
vec![]
},
(0..prepare_args.len())
.map(|index| format!("arg{index}"))
.collect_vec(),
]
.concat();
let func_expr = format!(
"{} {}({{ {} }})",
func.mode.dart_return_type(&func.output.dart_api_type()),
func.name.to_case(Case::Camel),
full_func_param_list.join(","),
);
let execute_func_name = match func.mode {
IrFuncMode::Normal => "_platform.executeNormal",
IrFuncMode::Sync => "_platform.executeSync",
IrFuncMode::Stream { .. } => "_platform.executeStream",
};
let const_meta_field_name = format!("k{}ConstMeta", func.name.to_case(Case::Pascal));
let signature = format!("{};", func_expr);
let comments = dart_comments(&func.comments);
let task_common_args = format!(
"
constMeta: {},
argValues: [{}],
hint: hint,
",
const_meta_field_name,
func.inputs
.iter()
.map(|input| input.name.dart_style())
.collect::<Vec<_>>()
.join(", "),
);
let input_0 = func.inputs.get(0).as_ref().map(|x| &x.ty);
let input_0_struct_name = if let Some(StructRef(IrTypeStructRef { name, .. })) = &input_0 {
Some(name)
} else {
None
};
let f = FunctionName::deserialize(&func.name);
let func_output_struct_name = if let StructRef(IrTypeStructRef { name, .. }) = &func.output {
Some(name)
} else {
None
};
let parse_success_data = if (f.is_static_method()
&& f.struct_name().unwrap() == {
if let IrType::StructRef(IrTypeStructRef { name, freezed: _ }) = &func.output {
name.clone()
} else {
String::new()
}
})
|| (input_0_struct_name.is_some() && MethodNamingUtil::has_methods(input_0_struct_name.unwrap(), ir_file))
|| (func_output_struct_name.is_some()
&& MethodNamingUtil::has_methods(func_output_struct_name.unwrap(), ir_file))
{
format!("(d) => _wire2api_{}(d)", func.output.safe_ident())
} else {
format!("_wire2api_{}", func.output.safe_ident())
};
let is_sync = matches!(func.mode, IrFuncMode::Sync);
let implementation = format!(
"{} {{
{}
return {}({task}(
callFfi: ({args}) => _platform.inner.{}({}),
parseSuccessData: {},
{}
));}}",
func_expr,
prepare_args.join("\n"),
execute_func_name,
func.wire_func_name(),
wire_param_list.join(", "),
parse_success_data,
task_common_args,
task = if is_sync {
"FlutterRustBridgeSyncTask"
} else {
"FlutterRustBridgeTask"
},
args = if is_sync { "" } else { "port_" },
);
let companion_field_signature = format!(
"FlutterRustBridgeTaskConstMeta get {};",
const_meta_field_name,
);
let companion_field_implementation = format!(
"
FlutterRustBridgeTaskConstMeta get {} => const FlutterRustBridgeTaskConstMeta(
debugName: \"{}\",
argNames: [{}],
);
",
const_meta_field_name,
func.name,
func.inputs
.iter()
.map(|input| format!("\"{}\"", input.name.dart_style()))
.collect::<Vec<_>>()
.join(", "),
);
GeneratedApiFunc {
signature,
implementation,
comments,
companion_field_signature,
companion_field_implementation,
}
}
pub(crate) fn generate_opaque_getters(ty: &IrType) -> GeneratedApiFunc {
let signature = format!(
"
DropFnType get dropOpaque{0};
ShareFnType get shareOpaque{0};
OpaqueTypeFinalizer get {0}Finalizer;
",
ty.dart_api_type(),
);
let implementation = format!(
"
DropFnType get dropOpaque{0} => _platform.inner.drop_opaque_{0};
ShareFnType get shareOpaque{0} => _platform.inner.share_opaque_{0};
OpaqueTypeFinalizer get {0}Finalizer => _platform.{0}Finalizer;
",
ty.dart_api_type()
);
GeneratedApiFunc {
signature,
implementation,
comments: String::new(),
companion_field_signature: String::new(),
companion_field_implementation: String::new(),
}
}