flatbuffers icon indicating copy to clipboard operation
flatbuffers copied to clipboard

Rust default for array

Open DolajoCZ opened this issue 1 year ago • 3 comments

Issue

Invalid generation of rust code with switch --gen-object-api and struct containing array of size 33 and more.

Reason

Generated object api struct implement Default trait by derive macro, but array implement Default trait only for size up to 32 (source).

Example of invalid fbs

Fbs file example.fbs

namespace example;

struct FooStruct {
	array_values: [double:81];
}

table FooTable {
	foo_struct: FooStruct;
}

root_type FooTable;

Command

flatc.exe --rust --gen-object-api example.fbs

Invalid code section

    #[derive(Debug, Clone, PartialEq, Default)]
    pub struct FooStructT {
        pub array_values: [f64; 81],
    }

Tool versions

flatc - 24.3.25 rustc - 1.82.0

Potential solution

For struct with array implement custom Default trait.

Example of solution from code above

    #[derive(Debug, Clone, PartialEq)]
    pub struct FooStructT {
        pub array_values: [f64; 81],
    }

    impl std::default::Default for FooStructT {
        fn default() -> Self {
            Self {
                array_values: [Default::default(); 81],
            }
        }
    }

DolajoCZ avatar Nov 05 '24 08:11 DolajoCZ

For correction should be sufficient to replace this code:

https://github.com/google/flatbuffers/blob/595bf0007ab1929570c7671f091313c8fc20644e/src/idl_gen_rust.cpp#L2910-L2917

by this code:

      // Struct declaration
      code_ += "#[derive(Debug, Copy, Clone, PartialEq)]";
      code_ += "{{ACCESS_TYPE}} struct {{STRUCT_OTY}} {";
      ForAllStructFields(struct_def, [&](const FieldDef &field) {
        (void)field;  // unused.
        code_ += "pub {{FIELD}}: {{FIELD_OTY}},";
      });
      code_ += "}";

      // Struct default trait implementation
      code_ += "impl std::default::Default for {{STRUCT_OTY}} {";
      code_ += "    fn default() -> Self {";
      code_ += "      Self {";
      ForAllStructFields(struct_def, [&](const FieldDef &field) {
        const Type &type = field.value.type;
        if (IsArray(type)) {
          code_ += "      {{FIELD}}: [Default::default(); " + NumToString(type.fixed_length) + "],";
        } else {
          code_ += "      {{FIELD}}: Default::default(),";
        }
      });
      code_ += "    }";
      code_ += "  }";
      code_ += "}";

Base on some tests everything looks good but I am not C++ developer so it is necessary to review it by some expert.

DolajoCZ avatar Nov 06 '24 09:11 DolajoCZ

This issue is stale because it has been open 6 months with no activity. Please comment or label not-stale, or this will be closed in 14 days.

github-actions[bot] avatar May 07 '25 20:05 github-actions[bot]

This PR should solve this issue.

DolajoCZ avatar May 12 '25 18:05 DolajoCZ

This issue is stale because it has been open 6 months with no activity. Please comment or label not-stale, or this will be closed in 14 days.

github-actions[bot] avatar Nov 10 '25 20:11 github-actions[bot]