| <!-- WARNING: This file is machine generated by //src/tests/fidl/source_compatibility/gen, do not edit. --> |
| |
| Note: This document covers API impact only. For more details, see the |
| [ABI compatibility page](/docs/development/languages/fidl/guides/compatibility/README.md) |
| |
| # Change an enum from strict to flexible |
| |
| ## Overview |
| |
| -|[init](#init)|[step 1](#step-1)|[step 2](#step-2)|[step 3](#step-3)|[step 4](#step-4) |
| ---|---|---|---|---|--- |
| fidl|[link](#fidl-init)||[link](#fidl-2)||[link](#fidl-4) |
| dart|[link](#dart-init)|||[link](#dart-3)| |
| go|[link](#go-init)|||[link](#go-3)| |
| hlcpp|[link](#hlcpp-init)|[link](#hlcpp-1)||[link](#hlcpp-3)| |
| llcpp|[link](#llcpp-init)|[link](#llcpp-1)||[link](#llcpp-3)| |
| rust|[link](#rust-init)|[link](#rust-1)||[link](#rust-3)| |
| |
| ## Initial State {#init} |
| |
| ### FIDL {#fidl-init} |
| |
| ```fidl |
| type Color = strict enum : int32 { |
| RED = 1; |
| BLUE = 2; |
| UNKNOWN_COLOR = 3; |
| }; |
| ``` |
| |
| ### Dart {#dart-init} |
| |
| ```dart |
| fidllib.Color writer(String s) { |
| if (s == 'red') { |
| return fidllib.Color.red; |
| } else if (s == 'blue') { |
| return fidllib.Color.blue; |
| } else { |
| return fidllib.Color.unknownColor; |
| } |
| } |
| |
| String reader(fidllib.Color color) { |
| switch (color) { |
| case fidllib.Color.blue: |
| return 'blue'; |
| case fidllib.Color.red: |
| return 'red'; |
| case fidllib.Color.unknownColor: |
| return 'unknown'; |
| default: |
| return 'error'; |
| } |
| } |
| ``` |
| |
| ### Go {#go-init} |
| |
| ```go |
| func writer(s string) lib.Color { |
| switch { |
| case s == "blue": |
| return lib.ColorBlue |
| case s == "red": |
| return lib.ColorRed |
| default: |
| return lib.ColorUnknownColor |
| } |
| } |
| |
| func reader(color lib.Color) (string, error) { |
| switch color { |
| case lib.ColorBlue: |
| return "blue", nil |
| case lib.ColorRed: |
| return "red", nil |
| case lib.ColorUnknownColor: |
| return "unknown", nil |
| default: |
| return "", errors.New("invalid color enum") |
| } |
| } |
| |
| ``` |
| |
| ### HLCPP {#hlcpp-init} |
| |
| ```cpp |
| template <fidl_test::Color color> |
| class ComplementaryColors {}; |
| |
| fidl_test::Color writer(std::string s) { |
| if (s == "red") { |
| return fidl_test::Color::RED; |
| } else if (s == "blue") { |
| return fidl_test::Color::BLUE; |
| } else { |
| return fidl_test::Color::UNKNOWN_COLOR; |
| } |
| } |
| |
| std::string reader(fidl_test::Color color) { |
| switch (color) { |
| case fidl_test::Color::RED: |
| return "red"; |
| case fidl_test::Color::BLUE: |
| return "blue"; |
| case fidl_test::Color::UNKNOWN_COLOR: |
| return "unknown"; |
| default: |
| return "error"; |
| } |
| } |
| ``` |
| |
| ### LLCPP {#llcpp-init} |
| |
| ```cpp |
| template <fidl_test::wire::Color color> |
| class ComplementaryColors {}; |
| |
| fidl_test::wire::Color writer(std::string s) { |
| if (s == "red") { |
| return fidl_test::wire::Color::kRed; |
| } else if (s == "blue") { |
| return fidl_test::wire::Color::kBlue; |
| } else { |
| return fidl_test::wire::Color::kUnknownColor; |
| } |
| } |
| |
| std::string reader(fidl_test::wire::Color color) { |
| switch (color) { |
| case fidl_test::wire::Color::kRed: |
| return "red"; |
| case fidl_test::wire::Color::kBlue: |
| return "blue"; |
| case fidl_test::wire::Color::kUnknownColor: |
| return "unknown"; |
| default: |
| return "error"; |
| } |
| } |
| ``` |
| |
| ### Rust {#rust-init} |
| |
| ```rust |
| fn writer(s: &str) -> fidl_lib::Color { |
| match s { |
| "red" => fidl_lib::Color::Red, |
| "blue" => fidl_lib::Color::Blue, |
| _ => fidl_lib::Color::UnknownColor, |
| } |
| } |
| |
| fn reader(color: fidl_lib::Color) -> &'static str { |
| match color { |
| fidl_lib::Color::Red => "red", |
| fidl_lib::Color::Blue => "blue", |
| fidl_lib::Color::UnknownColor => "unknown", |
| } |
| } |
| ``` |
| |
| ## Update Source Code {#step-1} |
| |
| ### HLCPP {#hlcpp-1} |
| |
| - Remove any usages of the enum as a non-type template parameter. These usages are not supported for flexible enums. |
| |
| ```diff |
| - template <fidl_test::Color color> |
| - class ComplementaryColors {}; |
| - |
| fidl_test::Color writer(std::string s) { |
| if (s == "red") { |
| return fidl_test::Color::RED; |
| } else if (s == "blue") { |
| return fidl_test::Color::BLUE; |
| } else { |
| return fidl_test::Color::UNKNOWN_COLOR; |
| } |
| } |
| |
| std::string reader(fidl_test::Color color) { |
| switch (color) { |
| |
| ``` |
| |
| ### LLCPP {#llcpp-1} |
| |
| - Remove any usages of the enum as a non-type template parameter. These usages are not supported for flexible enums. |
| |
| ```diff |
| - template <fidl_test::wire::Color color> |
| - class ComplementaryColors {}; |
| - |
| fidl_test::wire::Color writer(std::string s) { |
| if (s == "red") { |
| return fidl_test::wire::Color::kRed; |
| } else if (s == "blue") { |
| return fidl_test::wire::Color::kBlue; |
| } else { |
| return fidl_test::wire::Color::kUnknownColor; |
| } |
| } |
| |
| std::string reader(fidl_test::wire::Color color) { |
| switch (color) { |
| |
| ``` |
| |
| ### Rust {#rust-1} |
| |
| - Allow unreachable patterns and add an underscore arm to any `match` statements on the enum. |
| |
| ```diff |
| fn writer(s: &str) -> fidl_lib::Color { |
| match s { |
| "red" => fidl_lib::Color::Red, |
| "blue" => fidl_lib::Color::Blue, |
| _ => fidl_lib::Color::UnknownColor, |
| } |
| } |
| |
| fn reader(color: fidl_lib::Color) -> &'static str { |
| + #[allow(unreachable_patterns)] |
| match color { |
| fidl_lib::Color::Red => "red", |
| fidl_lib::Color::Blue => "blue", |
| - fidl_lib::Color::UnknownColor => "unknown", |
| + _ => "unknown", |
| } |
| } |
| |
| ``` |
| |
| ## Update FIDL Library {#step-2} |
| |
| - Change from `strict` to `flexible` |
| - If the enum had a member representing an unknown enum, add the `[Unknown]` attribute to it |
| |
| ```diff |
| - type Color = strict enum : int32 { |
| + type Color = flexible enum : int32 { |
| RED = 1; |
| BLUE = 2; |
| + @unknown |
| UNKNOWN_COLOR = 3; |
| }; |
| |
| ``` |
| |
| ## Update Source Code {#step-3} |
| |
| ### Dart {#dart-3} |
| |
| - If using a custom unknown with the [Unknown] attribute, update readers and writers to use `isUnknown` and `$unknown`. |
| |
| ```diff |
| fidllib.Color writer(String s) { |
| if (s == 'red') { |
| return fidllib.Color.red; |
| } else if (s == 'blue') { |
| return fidllib.Color.blue; |
| } else { |
| - return fidllib.Color.unknownColor; |
| + return fidllib.Color.$unknown; |
| } |
| } |
| |
| String reader(fidllib.Color color) { |
| + if (color.isUnknown()) { |
| + return 'unknown'; |
| + } |
| switch (color) { |
| case fidllib.Color.blue: |
| return 'blue'; |
| case fidllib.Color.red: |
| return 'red'; |
| - case fidllib.Color.unknownColor: |
| - return 'unknown'; |
| default: |
| return 'error'; |
| } |
| } |
| |
| ``` |
| |
| ### Go {#go-3} |
| |
| - If using a custom unknown with the [Unknown] attribute, update readers and writers to use `IsUnknown` and the `_Unknown` constant. |
| - You can now use any flexible enum specific APIs |
| |
| ```diff |
| func writer(s string) lib.Color { |
| switch { |
| case s == "blue": |
| return lib.ColorBlue |
| case s == "red": |
| return lib.ColorRed |
| default: |
| - return lib.ColorUnknownColor |
| + return lib.Color_Unknown |
| } |
| } |
| |
| func reader(color lib.Color) (string, error) { |
| + if color.IsUnknown() { |
| + return "unknown", nil |
| + } |
| switch color { |
| case lib.ColorBlue: |
| return "blue", nil |
| case lib.ColorRed: |
| return "red", nil |
| - case lib.ColorUnknownColor: |
| - return "unknown", nil |
| default: |
| return "", errors.New("invalid color enum") |
| } |
| } |
| |
| |
| ``` |
| |
| ### HLCPP {#hlcpp-3} |
| |
| - If using a custom unknown with the [Unknown] attribute, update readers and writers to use `IsUnknown` and `Unknown`. |
| - You can now use any flexible enum specific APIs |
| |
| ```diff |
| fidl_test::Color writer(std::string s) { |
| if (s == "red") { |
| return fidl_test::Color::RED; |
| } else if (s == "blue") { |
| return fidl_test::Color::BLUE; |
| } else { |
| - return fidl_test::Color::UNKNOWN_COLOR; |
| + return fidl_test::Color::Unknown(); |
| } |
| } |
| |
| std::string reader(fidl_test::Color color) { |
| + if (color.IsUnknown()) { |
| + return "unknown"; |
| + } |
| switch (color) { |
| case fidl_test::Color::RED: |
| return "red"; |
| case fidl_test::Color::BLUE: |
| return "blue"; |
| - case fidl_test::Color::UNKNOWN_COLOR: |
| - return "unknown"; |
| default: |
| return "error"; |
| } |
| } |
| |
| ``` |
| |
| ### LLCPP {#llcpp-3} |
| |
| - If using a custom unknown with the [Unknown] attribute, update readers and writers to use `IsUnknown` and `Unknown`. |
| - You can now use any flexible enum specific APIs |
| |
| ```diff |
| fidl_test::wire::Color writer(std::string s) { |
| if (s == "red") { |
| return fidl_test::wire::Color::kRed; |
| } else if (s == "blue") { |
| return fidl_test::wire::Color::kBlue; |
| } else { |
| - return fidl_test::wire::Color::kUnknownColor; |
| + return fidl_test::wire::Color::Unknown(); |
| } |
| } |
| |
| std::string reader(fidl_test::wire::Color color) { |
| + if (color.IsUnknown()) { |
| + return "unknown"; |
| + } |
| switch (color) { |
| case fidl_test::wire::Color::kRed: |
| return "red"; |
| case fidl_test::wire::Color::kBlue: |
| return "blue"; |
| - case fidl_test::wire::Color::kUnknownColor: |
| - return "unknown"; |
| default: |
| return "error"; |
| } |
| } |
| |
| ``` |
| |
| ### Rust {#rust-3} |
| |
| - If using a custom unknown with the [Unknown] attribute, update readers and writers to use the `ColorUnknown!` macro (or `is_unknown` outside of match statements) and `unknown`. |
| - You can now use any flexible enum specific APIs |
| |
| ```diff |
| fn writer(s: &str) -> fidl_lib::Color { |
| match s { |
| "red" => fidl_lib::Color::Red, |
| "blue" => fidl_lib::Color::Blue, |
| - _ => fidl_lib::Color::UnknownColor, |
| + _ => fidl_lib::Color::unknown(), |
| } |
| } |
| |
| fn reader(color: fidl_lib::Color) -> &'static str { |
| - #[allow(unreachable_patterns)] |
| match color { |
| fidl_lib::Color::Red => "red", |
| fidl_lib::Color::Blue => "blue", |
| - _ => "unknown", |
| + fidl_lib::ColorUnknown!() => "unknown", |
| } |
| } |
| |
| ``` |
| |
| ## Update FIDL Library {#step-4} |
| |
| - If transitioning away from a custom unknown member, you can now remove the placeholder member at this point. |
| |
| ```diff |
| type Color = flexible enum : int32 { |
| RED = 1; |
| BLUE = 2; |
| - @unknown |
| - UNKNOWN_COLOR = 3; |
| }; |
| |
| ``` |
| |