Skip to main content

rusteal_codegen/rust_gen/
param_helpers.rs

1use 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(&param.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(&param.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(&param.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}