summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCasper <casperneo@uchicago.edu>2020-10-29 12:57:29 -0700
committerGitHub <noreply@github.com>2020-10-29 12:57:29 -0700
commitb08b0a440226540a5157bb7ec1e82644ef228004 (patch)
treeca418f1fea9dcc00731207e4767242abe8e07589 /src
parent17ae48decc9101beaa850e1208ea067ed0da26c3 (diff)
downloadflatbuffers-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.cpp59
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.