uika_codegen/rust_gen/
structs.rs1use crate::context::CodegenContext;
4use crate::schema::StructInfo;
5
6use super::properties::{self, PropertyContext};
7
8pub fn generate_struct(s: &StructInfo, ctx: &CodegenContext) -> String {
10 let mut out = String::with_capacity(2048);
11 let name = &s.cpp_name; let stripped = &s.name; out.push_str("use super::*;\n");
16 out.push_str("use uika_runtime::{UeClass, UeStruct, UeEnum};\n");
17 let current_module = ctx
18 .package_to_module
19 .get(&s.package)
20 .map(|s| s.as_str())
21 .unwrap_or("");
22 for module in &ctx.enabled_modules {
23 if module != current_module {
24 if let Some(feature) = ctx.feature_for_module(module) {
25 out.push_str(&format!("#[cfg(feature = \"{feature}\")]\n"));
26 }
27 out.push_str(&format!("use crate::{module}::*;\n"));
28 }
29 }
30 out.push('\n');
31
32 out.push_str(&format!(
33 "/// Opaque UE struct `{name}`. Layout managed by C++ side.\n\
34 pub struct {name};\n\n"
35 ));
36
37 if s.has_static_struct {
38 let name_bytes = stripped.as_bytes();
39 let name_len = name_bytes.len();
40 let byte_lit = format!("b\"{}\\0\"", stripped);
41
42 out.push_str(&format!(
43 "impl uika_runtime::UeStruct for {name} {{\n\
44 \x20 fn static_struct() -> uika_runtime::UStructHandle {{\n\
45 \x20 static CACHE: std::sync::OnceLock<uika_runtime::UStructHandle> = std::sync::OnceLock::new();\n\
46 \x20 *CACHE.get_or_init(|| unsafe {{\n\
47 \x20 ((*uika_runtime::api().reflection).find_struct)({byte_lit}.as_ptr(), {name_len})\n\
48 \x20 }})\n\
49 \x20 }}\n\
50 }}\n\n"
51 ));
52
53 let (_, deduped_props) = properties::collect_deduped_properties(&s.props, Some(ctx));
55 if !deduped_props.is_empty() {
56 let pctx = PropertyContext {
57 find_prop_fn: "find_struct_property".to_string(),
58 handle_expr: format!("{name}::static_struct()"),
59 pre_access: String::new(), container_expr: "self.as_ptr()".to_string(),
61 is_class: false,
62 };
63
64 let trait_name = format!("{name}Ext");
65
66 let no_suppress = std::collections::HashSet::new();
68 let mut body_buf = String::new();
69 for prop in &deduped_props {
70 properties::generate_property(&mut body_buf, prop, &pctx, ctx, &no_suppress);
71 }
72
73 out.push_str(&format!("pub trait {trait_name} {{\n"));
75 for line in body_buf.lines() {
76 if line.starts_with(" fn ") && line.ends_with(" {") {
77 out.push_str(&line[..line.len() - 2]);
78 out.push_str(";\n");
79 }
80 }
81 out.push_str("}\n\n");
82
83 out.push_str(&format!(
85 "impl {trait_name} for uika_runtime::UStructRef<{name}> {{\n"
86 ));
87 out.push_str(&body_buf);
88 out.push_str("}\n");
89 }
90 }
91
92 out
93}