diff options
author | Casper <casperneo@uchicago.edu> | 2020-10-29 12:57:29 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-29 12:57:29 -0700 |
commit | b08b0a440226540a5157bb7ec1e82644ef228004 (patch) | |
tree | ca418f1fea9dcc00731207e4767242abe8e07589 /src | |
parent | 17ae48decc9101beaa850e1208ea067ed0da26c3 (diff) | |
download | flatbuffers-b08b0a440226540a5157bb7ec1e82644ef228004.tar.gz flatbuffers-b08b0a440226540a5157bb7ec1e82644ef228004.tar.bz2 flatbuffers-b08b0a440226540a5157bb7ec1e82644ef228004.zip |
Implement `Debug` trait for Rust flatbuffers. (#6207)
* Refactor idl_gen_rust to a ForAllX continuation pattern.
* Removed unneeded SetValue and updated sample rust gencode
* Make Rust flatbuffers print right
* Generated code and removed unnecessary trait constraint
* bumped rust version. Release required
* removed an unwrap in Rust Debug-print unions
* Tested formatting flatbuffers in rust.
* Set float precision in flaky debug-print test
* impl Debug for structs too
Co-authored-by: Casper Neo <cneo@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/idl_gen_rust.cpp | 59 |
1 files changed, 56 insertions, 3 deletions
diff --git a/src/idl_gen_rust.cpp b/src/idl_gen_rust.cpp index 590de4c6..b6434c84 100644 --- a/src/idl_gen_rust.cpp +++ b/src/idl_gen_rust.cpp @@ -1188,7 +1188,7 @@ class RustGenerator : public BaseGenerator { // Generate an offset type, the base type, the Follow impl, and the // init_from_table impl. code_ += "pub enum {{OFFSET_TYPELABEL}} {}"; - code_ += "#[derive(Copy, Clone, Debug, PartialEq)]"; + code_ += "#[derive(Copy, Clone, PartialEq)]"; code_ += ""; GenComment(struct_def.doc_comment); @@ -1454,6 +1454,45 @@ class RustGenerator : public BaseGenerator { code_ += " }"; code_ += "}"; code_ += ""; + + code_ += "impl std::fmt::Debug for {{STRUCT_NAME}}<'_> {"; + code_ += " fn fmt(&self, f: &mut std::fmt::Formatter<'_>" + ") -> std::fmt::Result {"; + code_ += " let mut ds = f.debug_struct(\"{{STRUCT_NAME}}\");"; + ForAllTableFields(struct_def, [&](const FieldDef &field) { + if (GetFullType(field.value.type) == ftUnionValue) { + // Generate a match statement to handle unions properly. + code_.SetValue("KEY_TYPE", GenTableAccessorFuncReturnType(field, "")); + code_.SetValue("FIELD_TYPE_FIELD_NAME", field.name); + code_.SetValue("UNION_ERR", "&\"InvalidFlatbuffer: Union discriminant" + " does not match value.\""); + + code_ += " match self.{{FIELD_NAME}}_type() {"; + ForAllUnionVariantsBesidesNone(*field.value.type.enum_def, + [&](const EnumVal &unused){ + (void) unused; + code_ += " {{U_ELEMENT_ENUM_TYPE}} => {"; + code_ += " if let Some(x) = self.{{FIELD_TYPE_FIELD_NAME}}_as_" + "{{U_ELEMENT_NAME}}() {"; + code_ += " ds.field(\"{{FIELD_NAME}}\", &x)"; + code_ += " } else {"; + code_ += " ds.field(\"{{FIELD_NAME}}\", {{UNION_ERR}})"; + code_ += " }"; + code_ += " },"; + }); + code_ += " _ => { "; + code_ += " let x: Option<()> = None;"; + code_ += " ds.field(\"{{FIELD_NAME}}\", &x)"; + code_ += " },"; + code_ += " };"; + } else { + // Most fields. + code_ += " ds.field(\"{{FIELD_NAME}}\", &self.{{FIELD_NAME}}());"; + } + }); + code_ += " ds.finish()"; + code_ += " }"; + code_ += "}"; } // Generate functions to compare tables and structs by key. This function @@ -1618,7 +1657,7 @@ class RustGenerator : public BaseGenerator { // PartialEq is useful to derive because we can correctly compare structs // for equality by just comparing their underlying byte data. This doesn't // hold for PartialOrd/Ord. - code_ += "#[derive(Clone, Copy, Debug, PartialEq)]"; + code_ += "#[derive(Clone, Copy, PartialEq)]"; code_ += "pub struct {{STRUCT_NAME}} {"; int padding_id = 0; @@ -1630,9 +1669,23 @@ class RustGenerator : public BaseGenerator { code_ += padding; } }); - code_ += "} // pub struct {{STRUCT_NAME}}"; + // Debug for structs. + code_ += "impl std::fmt::Debug for {{STRUCT_NAME}} {"; + code_ += " fn fmt(&self, f: &mut std::fmt::Formatter" + ") -> std::fmt::Result {"; + code_ += " f.debug_struct(\"{{STRUCT_NAME}}\")"; + ForAllStructFields(struct_def, [&](const FieldDef &unused) { + (void) unused; + code_ += " .field(\"{{FIELD_NAME}}\", &self.{{FIELD_NAME}}())"; + }); + code_ += " .finish()"; + code_ += " }"; + code_ += "}"; + code_ += ""; + + // Generate impls for SafeSliceAccess (because all structs are endian-safe), // Follow for the value type, Follow for the reference type, Push for the // value type, and Push for the reference type. |