-
Notifications
You must be signed in to change notification settings - Fork 256
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
An Issue with methods of Rust struct and other V2.0 questions #1906
Comments
Hi!
This looks like a bug, not a feature. Could you please create a minimal reproducible sample?
Indeed it is almost stable, just put a
Could you please elaborate a bit about your scenario? The
I am not very sure, but it seems that Dart's coding convention does not add the prefix. When users want the prefix, they can
Totally agree! I will do that in the next batch |
Because the example shows a folder where there can have many files, so in v2 there is no speciality between single-block and multi-block.
Oh, IIRC we do not scan
Happy to see it is solved!
dump_all and local is for debugging (not for end users) - I probably should make the comments clearer. |
Thanks, I have no other questions. Feel free to close it when needed. |
You are welcome. No worries, maybe we can leave it open and I will work on some of them a bit later. |
Hopefully, this issue could be fixed ASAP, because I realize it can't be even worked around:
By tagging with By the way, I also tried to put the struct in In a word, I just can't find a workaround for dealing with a rust struct in which both fields and methods need to be called in Dart and used at least in one of the API files. |
Hi, could you please provide a minimal reproducible sample? With your description I am not sure why it is both inferred as opaque and non-opaque... It should be reasonable to be inferred as non-opaque. |
Yes, exactly, I just found that not all struct would be failed, but with this one: pub struct MyTestStruct {
pub name: String,
pub age: u32,
}
impl MyTestStruct {
// comment out this function would make everything generated ok.
// but with `pub` and `&mut self`, it would cause error.
pub fn test_mut(&mut self) {
self.name = "test_mut".to_string();
}
} IIRC, |
I see:
I am thinking about another approach: What if we automatically generate getters and setters for opaque types? Like,
|
I think it could be a good idea. And I guess it means that the field needs to be called in Dart as methods like that in C#. |
Not very sure, could you please elaborate a bit? In Dart we do have getters and setters, thus users can write |
Oh, so I misunderstood your idea. I am ok with both I just realized there is a workaround at present--- Write Get/Set methods in Rust for all fields needed to be called in Dart, though it is quite tedious when there are many fields that need to be called in Dart. |
I think so (Rust only supports the latter IIRC). On the other hand, it seems that Dart/Flutter encourages the former way, so I guess we can follow Dart's convension.
Totally agree it is tedious! Talking about accessors, one big problem is that, it is good for things like String and int, but what if a field is of some complex type, or even some opaque type?
Consider what is generated under the hood:
|
That is partly what I am concerned as I said at the very 1st post:
And indeed as you said, this recursive issue could occur within params of methods of a rust struct/enum, but not only within fields.
From a user's perspective, as long as a method or function is valid in Rust, it should be supported for use in Dart. Frankly, designing this integration is beyond my capability and likely requires a global project context consideration to ensure it is constructive and easy to maintain for future Frb development. |
Now auto getters/setters of opaque types is supported: https://cjycode.com/flutter_rust_bridge/guides/types/arbitrary/rust-auto-opaque/properties And, opaque types can also be inside non-opaque types: https://cjycode.com/flutter_rust_bridge/guides/types/arbitrary/rust-auto-opaque/opaque-in-translatable Thus closing this. Feel free to reopen if needed! |
@fzyzcjy, thanks your effort. Here is some feedbacks:
#[frb(opaque)]
pub struct MyTestStruct {
pub name: String,
pub age: u32,
}
impl MyTestStruct {
#[frb(sync)]
fn new(name: String, age: u32) -> Self {
Self { name, age }
}
pub fn test_mut(&mut self) {
self.name = "test_mut".to_string();
}
} It can't be inited by
|
No! It must be a bug that it does not understand constructors. Could you please create an issue such that I can have a look?
IMHO this is solved in #1954, but I chose to discard it, because I realize that, the meaning of the api folder is the home for things that users want to generate. If a struct is not there, then just like if a function is not there, then we should think users really do not want us to generate anything for that. Feel free to discuss your scenario if this does not suit your needs! |
Ok, I've opened a new issue #1981.
For example, for a fn API in pub async fn update_media_doc_detail(media_doc: MediaDoc) -> MediaDoc {
...
} Firstly, it is clear that using custom structs as parameters or return types for an API is unavoidable(especially for a big project), as demonstrated by the However, your suggestion implies that if methods or fields of any type taken in an API function would be used in Dart, then it must be defined within the same API module. I believe this is a poor practice because it could lead to various types with different semantics being mixed together in the same file or (API ) module, which would complicate the codebase and hinder maintainability. If you agree on it, then, for the complex parsing part, I would suggest that it is ok to work around to make frb scan and generate those types not defined in API module with a new macro but not by parsing one by one through the API function, which I know is quite complex. For example, suppose the custom [#frb(generate)]
struct MediaDoc {
} then, let frb scan ALL the rust folder, once found type with |
(I will check and reply a bit later, hopefully within a day) |
What about something like
Or, even more folders like
Then it seems that we ensure things are in different modules. The implementation is simple (as long as the types are in the same crate; it seems no problem if in different modules i.e. files) |
I've though of this approach. This is what I said:
Here "(API) module" means it may be in API folder(the module) but not in the exact API definition file(like But still, as I stated, within this way, it implies that almost all custom types should belong to a module called This is like saying the human body is an app that needs to integrate various functional organs. The modules used for integration are called APIs. However, in your approach, you would place all the organs and their required functions under the API module. I believe, based on the "single responsibility principle," that different organs should be placed in different modules (rather than in the API module used for bridging functions). What if asking other core contributors to have a wide and rational discussion on it? |
Hmm, what if you change the
Sure, what about creating a new issue firstly (since this thread is already a bit long and contains multiple topics) |
I've put it in #1987. |
This is my 1st time using Frb v2.0(with dev. 32) in my own project since Frb v1.x.
If the struct is not defined in the
Api
folder, then its methods can't be generated--- This reminds me of the heavy time I spent on the multi-block issue PR to solve this issue(the potential recursive issue, because one of the fields of the issued rust struct could be another rust struct/enum, which may contain its own public methods...).
(Given the extensive time and effort I have already dedicated to this issue, I am hesitant to consider further contributions in this area, especially V2.0 is still not stable and under active development. My latest v1.x modification without this issue could be referred here, though it has other bugs)
Questions on V2.0:
rust_input
influtter_rust_bridge.yaml
, how to specify more than one file respectively? (Seems no way at present)I know
rust_input: rust/src/api/**/*.rs
is supported, but how to specify more than one file respectively.For example, in multi-block cases, with prefixes like
Api1.
Api2.
can make it more clear in Dart side, and it can also be used to distinguish the same name dart methods---indeed, currently, it can be done by manually adding the dart class, but a little verbose, since it has to be done everytime the rust side fns is changed.#[frb(sync)]
,#[frb(ignore)]
, and compound usage case, I did find them inseparated guidance file, but I think it is better to systematically introduce them in a specific page file in guidance in table style.
The text was updated successfully, but these errors were encountered: