rusty_bind_parser/cpp/
function_virtual_translator.rs1use crate::binding_types::{Function, RustWrapperType, WrapperType};
19use crate::cpp::templates::TargetLanguageTypeName;
20use crate::EXPORTED_SYMBOLS_PREFIX;
21
22pub struct FunctionVirtualTranslator {
23 pub function_name: String,
24 pub generated_args: String,
25 pub generated_function_body: Vec<String>,
26 pub generated_virtual_function_signature: String,
27 pub return_type: Option<WrapperType>,
28 pub arg_names: Vec<String>,
29 class_name: String,
30}
31
32impl FunctionVirtualTranslator {
33 fn create_list_of_arguments_translated_to_cpp(function: &Function) -> Vec<String> {
34 let mut generated_args = function
35 .arguments
36 .iter()
37 .skip(1)
38 .map(|arg| match &arg.typ {
39 WrapperType {
40 rust_type: RustWrapperType::Primitive | RustWrapperType::FieldlessEnum,
41 ..
42 } => format!("{} {}", arg.typ.wrapper_name, arg.arg_name),
43 _ => format!("void* {}", arg.arg_name),
44 })
45 .collect::<Vec<String>>();
46 generated_args.insert(0, "void* self".to_owned());
47 generated_args
48 }
49
50 fn create_function_signature(function: &Function) -> String {
51 function
52 .arguments
53 .iter()
54 .skip(1)
55 .map(|arg| format!("{} {}", arg.typ.get_name(), arg.arg_name))
56 .collect::<Vec<String>>()
57 .join(", ")
58 }
59
60 fn create_function_body(function: &Function) -> Vec<String> {
61 function
62 .arguments
63 .iter()
64 .skip(1)
65 .map(|arg| {
66 let inner_type_name = arg.typ.get_name();
67 let arg_name = &arg.arg_name;
68 format!("{inner_type_name}({arg_name})")
69 })
70 .collect()
71 }
72
73 pub fn from_virtual_function(function: &Function, class_name: &str) -> Self {
94 let generated_args =
95 FunctionVirtualTranslator::create_list_of_arguments_translated_to_cpp(function);
96 let generated_args = generated_args.join(", ");
97 let generated_virtual_function_signature =
98 FunctionVirtualTranslator::create_function_signature(function);
99 let generated_function_body: Vec<String> =
100 FunctionVirtualTranslator::create_function_body(function);
101 let function_name = function.name.to_string();
102 let arg_names = function
103 .arguments
104 .iter()
105 .map(|arg| arg.arg_name.to_string())
106 .collect();
107 FunctionVirtualTranslator {
108 function_name,
109 generated_args,
110 generated_function_body,
111 generated_virtual_function_signature,
112 return_type: function.return_type.clone(),
113 arg_names,
114 class_name: class_name.to_owned(),
115 }
116 }
117
118 pub fn generate_virtual_declaration(self) -> String {
122 let FunctionVirtualTranslator {
123 function_name,
124 generated_args: _,
125 generated_function_body: _,
126 generated_virtual_function_signature,
127 return_type,
128 ..
129 } = self;
130 let return_type_string = return_type
131 .as_ref()
132 .map(|w| w.get_name_for_abstract_method())
133 .unwrap_or_else(|| "void".to_string());
134 format!(" virtual {return_type_string} {function_name}({generated_virtual_function_signature}) = 0;\n")
135 }
136
137 pub fn generate_virtual_definition(self) -> String {
142 let FunctionVirtualTranslator {
143 function_name,
144 generated_args,
145 generated_function_body,
146 generated_virtual_function_signature: _,
147 return_type,
148 arg_names: _,
149 class_name,
150 } = self;
151 let class_function_name = format!("{class_name}$");
152 let generated_function_body = generated_function_body.join(", ");
153 match return_type {
154 Some(WrapperType {
155 rust_type: RustWrapperType::Primitive | RustWrapperType::FieldlessEnum,
156 wrapper_name,
157 ..
158 }) =>
159 format!(
160 "extern \"C\" {wrapper_name} {EXPORTED_SYMBOLS_PREFIX}${class_function_name}{function_name}({generated_args}) {{
161 return (({class_name}*)self)->{function_name}({generated_function_body});\n}}\n"),
162 None => format!(
163 "extern \"C\" void {EXPORTED_SYMBOLS_PREFIX}${class_function_name}{function_name}({generated_args}) {{
164 (({class_name}*)self)->{function_name}({generated_function_body});\n}}\n"),
165 _ =>
166 format!(
167 "extern \"C\" void* {EXPORTED_SYMBOLS_PREFIX}${class_function_name}{function_name}({generated_args}) {{
168 return ((({class_name}*)self)->{function_name}({generated_function_body}));\n}}\n"),
169 }
170 }
171}