| <!-- 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) |
| |
| # Remove union member |
| |
| ## Overview |
| |
| -|[init](#init)|[step 1](#step-1)|[step 2](#step-2)|[step 3](#step-3) |
| ---|---|---|---|--- |
| fidl|[link](#fidl-init)||[link](#fidl-2)| |
| dart|[link](#dart-init)|[link](#dart-1)||[link](#dart-3) |
| go|[link](#go-init)|[link](#go-1)||[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 JsonValue = flexible union { |
| 1: int_value int32; |
| 2: string_value string:MAX; |
| 3: float_value float32; |
| }; |
| ``` |
| |
| ### Dart {#dart-init} |
| |
| ```dart |
| fidllib.JsonValue writer(String s) { |
| final asFloat = double.tryParse(s); |
| if (asFloat != null) { |
| return fidllib.JsonValue.withFloatValue(asFloat); |
| } |
| final asInt = int.tryParse(s); |
| if (asInt != null) { |
| return fidllib.JsonValue.withIntValue(asInt); |
| } |
| return fidllib.JsonValue.withStringValue(s); |
| } |
| |
| String reader(fidllib.JsonValue value) { |
| switch (value.$tag) { |
| case fidllib.JsonValueTag.intValue: |
| return '${value.intValue}'; |
| case fidllib.JsonValueTag.stringValue: |
| return value.stringValue; |
| case fidllib.JsonValueTag.floatValue: |
| return '${value.floatValue}'; |
| default: |
| return '<${value.$unknownData.data.length} unknown bytes>'; |
| } |
| } |
| |
| ``` |
| |
| ### Go {#go-init} |
| |
| ```go |
| func writer(s string) lib.JsonValue { |
| n, err := strconv.ParseInt(s, 10, 32) |
| if err == nil { |
| return lib.JsonValueWithIntValue(int32(n)) |
| } |
| var f float64 |
| f, err = strconv.ParseFloat(s, 64) |
| if err == nil { |
| return lib.JsonValueWithFloatValue(float32(f)) |
| } |
| return lib.JsonValueWithStringValue(s) |
| } |
| |
| func reader(value lib.JsonValue) string { |
| switch value.Which() { |
| case lib.JsonValueIntValue: |
| return fmt.Sprintf("%d", value.IntValue) |
| case lib.JsonValueStringValue: |
| return value.StringValue |
| case lib.JsonValueFloatValue: |
| return fmt.Sprintf("%f", value.FloatValue) |
| default: |
| return fmt.Sprintf("<%d unknown bytes>", len(value.GetUnknownData().Bytes)) |
| } |
| } |
| |
| ``` |
| |
| ### HLCPP {#hlcpp-init} |
| |
| ```cpp |
| fidl_test::JsonValue writer(const std::string& s) { |
| std::optional<float> maybe_float = parse_as_float(s); |
| if (maybe_float) { |
| return fidl_test::JsonValue::WithFloatValue(std::move(*maybe_float)); |
| } |
| |
| std::optional<int32_t> maybe_int = parse_as_int(s); |
| if (maybe_int) { |
| return fidl_test::JsonValue::WithIntValue(std::move(*maybe_int)); |
| } |
| auto val = s; |
| return fidl_test::JsonValue::WithStringValue(std::move(val)); |
| } |
| |
| std::string reader(const fidl_test::JsonValue& value) { |
| switch (value.Which()) { |
| case fidl_test::JsonValue::Tag::kIntValue: |
| return std::to_string(value.int_value()); |
| case fidl_test::JsonValue::Tag::kStringValue: |
| return value.string_value(); |
| case fidl_test::JsonValue::Tag::kFloatValue: |
| return std::to_string(value.float_value()); |
| case fidl_test::JsonValue::Tag::Invalid: |
| return "<uninitialized>"; |
| case fidl_test::JsonValue::Tag::kUnknown: { |
| std::ostringstream out; |
| out << "<" << value.UnknownBytes()->size() << " unknown bytes>"; |
| return out.str(); |
| } |
| } |
| } |
| ``` |
| |
| ### LLCPP {#llcpp-init} |
| |
| ```cpp |
| fidl_test::wire::JsonValue writer(fidl::AnyArena& allocator, const std::string& s) { |
| std::optional<float> maybe_float = parse_as_float(s); |
| if (maybe_float) { |
| return fidl_test::wire::JsonValue::WithIntValue(allocator, *maybe_float); |
| } |
| std::optional<int32_t> maybe_int = parse_as_int(s); |
| if (maybe_int) { |
| return fidl_test::wire::JsonValue::WithIntValue(allocator, *maybe_int); |
| } |
| return fidl_test::wire::JsonValue::WithStringValue(allocator, allocator, s); |
| } |
| |
| std::string reader(const fidl_test::wire::JsonValue& value) { |
| switch (value.which()) { |
| case fidl_test::wire::JsonValue::Tag::kIntValue: |
| return std::to_string(value.int_value()); |
| case fidl_test::wire::JsonValue::Tag::kStringValue: |
| return std::string(value.string_value().data(), value.string_value().size()); |
| case fidl_test::wire::JsonValue::Tag::kFloatValue: |
| return std::to_string(value.float_value()); |
| case fidl_test::wire::JsonValue::Tag::kUnknown: |
| return "<unknown>"; |
| } |
| } |
| ``` |
| |
| ### Rust {#rust-init} |
| |
| ```rust |
| fn writer(s: &str) -> fidl_lib::JsonValue { |
| let as_float = s.parse::<f32>(); |
| if let Ok(val) = as_float { |
| return fidl_lib::JsonValue::FloatValue(val); |
| } |
| let as_int = s.parse::<i32>(); |
| as_int |
| .map(|n| fidl_lib::JsonValue::IntValue(n)) |
| .unwrap_or(fidl_lib::JsonValue::StringValue(s.to_string())) |
| } |
| |
| fn reader(value: fidl_lib::JsonValue) -> String { |
| match value { |
| fidl_lib::JsonValue::IntValue(n) => format!("{}", n), |
| fidl_lib::JsonValue::StringValue(s) => s, |
| fidl_lib::JsonValue::FloatValue(v) => format!("{:.2}", v), |
| fidl_lib::JsonValueUnknown!() => "<unknown>".to_string(), |
| } |
| } |
| ``` |
| |
| ## Update Source Code {#step-1} |
| |
| ### Dart {#dart-1} |
| |
| - Update writers to stop producing new instances of the soon-to-be-removed variant. |
| - Remove references to the soon-to-be-removed variant from any switch statements on the union tag. These must be temporarily handled as part of a default case. |
| |
| ```diff |
| fidllib.JsonValue writer(String s) { |
| - final asFloat = double.tryParse(s); |
| - if (asFloat != null) { |
| - return fidllib.JsonValue.withFloatValue(asFloat); |
| - } |
| final asInt = int.tryParse(s); |
| if (asInt != null) { |
| return fidllib.JsonValue.withIntValue(asInt); |
| } |
| return fidllib.JsonValue.withStringValue(s); |
| } |
| |
| String reader(fidllib.JsonValue value) { |
| switch (value.$tag) { |
| case fidllib.JsonValueTag.intValue: |
| return '${value.intValue}'; |
| case fidllib.JsonValueTag.stringValue: |
| return value.stringValue; |
| - case fidllib.JsonValueTag.floatValue: |
| - return '${value.floatValue}'; |
| + case fidllib.JsonValueTag.$unknown: |
| + return '<${value.$unknownData.data.length} unknown bytes>'; |
| default: |
| - return '<${value.$unknownData.data.length} unknown bytes>'; |
| + return '<unknown new member>'; |
| } |
| } |
| |
| |
| ``` |
| |
| ### Go {#go-1} |
| |
| - Update writers to stop producing new instances of the soon-to-be-removed variant. |
| - Remove references to the soon-to-be-removed variant from any switch statements on the union tag. These must be temporarily handled as part of a default case. |
| |
| ```diff |
| func writer(s string) lib.JsonValue { |
| n, err := strconv.ParseInt(s, 10, 32) |
| if err == nil { |
| return lib.JsonValueWithIntValue(int32(n)) |
| - } |
| - var f float64 |
| - f, err = strconv.ParseFloat(s, 64) |
| - if err == nil { |
| - return lib.JsonValueWithFloatValue(float32(f)) |
| } |
| return lib.JsonValueWithStringValue(s) |
| } |
| |
| func reader(value lib.JsonValue) string { |
| switch value.Which() { |
| case lib.JsonValueIntValue: |
| return fmt.Sprintf("%d", value.IntValue) |
| case lib.JsonValueStringValue: |
| return value.StringValue |
| - case lib.JsonValueFloatValue: |
| - return fmt.Sprintf("%f", value.FloatValue) |
| + case lib.JsonValue_unknownData: |
| + return fmt.Sprintf("<%d unknown bytes>", len(value.GetUnknownData().Bytes)) |
| default: |
| - return fmt.Sprintf("<%d unknown bytes>", len(value.GetUnknownData().Bytes)) |
| + return "<unknown new member>" |
| } |
| } |
| |
| |
| ``` |
| |
| ### HLCPP {#hlcpp-1} |
| |
| - Update writers to stop producing new instances of the soon-to-be-removed variant. |
| - Remove references to the soon-to-be-removed variant from any switch statements on the union tag. These must be temporarily handled as part of a default case. |
| |
| ```diff |
| fidl_test::JsonValue writer(const std::string& s) { |
| - std::optional<float> maybe_float = parse_as_float(s); |
| - if (maybe_float) { |
| - return fidl_test::JsonValue::WithFloatValue(std::move(*maybe_float)); |
| - } |
| - |
| std::optional<int32_t> maybe_int = parse_as_int(s); |
| if (maybe_int) { |
| return fidl_test::JsonValue::WithIntValue(std::move(*maybe_int)); |
| } |
| auto val = s; |
| return fidl_test::JsonValue::WithStringValue(std::move(val)); |
| } |
| |
| std::string reader(const fidl_test::JsonValue& value) { |
| switch (value.Which()) { |
| case fidl_test::JsonValue::Tag::kIntValue: |
| return std::to_string(value.int_value()); |
| case fidl_test::JsonValue::Tag::kStringValue: |
| return value.string_value(); |
| - case fidl_test::JsonValue::Tag::kFloatValue: |
| - return std::to_string(value.float_value()); |
| case fidl_test::JsonValue::Tag::Invalid: |
| return "<uninitialized>"; |
| case fidl_test::JsonValue::Tag::kUnknown: { |
| std::ostringstream out; |
| out << "<" << value.UnknownBytes()->size() << " unknown bytes>"; |
| return out.str(); |
| } |
| + default: |
| + return "<unknown new member>"; |
| } |
| } |
| |
| ``` |
| |
| ### LLCPP {#llcpp-1} |
| |
| - Update writers to stop producing new instances of the soon-to-be-removed variant. |
| - Remove references to the soon-to-be-removed variant from any switch statements on the union tag. These must be temporarily handled as part of a default case. |
| |
| ```diff |
| fidl_test::wire::JsonValue writer(fidl::AnyArena& allocator, const std::string& s) { |
| - std::optional<float> maybe_float = parse_as_float(s); |
| - if (maybe_float) { |
| - return fidl_test::wire::JsonValue::WithIntValue(allocator, *maybe_float); |
| - } |
| std::optional<int32_t> maybe_int = parse_as_int(s); |
| if (maybe_int) { |
| return fidl_test::wire::JsonValue::WithIntValue(allocator, *maybe_int); |
| } |
| return fidl_test::wire::JsonValue::WithStringValue(allocator, allocator, s); |
| } |
| |
| std::string reader(const fidl_test::wire::JsonValue& value) { |
| switch (value.which()) { |
| case fidl_test::wire::JsonValue::Tag::kIntValue: |
| return std::to_string(value.int_value()); |
| case fidl_test::wire::JsonValue::Tag::kStringValue: |
| return std::string(value.string_value().data(), value.string_value().size()); |
| - case fidl_test::wire::JsonValue::Tag::kFloatValue: |
| - return std::to_string(value.float_value()); |
| case fidl_test::wire::JsonValue::Tag::kUnknown: |
| + default: |
| return "<unknown>"; |
| } |
| } |
| |
| ``` |
| |
| ### Rust {#rust-1} |
| |
| - Update writers to stop producing new instances of the soon-to-be-removed variant. |
| - Remove references to the soon-to-be-removed variant from any match statements on the union. These must be temporarily handled as part of a default catch-all case. |
| |
| ```diff |
| fn writer(s: &str) -> fidl_lib::JsonValue { |
| - let as_float = s.parse::<f32>(); |
| - if let Ok(val) = as_float { |
| - return fidl_lib::JsonValue::FloatValue(val); |
| - } |
| let as_int = s.parse::<i32>(); |
| as_int |
| .map(|n| fidl_lib::JsonValue::IntValue(n)) |
| .unwrap_or(fidl_lib::JsonValue::StringValue(s.to_string())) |
| } |
| |
| fn reader(value: fidl_lib::JsonValue) -> String { |
| match value { |
| fidl_lib::JsonValue::IntValue(n) => format!("{}", n), |
| fidl_lib::JsonValue::StringValue(s) => s, |
| - fidl_lib::JsonValue::FloatValue(v) => format!("{:.2}", v), |
| - fidl_lib::JsonValueUnknown!() => "<unknown>".to_string(), |
| + _ => "<unknown>".to_string(), |
| } |
| } |
| |
| ``` |
| |
| ## Update FIDL Library {#step-2} |
| |
| - Remove the union variant |
| |
| ```diff |
| type JsonValue = flexible union { |
| 1: int_value int32; |
| 2: string_value string:MAX; |
| - 3: float_value float32; |
| }; |
| |
| ``` |
| |
| ## Update Source Code {#step-3} |
| |
| ### Dart {#dart-3} |
| |
| - The default case can now be removed from any switch statements on the union tag. |
| |
| ```diff |
| if (asInt != null) { |
| return fidllib.JsonValue.withIntValue(asInt); |
| } |
| return fidllib.JsonValue.withStringValue(s); |
| } |
| |
| String reader(fidllib.JsonValue value) { |
| switch (value.$tag) { |
| case fidllib.JsonValueTag.intValue: |
| return '${value.intValue}'; |
| case fidllib.JsonValueTag.stringValue: |
| return value.stringValue; |
| - case fidllib.JsonValueTag.$unknown: |
| + default: |
| return '<${value.$unknownData.data.length} unknown bytes>'; |
| - default: |
| - return '<unknown new member>'; |
| } |
| } |
| |
| |
| ``` |
| |
| ### Go {#go-3} |
| |
| - The default case can now be removed from any switch statements on the union tag. |
| |
| ```diff |
| if err == nil { |
| return lib.JsonValueWithIntValue(int32(n)) |
| } |
| return lib.JsonValueWithStringValue(s) |
| } |
| |
| func reader(value lib.JsonValue) string { |
| switch value.Which() { |
| case lib.JsonValueIntValue: |
| return fmt.Sprintf("%d", value.IntValue) |
| case lib.JsonValueStringValue: |
| return value.StringValue |
| - case lib.JsonValue_unknownData: |
| + default: |
| return fmt.Sprintf("<%d unknown bytes>", len(value.GetUnknownData().Bytes)) |
| - default: |
| - return "<unknown new member>" |
| } |
| } |
| |
| |
| ``` |
| |
| ### HLCPP {#hlcpp-3} |
| |
| - The default case can now be removed from any switch statements on the union tag. |
| |
| ```diff |
| switch (value.Which()) { |
| case fidl_test::JsonValue::Tag::kIntValue: |
| return std::to_string(value.int_value()); |
| case fidl_test::JsonValue::Tag::kStringValue: |
| return value.string_value(); |
| case fidl_test::JsonValue::Tag::Invalid: |
| return "<uninitialized>"; |
| case fidl_test::JsonValue::Tag::kUnknown: { |
| std::ostringstream out; |
| out << "<" << value.UnknownBytes()->size() << " unknown bytes>"; |
| return out.str(); |
| } |
| - default: |
| - return "<unknown new member>"; |
| } |
| } |
| |
| ``` |
| |
| ### LLCPP {#llcpp-3} |
| |
| - The default case can now be removed from any switch statements on the union tag. |
| |
| ```diff |
| return fidl_test::wire::JsonValue::WithIntValue(allocator, *maybe_int); |
| } |
| return fidl_test::wire::JsonValue::WithStringValue(allocator, allocator, s); |
| } |
| |
| std::string reader(const fidl_test::wire::JsonValue& value) { |
| switch (value.which()) { |
| case fidl_test::wire::JsonValue::Tag::kIntValue: |
| return std::to_string(value.int_value()); |
| case fidl_test::wire::JsonValue::Tag::kStringValue: |
| return std::string(value.string_value().data(), value.string_value().size()); |
| case fidl_test::wire::JsonValue::Tag::kUnknown: |
| - default: |
| return "<unknown>"; |
| } |
| } |
| |
| ``` |
| |
| ### Rust {#rust-3} |
| |
| - The catch-all case can now be removed from any match statements on the union. |
| |
| ```diff |
| fn writer(s: &str) -> fidl_lib::JsonValue { |
| let as_int = s.parse::<i32>(); |
| as_int |
| .map(|n| fidl_lib::JsonValue::IntValue(n)) |
| .unwrap_or(fidl_lib::JsonValue::StringValue(s.to_string())) |
| } |
| |
| fn reader(value: fidl_lib::JsonValue) -> String { |
| match value { |
| fidl_lib::JsonValue::IntValue(n) => format!("{}", n), |
| fidl_lib::JsonValue::StringValue(s) => s, |
| - _ => "<unknown>".to_string(), |
| + fidl_lib::JsonValueUnknown!() => "<unknown>".to_string(), |
| } |
| } |
| |
| ``` |
| |