-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Description
How to use a Rust generated code with an evolution growing schema?
Main question is "what to do with panic!?".
I'm novice with Rust and following examples may be wrong.
For example, consider the monster_test.fbs. Let the Monster schema from the master branch is the scheme with version v-0. This scheme has the Race enum:
enum Race:byte {
None = -1,
Human = 0,
Dwarf,
Elf,
}
table Monster{
signed_enum:Race = None (id:48);
}The generated code in the master:
flatbuffers/tests/monster_test_generated.rs
Lines 1327 to 1330 in 26f238c
| #[inline] | |
| pub fn signed_enum(&self) -> Race { | |
| self._tab.get::<Race>(Monster::VT_SIGNED_ENUM, Some(Race::None)).unwrap() | |
| } |
Good use-case 1 (compatible update)
Let's add a new enumerator to the Race and update the schema to v-1:
enum Race:byte {
None = -1,
Human = 0,
Dwarf, // = 1
Elf, // = 2
Halfling = 3,
}- Let Tower-0 is a monster factory built at age-0 by schema v-0 rules.
- Let Tower-1 is a monster factory built at age-1 by schema v-1 rules.
- Let a Commander-1 is a broadcast server which has newest implementation v-1.
What will the Tower-0 do if it receives a new request with Halfling from the commander?
It will panic due to unwrap() call.
Bad use-case 2 (broken update)
Typically, enum values should only ever be added, never removed.
Let this happen, remove the Elf and update the scheme to v-2.
enum Race:byte {
None = -1,
Human = 0,
Dwarf, // = 1
// = 2 (removed Elf race)
Halfling = 3,
}What will happen?
The Tower-0 will panic with the Halfling request from the Commander-1.
The Tower-1 will panic with the Elf request from a Commander-0.
What should an user-code do for compatibility?
Probably, signed_enum(&self) should return Option<Race> instead of Race.
Or should a program use std::panic::catch_unwind?
Instead of the towers it can be something real (non ideal), AI-robots for example.