Add type-safe Rust EventLoop APIs

Change-Id: I8c4ac13dec513fd03fe534f8f9449585962b970c
Signed-off-by: Brian Silverman <bsilver16384@gmail.com>
diff --git a/third_party/flatbuffers/build_defs.bzl b/third_party/flatbuffers/build_defs.bzl
index c3e2bb0..4ebd872 100644
--- a/third_party/flatbuffers/build_defs.bzl
+++ b/third_party/flatbuffers/build_defs.bzl
@@ -43,6 +43,7 @@
 DEFAULT_FLATC_RUST_ARGS = [
     "--gen-object-api",
     "--require-explicit-ids",
+    "--gen-name-strings",
 ]
 
 DEFAULT_FLATC_TS_ARGS = [
diff --git a/third_party/flatbuffers/rust/flatbuffers/src/primitives.rs b/third_party/flatbuffers/rust/flatbuffers/src/primitives.rs
index 72764b2..4c12af8 100644
--- a/third_party/flatbuffers/rust/flatbuffers/src/primitives.rs
+++ b/third_party/flatbuffers/rust/flatbuffers/src/primitives.rs
@@ -326,3 +326,12 @@
 impl_follow_for_endian_scalar!(i64);
 impl_follow_for_endian_scalar!(f32);
 impl_follow_for_endian_scalar!(f64);
+
+pub trait FullyQualifiedName {
+    /// Returns the fully-qualified name for this table. This will include all namespaces,like
+    /// `MyGame.Monster`.
+    ///
+    /// Use `--gen-name-strings` when running the flatbuffers compile to generate implementations
+    /// of this trait for all tables.
+    fn get_fully_qualified_name() -> &'static str;
+}
diff --git a/third_party/flatbuffers/src/idl_gen_rust.cpp b/third_party/flatbuffers/src/idl_gen_rust.cpp
index 787d03a..0b0ad9a 100644
--- a/third_party/flatbuffers/src/idl_gen_rust.cpp
+++ b/third_party/flatbuffers/src/idl_gen_rust.cpp
@@ -1566,12 +1566,16 @@
 
   // Generates a fully-qualified name getter for use with --gen-name-strings
   void GenFullyQualifiedNameGetter(const StructDef &struct_def,
-                                   const std::string &name) {
+                                   const std::string &name, bool is_struct) {
     const std::string fully_qualified_name =
         struct_def.defined_namespace->GetFullyQualifiedName(name);
-    code_ += "  pub const fn get_fully_qualified_name() -> &'static str {";
+    code_ += "impl flatbuffers::FullyQualifiedName for {{STRUCT_TY}}\\";
+    if (!is_struct) { code_ += "<'_>\\"; }
+    code_ += "{";
+    code_ += "  fn get_fully_qualified_name() -> &'static str {";
     code_ += "    \"" + fully_qualified_name + "\"";
     code_ += "  }";
+    code_ += "}";
     code_ += "";
   }
 
@@ -1659,10 +1663,6 @@
     });
     code_ += "";
 
-    if (parser_.opts.generate_name_strings) {
-      GenFullyQualifiedNameGetter(struct_def, struct_def.name);
-    }
-
     code_ += "  #[inline]";
     code_ +=
         "  pub fn init_from_table(table: flatbuffers::Table<'a>) -> "
@@ -1918,6 +1918,10 @@
     code_ += "}";  // End of table impl.
     code_ += "";
 
+    if (parser_.opts.generate_name_strings) {
+      GenFullyQualifiedNameGetter(struct_def, struct_def.name, false);
+    }
+
     // Generate Verifier;
     code_ += "impl flatbuffers::Verifiable for {{STRUCT_TY}}<'_> {";
     code_ += "  #[inline]";
@@ -2735,10 +2739,6 @@
     code_ += "  }";
     code_ += "";
 
-    if (parser_.opts.generate_name_strings) {
-      GenFullyQualifiedNameGetter(struct_def, struct_def.name);
-    }
-
     // Generate accessor methods for the struct.
     ForAllStructFields(struct_def, [&](const FieldDef &field) {
       this->GenComment(field.doc_comment);
@@ -2849,6 +2849,10 @@
     code_ += "}";  // End impl Struct methods.
     code_ += "";
 
+    if (parser_.opts.generate_name_strings) {
+      GenFullyQualifiedNameGetter(struct_def, struct_def.name, true);
+    }
+
     // Generate Struct Object.
     if (parser_.opts.generate_object_based_api) {
       // Struct declaration