rusteal_codegen/
defaults.rs1use crate::context::CodegenContext;
2use crate::schema::ParamInfo;
3use crate::type_map::{ConversionKind, MappedType};
4
5pub fn parse_default_literal(
6 param: &ParamInfo,
7 mapped: &MappedType,
8 ctx: &CodegenContext,
9) -> Option<String> {
10 let default_str = param.default.as_deref()?;
11
12 if mapped.rust_to_ffi == ConversionKind::StructOpaque {
13 return None;
14 }
15
16 match param.prop_type.as_str() {
17 "BoolProperty" => parse_bool_default(default_str),
18 "FloatProperty" => parse_float_default(default_str, "f32"),
19 "DoubleProperty" => parse_float_default(default_str, "f64"),
20 "IntProperty" => parse_int_default(default_str, "i32"),
21 "Int8Property" => parse_int_default(default_str, "i8"),
22 "Int16Property" => parse_int_default(default_str, "i16"),
23 "Int64Property" => parse_int_default(default_str, "i64"),
24 "ByteProperty" => {
25 if param.enum_name.is_some() {
26 parse_enum_default(default_str, param, ctx)
27 } else {
28 parse_int_default(default_str, "u8")
29 }
30 }
31 "UInt16Property" => parse_int_default(default_str, "u16"),
32 "UInt32Property" => parse_int_default(default_str, "u32"),
33 "UInt64Property" => parse_int_default(default_str, "u64"),
34 "EnumProperty" => parse_enum_default(default_str, param, ctx),
35 "ObjectProperty" | "ClassProperty" | "SoftObjectProperty" | "WeakObjectProperty"
36 | "InterfaceProperty" => parse_object_default(default_str, mapped),
37 "StrProperty" | "TextProperty" => parse_string_default(default_str),
38 "NameProperty" => parse_fname_default(default_str),
39 _ => None,
40 }
41}
42
43fn parse_bool_default(s: &str) -> Option<String> {
44 match s {
45 "true" | "True" => Some("true".into()),
46 "false" | "False" => Some("false".into()),
47 _ => None,
48 }
49}
50
51fn parse_float_default(s: &str, suffix: &str) -> Option<String> {
52 let _: f64 = s.parse().ok()?;
53
54 if s.contains('.') {
55 Some(format!("{s}{suffix}"))
56 } else {
57 Some(format!("{s}.0{suffix}"))
58 }
59}
60
61fn parse_int_default(s: &str, suffix: &str) -> Option<String> {
62 let _: i128 = s.parse().ok()?;
63 Some(format!("{s}{suffix}"))
64}
65
66fn parse_object_default(s: &str, mapped: &MappedType) -> Option<String> {
67 if s == "None" {
68 if mapped.rust_to_ffi == ConversionKind::ObjectRef {
69 Some("unsafe { rusteal_core::ObjectPointer::from_object_handle(rusteal_core::UObjectHandle::null()) }".into())
70 } else {
71 Some("rusteal_core::UObjectHandle::null()".into())
72 }
73 } else {
74 None
75 }
76}
77
78fn parse_string_default(s: &str) -> Option<String> {
79 let escaped = s.replace('\\', "\\\\").replace('"', "\\\"");
80 Some(format!("\"{escaped}\""))
81}
82
83fn parse_fname_default(s: &str) -> Option<String> {
84 if s.is_empty() || s == "None" {
85 Some("rusteal_core::FNameHandle(0)".into())
86 } else {
87 None
88 }
89}
90
91fn parse_enum_default(s: &str, param: &ParamInfo, ctx: &CodegenContext) -> Option<String> {
92 let enum_name = param.enum_name.as_deref()?;
93 let enum_info = ctx.enums.get(enum_name)?;
94
95 let actual_repr = ctx.enum_actual_repr(enum_name).unwrap_or("u8");
96
97 for (variant_name, value) in &enum_info.pairs {
98 if variant_name == s || variant_name.ends_with(&format!("::{s}")) {
99 return Some(format!(
100 "{enum_name}::from_value({value} as {actual_repr}).expect(\"invalid enum default for {enum_name}\")"
101 ));
102 }
103 }
104
105 None
106}