use super::{
create_enum_class,
enums_cpp_forward_declarations,
externs::create_extern_imports,
function_translator::*,
function_virtual_translator::*,
templates::*,
translate_enums,
};
use crate::binding_types::{ExternFunction, RustWrapperType, WrapperType};
use crate::cpp::wasm_generator::create_wasm_module;
use crate::extern_module_translator::{Exceptions, ExternModuleTranslator};
fn create_classes_declarations(extern_module_translator: &ExternModuleTranslator) -> String {
extern_module_translator
.user_custom_types
.iter()
.map(|(wrapper_type, vec_of_functions)| {
let class_name = wrapper_type.wrapper_name.to_string();
let functions_declaration: String = vec_of_functions
.iter()
.map(|f| FunctionTranslator::from_class_method(f, &class_name))
.map(FunctionTranslator::generate_declaration)
.collect();
custom_class_definition(&class_name, functions_declaration)
})
.collect::<String>()
}
fn create_class_methods_definitions(extern_module_translator: &ExternModuleTranslator) -> String {
extern_module_translator
.user_custom_types
.iter()
.map(|(wrapper_type, vec_of_functions)| {
let class_name = wrapper_type.wrapper_name.to_string();
vec_of_functions
.iter()
.map(|f| FunctionTranslator::from_class_method(f, &class_name))
.map(FunctionTranslator::generate_definition)
.collect::<String>()
})
.collect::<String>()
}
fn create_abstract_classes_declarations(
extern_module_translator: &ExternModuleTranslator,
) -> String {
extern_module_translator
.user_traits
.iter()
.map(|(wrapper_type, vec_of_functions)| {
let class_name = wrapper_type.wrapper_name.to_string();
let functions_declaration: String = vec_of_functions
.iter()
.map(|f| FunctionVirtualTranslator::from_virtual_function(f, &class_name))
.map(FunctionVirtualTranslator::generate_virtual_declaration)
.collect();
abstract_class_declaration(&class_name, &functions_declaration)
})
.collect::<String>()
}
fn create_virtual_method_calls(extern_module_translator: &ExternModuleTranslator) -> String {
extern_module_translator
.user_traits
.iter()
.map(|(wrapper_type, vec_of_functions)| {
let class_name = wrapper_type.wrapper_name.to_string();
vec_of_functions
.iter()
.map(|f| FunctionVirtualTranslator::from_virtual_function(f, &class_name))
.map(FunctionVirtualTranslator::generate_virtual_definition)
.collect::<String>()
})
.collect::<String>()
}
fn create_rust_types_wrappers(extern_module_translator: &ExternModuleTranslator) -> String {
extern_module_translator
.rust_types_wrappers
.ordered_iter()
.filter_map(|wrapper| match wrapper {
WrapperType {
rust_type: RustWrapperType::Vector(inner_type),
..
} => {
let inner_type_name = inner_type.get_name();
let vec_base_impl = vector_impl(&inner_type_name, &inner_type.wrapper_name);
Some(vec_base_impl + &begin_end_impl(&inner_type_name, &inner_type.rust_type))
}
WrapperType {
rust_type: RustWrapperType::Option(inner_type),
..
} => {
let inner_type_name = inner_type.get_name();
Some(option_class(&inner_type_name, &inner_type.wrapper_name))
}
WrapperType {
rust_type: RustWrapperType::Exceptions(Exceptions::NonPrimitive(idents)),
wrapper_name,
..
} => Some(
idents
.iter()
.map(|exception| {
create_non_primitive_exception_class(
&exception.to_string(),
wrapper_name,
extern_module_translator.exception_trait_methods.iter(),
)
})
.collect::<String>(),
),
WrapperType {
rust_type: RustWrapperType::Exceptions(Exceptions::Primitive(idents)),
wrapper_name,
..
} => Some(
idents
.iter()
.map(|exception| {
create_primitive_exception_class(
&exception.to_string(),
wrapper_name,
extern_module_translator.exception_trait_methods.iter(),
)
})
.collect::<String>(),
),
_ => None,
})
.collect()
}
fn create_result_wrappers(extern_module_translator: &ExternModuleTranslator) -> String {
extern_module_translator
.rust_types_wrappers
.ordered_iter()
.filter_map(|wrapper| match wrapper {
WrapperType {
rust_type: RustWrapperType::Result(ok_type, exceptions_type),
..
} => {
let ok_type = ok_type.get_name();
let error_enum_name = &exceptions_type.wrapper_name;
Some(result_class(
&wrapper.wrapper_name,
&ok_type,
error_enum_name,
))
}
_ => None,
})
.collect()
}
fn create_global_functions_definitions(
extern_module_translator: &ExternModuleTranslator,
) -> String {
extern_module_translator
.global_functions
.iter()
.map(FunctionTranslator::from_global_function)
.map(FunctionTranslator::generate_definition)
.collect()
}
pub fn create_classes_forward_declarations(
extern_module_translator: &ExternModuleTranslator,
) -> String {
extern_module_translator
.rust_types_wrappers
.unordered_iter()
.map(|wrapper| match wrapper {
WrapperType {
wrapper_name,
rust_type:
RustWrapperType::Custom
| RustWrapperType::Trait
| RustWrapperType::Result(_, _)
| RustWrapperType::ArcMutex,
..
} => {
format!("struct {wrapper_name};\n")
}
_ => "".to_owned(),
})
.collect()
}
fn create_exception_class_enum(extern_module_translator: &ExternModuleTranslator) -> String {
create_enum_class(
"ExceptionClass",
extern_module_translator
.exception_names
.iter()
.chain(std::iter::once(&RUST_EXCEPTION_BASE_CLASS_NAME.to_string())),
)
}
pub fn generate_cpp_file(
extern_module_translator: &ExternModuleTranslator,
extern_functions: &[ExternFunction],
) -> String {
let externs = create_extern_imports(extern_functions);
let classes_forward_declarations =
create_classes_forward_declarations(extern_module_translator);
let enums_cpp_forward_declarations = enums_cpp_forward_declarations(extern_module_translator);
let enum_classes_definitions = translate_enums(extern_module_translator);
let classes_declaration = create_classes_declarations(extern_module_translator);
let classes_definition = create_class_methods_definitions(extern_module_translator);
let abstract_classes_declaration =
create_abstract_classes_declarations(extern_module_translator);
let virtual_methods_calls = create_virtual_method_calls(extern_module_translator);
let rust_types_wrappers = create_rust_types_wrappers(extern_module_translator);
let result_wrapper = create_result_wrappers(extern_module_translator);
let global_functions_definition: String =
create_global_functions_definitions(extern_module_translator);
let wasm_module = create_wasm_module(extern_module_translator);
let exception_class_enum = create_exception_class_enum(extern_module_translator);
let base_exception_class = base_exception_class(extern_module_translator);
format!(
"{IMPORTS}
{exception_class_enum}
{TYPEDEFS}
{enums_cpp_forward_declarations}
{classes_forward_declarations}
extern \"C\" {{
{externs}
}}
{PREDEFINED}
{base_exception_class}
{abstract_classes_declaration}
{classes_declaration}
{enum_classes_definitions}
{rust_types_wrappers}
{result_wrapper}
{global_functions_definition}
{classes_definition}
{virtual_methods_calls}
{wasm_module}"
)
}