Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support third-party (mirroring) enums with struct variants #2327

Open
p0lloc opened this issue Sep 27, 2024 · 4 comments
Open

Support third-party (mirroring) enums with struct variants #2327

p0lloc opened this issue Sep 27, 2024 · 4 comments
Labels
awaiting Waiting for responses, PR, further discussions, upstream release, etc enhancement New feature or request

Comments

@p0lloc
Copy link

p0lloc commented Sep 27, 2024

Describe the bug

The code generator does not generate concrete code for a struct-like enum defined in a third-party crate.
It is left as an opaque type and cannot be constructed on the Dart side.

Steps to reproduce

  1. Create and add a third-party crate to rust_input
  2. Write a struct-like enum in the third-party crate:
pub enum ThirdPartyEnum {
    A(String),
    B(f32)
}
  1. Reference the enum in the first-party crate like:
pub fn third_party(value: ThirdPartyEnum) {
    // do something with value
}
  1. Run flutter_rust_bridge_codegen generate
  2. ThirdPartyEnum is left as abstract and cannot be used in the Dart code

Logs

#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
pub enum ThirdPartyEnum { A(String), B(f32), }
 stderr=    Checking model v0.1.0 (/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/model)
target(s) in 0.07s


Dumping cargo_expand.rs into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/source/cargo_expand.rs"
Dumping hir_tree/1_parse_pack.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/hir/hir_tree/1_parse_pack.json"
Dumping hir_tree/2_pub_use_transformer.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/hir/hir_tree/2_pub_use_transformer.json"
Dumping hir_naive_flat/1_parse_pack.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/hir/hir_naive_flat/1_parse_pack.json"
Dumping hir_naive_flat/2_move_third_party_override_transformer.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/hir/hir_naive_flat/2_move_third_party_override_transformer.json"
Dumping hir_naive_flat/3_filter_transformer.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/hir/hir_naive_flat/3_filter_transformer.json"
parse_syn_item_struct_or_enum item_ident=Ident { sym: FirstPartyEnum, span: bytes(434..448) }
parse_syn_item_struct_or_enum item_ident=Ident { sym: ThirdPartyEnum, span: bytes(36682..36696) }
Dumping hir_flat/1_parse_pack.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/hir/hir_flat/1_parse_pack.json"
Dumping hir_flat/2_filter_transformer.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/hir/hir_flat/2_filter_transformer.json"
Dumping hir_flat/3_remove_not_defined_trait_transformer.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/hir/hir_flat/3_remove_not_defined_trait_transformer.json"
Dumping hir_flat/4_copy_trait_def_to_impl_transformer.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/hir/hir_flat/4_copy_trait_def_to_impl_transformer.json"
Dumping hir_flat/5_function_frb_override_transformer.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/hir/hir_flat/5_function_frb_override_transformer.json"
Dumping hir_flat/6_merge_duplicate_transformer.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/hir/hir_flat/6_merge_duplicate_transformer.json"
Dumping hir_flat/7_resolve_type_alias_transformer.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/hir/hir_flat/7_resolve_type_alias_transformer.json"
Dumping hir_flat/8_sort_transformer.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/hir/hir_flat/8_sort_transformer.json"
parse_function function name: "first_party"
parse_function_lifetime name=first_party inputs_lifetimes=[[]] output_lifetimes=[] ans=ParseFunctionLifetimeOutput { needs_extend_lifetime_per_arg: [false] }
TypeParserWithContext.parse_type ty=String ans=Delegate(String)
TypeParserWithContext.parse_type ty=f32 ans=Primitive(F32)
TypeParserWithContext.parse_type ty=FirstPartyEnum ans=EnumRef(MirTypeEnumRef { ident: MirEnumIdent(NamespacedName { namespace: Namespace { joined_path: "crate::api::minimal" }, name: "FirstPartyEnum" }), is_exception: false })
parse_function function name: "init_app"
parse_function_lifetime name=init_app inputs_lifetimes=[] output_lifetimes=[] ans=ParseFunctionLifetimeOutput { needs_extend_lifetime_per_arg: [] }
parse_function function name: "third_party"
parse_function_lifetime name=third_party inputs_lifetimes=[[]] output_lifetimes=[] ans=ParseFunctionLifetimeOutput { needs_extend_lifetime_per_arg: [false] }
TypeParserWithContext.parse_type ty=String ans=Delegate(String)
TypeParserWithContext.parse_type ty=f32 ans=Primitive(F32)
Treat ThirdPartyEnum as opaque by compute_default_opaque
TypeParserWithContext.parse_type ty=ThirdPartyEnum ans=RustAutoOpaqueImplicit(MirTypeRustAutoOpaqueImplicit { ownership_mode: Owned, inner: MirTypeRustOpaque { namespace: Namespace { joined_path: "model" }, inner: MirRustOpaqueInner(MirLifetimeAwareType { raw: "flutter_rust_bridge::for_generated::RustAutoOpaqueInner<ThirdPartyEnum>" }), codec: Moi, dart_api_type: None, brief_name: true }, raw: MirRustAutoOpaqueRaw { string: MirLifetimeAwareType { raw: "ThirdPartyEnum" }, segments: [NameComponent { ident: "ThirdPartyEnum", args: [] }] }, reason: Some(StructOrEnumRequireOpaque), ignore: false })
Dumping early_generator/1_tentative_mir/1_parse_pack.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/hir/early_generator/1_tentative_mir/1_parse_pack.json"
Dumping early_generator/1_tentative_mir/2_filter_trait_impl_transformer.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/hir/early_generator/1_tentative_mir/2_filter_trait_impl_transformer.json"
Dumping early_generator/2_trait_impl_enum.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/hir/early_generator/2_trait_impl_enum.json"
Dumping early_generator/3_proxy_enum.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/hir/early_generator/3_proxy_enum.json"
Dumping early_generator/4_ui_related.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/hir/early_generator/4_ui_related.json"
Dumping early_generator/5_sorter.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/hir/early_generator/5_sorter.json"
parse_function function name: "first_party"
parse_function_lifetime name=first_party inputs_lifetimes=[[]] output_lifetimes=[] ans=ParseFunctionLifetimeOutput { needs_extend_lifetime_per_arg: [false] }
TypeParserWithContext.parse_type ty=String ans=Delegate(String)
TypeParserWithContext.parse_type ty=f32 ans=Primitive(F32)
TypeParserWithContext.parse_type ty=FirstPartyEnum ans=EnumRef(MirTypeEnumRef { ident: MirEnumIdent(NamespacedName { namespace: Namespace { joined_path: "crate::api::minimal" }, name: "FirstPartyEnum" }), is_exception: false })
parse_function function name: "init_app"
parse_function_lifetime name=init_app inputs_lifetimes=[] output_lifetimes=[] ans=ParseFunctionLifetimeOutput { needs_extend_lifetime_per_arg: [] }
parse_function function name: "third_party"
parse_function_lifetime name=third_party inputs_lifetimes=[[]] output_lifetimes=[] ans=ParseFunctionLifetimeOutput { needs_extend_lifetime_per_arg: [false] }
TypeParserWithContext.parse_type ty=String ans=Delegate(String)
TypeParserWithContext.parse_type ty=f32 ans=Primitive(F32)
Treat ThirdPartyEnum as opaque by compute_default_opaque
To handle some types, `enable_lifetime: true` may need to be set. Please visit https://fzyzcjy.github.io/flutter_rust_bridge/guides/lifetimes for more details
TypeParserWithContext.parse_type ty=ThirdPartyEnum ans=RustAutoOpaqueImplicit(MirTypeRustAutoOpaqueImplicit { ownership_mode: Owned, inner: MirTypeRustOpaque { namespace: Namespace { joined_path: "model" }, inner: MirRustOpaqueInner(MirLifetimeAwareType { raw: "flutter_rust_bridge::for_generated::RustAutoOpaqueInner<ThirdPartyEnum>" }), codec: Moi, dart_api_type: None, brief_name: true }, raw: MirRustAutoOpaqueRaw { string: MirLifetimeAwareType { raw: "ThirdPartyEnum" }, segments: [NameComponent { ident: "ThirdPartyEnum", args: [] }] }, reason: Some(StructOrEnumRequireOpaque), ignore: false })
Dumping 1_parse_pack.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/mir/1_parse_pack.json"
Dumping 2_filter_trait_impl_transformer.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/mir/2_filter_trait_impl_transformer.json"
Dumping api_dart.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/generator_info/api_dart.json"
Dumping api_dart.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/generator_spec/api_dart.json"
Dumping api_dart/api/minimal.dart into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/generator_text/api_dart/api/minimal.dart"
Dumping api_dart/third_party/model.dart into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/generator_text/api_dart/third_party/model.dart"
Dumping api_dart/frb_generated.dart into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/generator_text/api_dart/frb_generated.dart"
Dumping wire_rust.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/generator_info/wire_rust.json"
Dumping wire_rust.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/generator_spec/wire_rust.json"
Dumping wire_rust.rs into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/generator_text/wire_rust.rs"
Dumping wire_c.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/generator_spec/wire_c.json"
Dumping wire_c/content.h into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/generator_text/wire_c/content.h"
Dumping wire_dart.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/generator_info/wire_dart.json"
Dumping wire_dart.json into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/generator_spec/wire_dart.json"
Dumping wire_dart/Common.dart into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/generator_text/wire_dart/Common.dart"
Dumping wire_dart/Io.dart into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/generator_text/wire_dart/Io.dart"
Dumping wire_dart/Web.dart into "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal/rust/target/frb_dump/generator_text/wire_dart/Web.dart"
Guessing toolchain the runner is run into
Checking presence of freezed in dev_dependencies at "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal"
Checking presence of freezed in dev_dependencies at "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal"
Checking presence of freezed_annotation in dependencies at "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal"
Checking presence of freezed_annotation in dependencies at "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal"
Checking presence of build_runner in dev_dependencies at "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal"
Checking presence of build_runner in dev_dependencies at "/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal"
Running build_runner at dart_root="/home/dev/clone/flutter_rust_bridge/frb_example/dart_minimal"
Guessing toolchain the runner is run into

Expected behavior

A struct-like enum in the first-party crate:

pub enum FirstPartyEnum {
    A(String),
    B(f32),
}

generates the following Dart code:

@freezed
sealed class FirstPartyEnum with _$FirstPartyEnum {
  const FirstPartyEnum._();

  const factory FirstPartyEnum.a(
    String field0,
  ) = FirstPartyEnum_A;
  const factory FirstPartyEnum.b(
    double field0,
  ) = FirstPartyEnum_B;
}

I expected the same behavior for my third-party crate.

Generated binding code

No response

OS

No response

Version of flutter_rust_bridge_codegen

No response

Flutter info

No response

Version of clang++

No response

Additional context

No response

@p0lloc p0lloc added the bug Something isn't working label Sep 27, 2024
Copy link

welcome bot commented Sep 27, 2024

Hi! Thanks for opening your first issue here! 😄

@fzyzcjy
Copy link
Owner

fzyzcjy commented Sep 28, 2024

@fzyzcjy fzyzcjy added the awaiting Waiting for responses, PR, further discussions, upstream release, etc label Sep 28, 2024
@p0lloc
Copy link
Author

p0lloc commented Sep 28, 2024

Thanks for the quick response! I have read the documentation for third-party crates but I can't seem to find more information regarding struct-like enums. Are they simply not supported with automatic scanning?

The documentation for mirroring with the manual approach states "It works with basic enums too. Enums with struct variants are not yet supported".

@fzyzcjy
Copy link
Owner

fzyzcjy commented Sep 28, 2024

Hmm ok, then "mirroring Enums with struct variants" is not supported yet. A workaround is to copy-paste the definition to your first party crate. Also feel free to PR to support this new feature!

@fzyzcjy fzyzcjy changed the title Concrete Dart type not generated for third-party struct enum Support third-party (mirroring) enums with struct variants Sep 28, 2024
@fzyzcjy fzyzcjy added bug Something isn't working enhancement New feature or request and removed bug Something isn't working labels Sep 28, 2024
@fzyzcjy fzyzcjy removed the bug Something isn't working label Nov 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting Waiting for responses, PR, further discussions, upstream release, etc enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants