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

Improve Documentation about borrow types #1916

Closed
patmuk opened this issue May 3, 2024 · 6 comments · Fixed by #1977
Closed

Improve Documentation about borrow types #1916

patmuk opened this issue May 3, 2024 · 6 comments · Fixed by #1977
Labels
enhancement New feature or request

Comments

@patmuk
Copy link
Contributor

patmuk commented May 3, 2024

I am not totally sure, but I assume that a struct with borrowed fields is auto opaque?

If so, can this be stated better in the documentation, for others?

My use case is having a viewModel, but defined in Rust. Thus it needs to be read by flutter, so I can't use an opaque type. But being a viewModel, I want to use borrowed values from the Model ... so the only option left is cloning the model's fields on each access ... or implementing the view logic in Flutter. So either the performance is suboptimal, or the logic might be repeated for different UIs (Flutter, cli, ...).

For example, a model like

struct MyModel {
    items : Vec<Field>
}

could have the viewModel

struct MyViewModel {
    my_items : Vec<&Field>
    not_my_items : Vec<&Field>
    total_item_count : u64
}

This is all very theoretical - as the performance hit might be not noticeable and I might never have a second UI, as Flutter covers all platforms.
But back to my request: It would be good to document this more clear if I understood it correctly.

@patmuk patmuk added the enhancement New feature or request label May 3, 2024
@fzyzcjy
Copy link
Owner

fzyzcjy commented May 3, 2024

a struct with borrowed fields is auto opaque?

By default IMHO; try to add #[frb(non_opaque)] and see whether it works.

IIRC this was originally non-opaque, but later it gives problems on some scenarios and thus the default is flipped and it looks like this...

@patmuk
Copy link
Contributor Author

patmuk commented May 3, 2024

Thanks! But it doesn't seem to work:
The lifetime parameter is missing in the generated code:

// Codec=Dco (DartCObject based), see doc to use other codecs
            impl flutter_rust_bridge::IntoDart for crate::domain::share_cycle::ShareCycleViewModel {
                fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
                    [
                    self.wanted_items.into_into_dart().into_dart(),
self.to_share_tems.into_into_dart().into_dart(),
self.completely_shared_items.into_into_dart().into_dart()
                ].into_dart()
                }
            }
            impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive for crate::domain::share_cycle::ShareCycleViewModel {}
impl flutter_rust_bridge::IntoIntoDart<crate::domain::share_cycle::ShareCycleViewModel> for crate::domain::share_cycle::ShareCycleViewModel {
            fn into_into_dart(self) -> crate::domain::share_cycle::ShareCycleViewModel {
                self
            }
        }

my struct is

#[flutter_rust_bridge::frb(non_opaque)]
#[derive(Debug, PartialEq, Eq)]
pub struct ShareCycleViewModel<'a> {
    pub wanted_items: Vec<&'a MediaItem>,
    pub to_share_tems: Vec<&'a MediaItem>,
    pub completely_shared_items: Vec<&'a MediaItem>,
}

Probably this was where the problem with non-opaque borrowed fields started?

@fzyzcjy
Copy link
Owner

fzyzcjy commented May 4, 2024

Hmm, it looks like borrowed opaque types are not supported (at least yet). To work on it, maybe we can first discuss - what code should it generate? Unsafe code can definitely handle it, but I would like to have as little unsafe code as possible, surely ;)

@patmuk
Copy link
Contributor Author

patmuk commented May 4, 2024

Yes, I agree - I would not like unsafe code as well.
Honestly, I think it might not be worth the effort. Probably modifying a Model to be shown in a view is part of the view, not the core ... even if different views have to do the same.
Or more general: If something in rust should be used by flutter (and not just passed through), it should be owned. Technically it might work - but I have the feeling that along the way one gets into trouble sooner or later.

@fzyzcjy
Copy link
Owner

fzyzcjy commented May 24, 2024

Rethinking this, I guess another way may be:

struct MyModel {
    items : Vec<Arc<Field>>
}

struct MyViewModel {
    my_items : Vec<Arc<Field>>,
    not_my_items : Vec<Arc<Field>>,
    total_item_count : u64
}

i.e. use Arc<..> (or possibly Arc<Mutex<..>> etc) to make Field shared by MyModel and MyViewModel, instead of borrowed.

@patmuk
Copy link
Contributor Author

patmuk commented May 27, 2024

@fzyzcjy thanks, that is a great idea! I currently implemented it with each (complex) item having a distinct ID, and sharing a lookup table of these between dart and rust. But an Arc sounds like a better, more direct approach. Will try that :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants