fix(flatbuffers): use manual impl Default for struct object types (#8947)

* fix(flatbuffers): use manual impl Default for struct object types

* fix: handle bool and float zero literals in struct object Default impl

* fix: regenerate all test bindings with generate_code.py

* fix: data type check on swift build

* fix: test large array on struct and enum
This commit is contained in:
Renzo
2026-03-06 11:20:32 -08:00
committed by GitHub
parent 57659d9f38
commit 292870612c
37 changed files with 2181 additions and 27 deletions

View File

@@ -3037,15 +3037,56 @@ class RustGenerator : public BaseGenerator {
if (parser_.opts.generate_object_based_api) {
// Struct declaration
code_ += "";
code_ += "#[derive(Debug, Clone, PartialEq, Default)]";
code_ += "#[derive(Debug, Clone, PartialEq)]";
code_ += "{{ACCESS_TYPE}} struct {{STRUCT_OTY}} {";
ForAllStructFields(struct_def, [&](const FieldDef& field) {
(void)field; // unused.
code_ += "pub {{FIELD}}: {{FIELD_OTY}},";
});
code_ += "}";
// Manual impl Default to avoid issues with arrays > 32 elements
// where #[derive(Default)] fails on older Rust versions.
code_ += "impl Default for {{STRUCT_OTY}} {";
code_ += " fn default() -> Self {";
code_ += " Self {";
ForAllStructFields(struct_def, [&](const FieldDef& field) {
const auto full_type = GetFullType(field.value.type);
switch (full_type) {
case ftArrayOfBuiltin: {
// Use the correct zero literal for each element type:
// bool -> false, float/double -> 0.0, integers -> 0
const auto elem_type = field.value.type.VectorType().base_type;
std::string zero;
if (elem_type == BASE_TYPE_BOOL) {
zero = "false";
} else if (IsFloat(elem_type)) {
zero = "0.0";
} else {
zero = "0";
}
code_ += " {{FIELD}}: [" + zero + "; " +
NumToString(field.value.type.fixed_length) + "],";
break;
}
case ftArrayOfEnum:
case ftArrayOfStruct: {
code_ +=
" {{FIELD}}: ::flatbuffers::array_init(|_| "
"Default::default()),";
break;
}
default: {
std::string default_value =
GetDefaultValue(field, kObject);
code_ += " {{FIELD}}: " + default_value + ",";
break;
}
}
});
code_ += " }";
code_ += " }";
code_ += "}";
code_ += "";
// The `pack` method that turns the native struct into its Flatbuffers
// counterpart.
code_ += "impl {{STRUCT_OTY}} {";

View File

@@ -282,9 +282,16 @@ class SwiftGenerator : public BaseGenerator {
NumToString(field.value.type.VectorType().fixed_length);
code_.SetValue("FIXEDLENGTH", fixed_length);
const auto vector_base_type = IsStruct(field.value.type.VectorType())
? (type + "()")
: SwiftConstant(field);
std::string vector_base_type;
if (IsStruct(field.value.type.VectorType())) {
vector_base_type = type + "()";
} else if (IsBool(field.value.type.VectorType().base_type)) {
vector_base_type = "false";
} else if (IsFloat(field.value.type.VectorType().base_type)) {
vector_base_type = "0.0";
} else {
vector_base_type = SwiftConstant(field);
}
code_ += "private var _{{FIELDVAR}}: InlineArray<{{FIXEDLENGTH}}, " +
valueType + ">";