use crate::binding_types::{Function, RustWrapperType, WrapperType};
use crate::cpp::templates::TargetLanguageTypeName;
use crate::EXPORTED_SYMBOLS_PREFIX;
pub struct FunctionVirtualTranslator {
pub function_name: String,
pub generated_args: String,
pub generated_function_body: Vec<String>,
pub generated_virtual_function_signature: String,
pub return_type: Option<WrapperType>,
pub arg_names: Vec<String>,
class_name: String,
}
impl FunctionVirtualTranslator {
fn create_list_of_arguments_translated_to_cpp(function: &Function) -> Vec<String> {
let mut generated_args = function
.arguments
.iter()
.skip(1)
.map(|arg| match &arg.typ {
WrapperType {
rust_type: RustWrapperType::Primitive | RustWrapperType::FieldlessEnum,
..
} => format!("{} {}", arg.typ.wrapper_name, arg.arg_name),
_ => format!("void* {}", arg.arg_name),
})
.collect::<Vec<String>>();
generated_args.insert(0, "void* self".to_owned());
generated_args
}
fn create_function_signature(function: &Function) -> String {
function
.arguments
.iter()
.skip(1)
.map(|arg| format!("{} {}", arg.typ.get_name(), arg.arg_name))
.collect::<Vec<String>>()
.join(", ")
}
fn create_function_body(function: &Function) -> Vec<String> {
function
.arguments
.iter()
.skip(1)
.map(|arg| {
let inner_type_name = arg.typ.get_name();
let arg_name = &arg.arg_name;
format!("{inner_type_name}({arg_name})")
})
.collect()
}
pub fn from_virtual_function(function: &Function, class_name: &str) -> Self {
let generated_args =
FunctionVirtualTranslator::create_list_of_arguments_translated_to_cpp(function);
let generated_args = generated_args.join(", ");
let generated_virtual_function_signature =
FunctionVirtualTranslator::create_function_signature(function);
let generated_function_body: Vec<String> =
FunctionVirtualTranslator::create_function_body(function);
let function_name = function.name.to_string();
let arg_names = function
.arguments
.iter()
.map(|arg| arg.arg_name.to_string())
.collect();
FunctionVirtualTranslator {
function_name,
generated_args,
generated_function_body,
generated_virtual_function_signature,
return_type: function.return_type.clone(),
arg_names,
class_name: class_name.to_owned(),
}
}
pub fn generate_virtual_declaration(self) -> String {
let FunctionVirtualTranslator {
function_name,
generated_args: _,
generated_function_body: _,
generated_virtual_function_signature,
return_type,
..
} = self;
let return_type_string = return_type
.as_ref()
.map(|w| w.get_name_for_abstract_method())
.unwrap_or_else(|| "void".to_string());
format!(" virtual {return_type_string} {function_name}({generated_virtual_function_signature}) = 0;\n")
}
pub fn generate_virtual_definition(self) -> String {
let FunctionVirtualTranslator {
function_name,
generated_args,
generated_function_body,
generated_virtual_function_signature: _,
return_type,
arg_names: _,
class_name,
} = self;
let class_function_name = format!("{class_name}$");
let generated_function_body = generated_function_body.join(", ");
match return_type {
Some(WrapperType {
rust_type: RustWrapperType::Primitive | RustWrapperType::FieldlessEnum,
wrapper_name,
..
}) =>
format!(
"extern \"C\" {wrapper_name} {EXPORTED_SYMBOLS_PREFIX}${class_function_name}{function_name}({generated_args}) {{
return (({class_name}*)self)->{function_name}({generated_function_body});\n}}\n"),
None => format!(
"extern \"C\" void {EXPORTED_SYMBOLS_PREFIX}${class_function_name}{function_name}({generated_args}) {{
(({class_name}*)self)->{function_name}({generated_function_body});\n}}\n"),
_ =>
format!(
"extern \"C\" void* {EXPORTED_SYMBOLS_PREFIX}${class_function_name}{function_name}({generated_args}) {{
return ((({class_name}*)self)->{function_name}({generated_function_body}));\n}}\n"),
}
}
}