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