[rust] add deser support for enum type (#8803)
* add deser support for enum type
* update generated files
* remove deser generator when bitflag enable
* add deser test
* Restore the Rust editions version
* Remove unnecessary modifications
diff --git a/src/idl_gen_rust.cpp b/src/idl_gen_rust.cpp
index be4091d..22df1dc 100644
--- a/src/idl_gen_rust.cpp
+++ b/src/idl_gen_rust.cpp
@@ -841,6 +841,29 @@
code_ += " }";
code_ += "}";
code_ += "";
+
+ if (!IsBitFlagsEnum(enum_def)) {
+ code_ += "impl<'de> serde::Deserialize<'de> for {{ENUM_TY}} {";
+ code_ +=
+ " fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>";
+ code_ += " where";
+ code_ += " D: serde::Deserializer<'de>,";
+ code_ += " {";
+ code_ += " let s = String::deserialize(deserializer)?;";
+ code_ += " for item in {{ENUM_TY}}::ENUM_VALUES {";
+ code_ += " if let Some(item_name) = item.variant_name() {";
+ code_ += " if item_name == s {";
+ code_ += " return Ok(item.clone());";
+ code_ += " }";
+ code_ += " }";
+ code_ += " }";
+ code_ += " Err(serde::de::Error::custom(format!(";
+ code_ += " \"Unknown {{ENUM_TY}} variant: {s}\"";
+ code_ += " )))";
+ code_ += " }";
+ code_ += "}";
+ code_ += "";
+ }
}
// Generate Follow and Push so we can serialize and stuff.
diff --git a/tests/monster_test_serialize/my_game/example/any_ambiguous_aliases_generated.rs b/tests/monster_test_serialize/my_game/example/any_ambiguous_aliases_generated.rs
index 25c2f9f..c3c54ee 100644
--- a/tests/monster_test_serialize/my_game/example/any_ambiguous_aliases_generated.rs
+++ b/tests/monster_test_serialize/my_game/example/any_ambiguous_aliases_generated.rs
@@ -71,6 +71,25 @@
}
}
+impl<'de> serde::Deserialize<'de> for AnyAmbiguousAliases {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ let s = String::deserialize(deserializer)?;
+ for item in AnyAmbiguousAliases::ENUM_VALUES {
+ if let Some(item_name) = item.variant_name() {
+ if item_name == s {
+ return Ok(item.clone());
+ }
+ }
+ }
+ Err(serde::de::Error::custom(format!(
+ "Unknown AnyAmbiguousAliases variant: {s}"
+ )))
+ }
+}
+
impl<'a> flatbuffers::Follow<'a> for AnyAmbiguousAliases {
type Inner = Self;
#[inline]
diff --git a/tests/monster_test_serialize/my_game/example/any_generated.rs b/tests/monster_test_serialize/my_game/example/any_generated.rs
index 2781a59..0288089 100644
--- a/tests/monster_test_serialize/my_game/example/any_generated.rs
+++ b/tests/monster_test_serialize/my_game/example/any_generated.rs
@@ -71,6 +71,25 @@
}
}
+impl<'de> serde::Deserialize<'de> for Any {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ let s = String::deserialize(deserializer)?;
+ for item in Any::ENUM_VALUES {
+ if let Some(item_name) = item.variant_name() {
+ if item_name == s {
+ return Ok(item.clone());
+ }
+ }
+ }
+ Err(serde::de::Error::custom(format!(
+ "Unknown Any variant: {s}"
+ )))
+ }
+}
+
impl<'a> flatbuffers::Follow<'a> for Any {
type Inner = Self;
#[inline]
diff --git a/tests/monster_test_serialize/my_game/example/any_unique_aliases_generated.rs b/tests/monster_test_serialize/my_game/example/any_unique_aliases_generated.rs
index 3ae88c3..89ae6d4 100644
--- a/tests/monster_test_serialize/my_game/example/any_unique_aliases_generated.rs
+++ b/tests/monster_test_serialize/my_game/example/any_unique_aliases_generated.rs
@@ -71,6 +71,25 @@
}
}
+impl<'de> serde::Deserialize<'de> for AnyUniqueAliases {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ let s = String::deserialize(deserializer)?;
+ for item in AnyUniqueAliases::ENUM_VALUES {
+ if let Some(item_name) = item.variant_name() {
+ if item_name == s {
+ return Ok(item.clone());
+ }
+ }
+ }
+ Err(serde::de::Error::custom(format!(
+ "Unknown AnyUniqueAliases variant: {s}"
+ )))
+ }
+}
+
impl<'a> flatbuffers::Follow<'a> for AnyUniqueAliases {
type Inner = Self;
#[inline]
diff --git a/tests/monster_test_serialize/my_game/example/race_generated.rs b/tests/monster_test_serialize/my_game/example/race_generated.rs
index 681b627..c1c0618 100644
--- a/tests/monster_test_serialize/my_game/example/race_generated.rs
+++ b/tests/monster_test_serialize/my_game/example/race_generated.rs
@@ -71,6 +71,25 @@
}
}
+impl<'de> serde::Deserialize<'de> for Race {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ let s = String::deserialize(deserializer)?;
+ for item in Race::ENUM_VALUES {
+ if let Some(item_name) = item.variant_name() {
+ if item_name == s {
+ return Ok(item.clone());
+ }
+ }
+ }
+ Err(serde::de::Error::custom(format!(
+ "Unknown Race variant: {s}"
+ )))
+ }
+}
+
impl<'a> flatbuffers::Follow<'a> for Race {
type Inner = Self;
#[inline]
diff --git a/tests/monster_test_serialize/my_game/other_name_space/from_include_generated.rs b/tests/monster_test_serialize/my_game/other_name_space/from_include_generated.rs
index 17a951a..647fd6a 100644
--- a/tests/monster_test_serialize/my_game/other_name_space/from_include_generated.rs
+++ b/tests/monster_test_serialize/my_game/other_name_space/from_include_generated.rs
@@ -59,6 +59,25 @@
}
}
+impl<'de> serde::Deserialize<'de> for FromInclude {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ let s = String::deserialize(deserializer)?;
+ for item in FromInclude::ENUM_VALUES {
+ if let Some(item_name) = item.variant_name() {
+ if item_name == s {
+ return Ok(item.clone());
+ }
+ }
+ }
+ Err(serde::de::Error::custom(format!(
+ "Unknown FromInclude variant: {s}"
+ )))
+ }
+}
+
impl<'a> flatbuffers::Follow<'a> for FromInclude {
type Inner = Self;
#[inline]
diff --git a/tests/rust_serialize_test/Cargo.toml b/tests/rust_serialize_test/Cargo.toml
index ff47c12..4a28955 100644
--- a/tests/rust_serialize_test/Cargo.toml
+++ b/tests/rust_serialize_test/Cargo.toml
@@ -9,4 +9,3 @@
flatbuffers = { path = "../../rust/flatbuffers", features=["serialize"] }
serde = "1.0"
serde_json = "1.0"
-
diff --git a/tests/rust_serialize_test/src/main.rs b/tests/rust_serialize_test/src/main.rs
index 239e2a4..0978da0 100644
--- a/tests/rust_serialize_test/src/main.rs
+++ b/tests/rust_serialize_test/src/main.rs
@@ -3,6 +3,9 @@
mod monster_test_serialize_generated;
pub use monster_test_serialize_generated::my_game;
+use crate::my_game::example::AnyAmbiguousAliases;
+use std::collections::HashMap;
+
fn create_serialized_example_with_generated_code(builder: &mut flatbuffers::FlatBufferBuilder) {
let mon = {
let s0 = builder.create_string("test1");
@@ -29,7 +32,10 @@
test: Some(
my_game::example::Monster::create(
builder,
- &my_game::example::MonsterArgs { name: Some(fred_name), ..Default::default() },
+ &my_game::example::MonsterArgs {
+ name: Some(fred_name),
+ ..Default::default()
+ },
)
.as_union_value(),
),
@@ -83,4 +89,8 @@
let t1 = testarrayofstring[1].as_str().unwrap();
assert_eq!(t1, "test2");
+
+ let s = r#"{"val":"M1"}"#;
+ let des = serde_json::from_str::<HashMap<String, AnyAmbiguousAliases>>(s).unwrap();
+ assert_eq!(*des.get("val").unwrap(), AnyAmbiguousAliases::M1);
}