rusteal_codegen/rust_gen/
param_helpers.rs1use crate::context::CodegenContext;
2use crate::naming::{escape_reserved, to_snake_case};
3use crate::schema::*;
4use crate::type_map::{ConversionKind, MappedType};
5
6use super::classes::is_struct_owned;
7use super::properties;
8
9pub fn emit_out_param_var_decl(out: &mut String, param: &ParamInfo, mapped: &MappedType) {
10 let pname = escape_reserved(&to_snake_case(¶m.name));
11
12 match mapped.ffi_to_rust {
13 ConversionKind::StructOpaque => {
14 out.push_str(&format!(" let mut {pname}_buf = vec![0u8; 256];\n"));
15 }
16 ConversionKind::StringUtf8 => {
17 out.push_str(&format!(" let mut {pname}_buf = vec![0u8; 512];\n"));
18 out.push_str(&format!(" let mut {pname}_len: u32 = 0;\n"));
19 }
20 ConversionKind::ObjectRef => {
21 out.push_str(&format!(
22 " let mut {pname} = rusteal_core::UObjectHandle::null();\n"
23 ));
24 }
25 ConversionKind::EnumCast => {
26 out.push_str(&format!(
27 " let mut {pname}: {} = 0;\n",
28 mapped.rust_ffi_type
29 ));
30 }
31 _ => {
32 let default = properties::default_value_for(&mapped.rust_ffi_type);
33 out.push_str(&format!(" let mut {pname} = {default};\n"));
34 }
35 }
36}
37
38pub fn emit_inout_string_buf_decl(out: &mut String, param: &ParamInfo, mapped: &MappedType) {
39 if mapped.ffi_to_rust == ConversionKind::StringUtf8 {
40 let pname = escape_reserved(&to_snake_case(¶m.name));
41 out.push_str(&format!(" let mut {pname}_buf = vec![0u8; 512];\n"));
42 out.push_str(&format!(" let mut {pname}_len: u32 = 0;\n"));
43 }
44}
45
46pub fn emit_out_param_conversion(
47 out: &mut String,
48 param: &ParamInfo,
49 mapped: &MappedType,
50 ctx: &CodegenContext,
51) -> String {
52 let pname = escape_reserved(&to_snake_case(¶m.name));
53
54 match mapped.ffi_to_rust {
55 ConversionKind::ObjectRef => {
56 format!("unsafe {{ rusteal_core::ObjectPointer::from_object_handle({pname}) }}")
57 }
58 ConversionKind::StringUtf8 => {
59 out.push_str(&format!(
60 " {pname}_buf.truncate({pname}_len as usize);\n"
61 ));
62
63 out.push_str(&format!(
64 " let {pname}_str = String::from_utf8_lossy(&{pname}_buf).into_owned();\n"
65 ));
66
67 format!("{pname}_str")
68 }
69 ConversionKind::EnumCast => {
70 let rt = &mapped.rust_type;
71
72 let actual_repr = param
73 .enum_name
74 .as_deref()
75 .and_then(|en| ctx.enum_actual_repr(en))
76 .unwrap_or(&mapped.rust_ffi_type);
77
78 out.push_str(&format!(
79 " let {pname}_enum = {rt}::from_value({pname} as {actual_repr}).expect(\"unknown enum value\");\n"
80 ));
81
82 format!("{pname}_enum")
83 }
84 ConversionKind::StructOpaque => {
85 if is_struct_owned(param.struct_name.as_deref(), ctx) {
86 out.push_str(&format!(
87 " let {pname}_owned = rusteal_core::OwnedStruct::from_bytes({pname}_buf);\n"
88 ));
89
90 format!("{pname}_owned")
91 } else {
92 out.push_str(&format!(
93 " let {pname}_ptr = {pname}_buf.as_ptr();\n"
94 ));
95
96 out.push_str(&format!(" std::mem::forget({pname}_buf);\n"));
97
98 format!("{pname}_ptr")
99 }
100 }
101 ConversionKind::IntCast => {
102 let rt = &mapped.rust_type;
103
104 format!("{pname} as {rt}")
105 }
106 ConversionKind::FName => pname.to_string(),
107 _ => pname.to_string(),
108 }
109}
110
111pub fn emit_return_expr(out: &mut String, return_parts: &[String]) {
112 match return_parts.len() {
113 0 => {}
114 1 => out.push_str(&format!(" {}\n", return_parts[0])),
115 _ => out.push_str(&format!(" ({})\n", return_parts.join(", "))),
116 }
117}