Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rust default for array #8436

Open
DolajoCZ opened this issue Nov 5, 2024 · 1 comment
Open

Rust default for array #8436

DolajoCZ opened this issue Nov 5, 2024 · 1 comment

Comments

@DolajoCZ
Copy link

DolajoCZ commented Nov 5, 2024

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
Copy link
Author

DolajoCZ commented Nov 6, 2024

For correction should be sufficient to replace this code:

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

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant