How to use generics traits?
Not sure is it an issue or I do something wrong.
Demo project available here: https://github.com/NightBlaze/generics-frb
I use stateful architecture with the next structure for each screen:
Dart part:
- UI (
screen.dartfile https://github.com/NightBlaze/generics-frb/blob/main/lib/root_screen.dart ) • it's just UI without logic which calls Rust code and receive responses via stream.
Rust part:
-
Logic (
screen_name_logic.rsfile https://github.com/NightBlaze/generics-frb/blob/main/rust/src/api/screens/root_screen/root_screen_logic.rs ) • it's exposesScreenNameLogicstruct without any public fields, just functions. • it implements interior mutability pattern • it holdsview_model_sink: Option<StreamSink<ScreenNameViewModel>>field • it holds a state of a screen -
State (
screen_name_state.rsfile https://github.com/NightBlaze/generics-frb/blob/main/rust/src/api/screens/root_screen/root_screen_state.rs ) • it's a simple struct. • it has apub(crate) fn render(&self) -> ScreenNameViewModelto create a view model. Technically it'sIntotrait but I decided to not use it. -
ViewModel (
screen_name_view_model.rsfile https://github.com/NightBlaze/generics-frb/blob/main/rust/src/api/screens/root_screen/root_screen_view_models.rs ) • it's a simple struct without any logic.
So every ScreenNameLogic has a function to render state like this one:
fn render_state(&self) {
if let Some(sink) = self.view_model_sink.as_ref() {
if let Err(error) = sink.add(self.state.render()) {
debug_log(format!("[ScreenName] Fail to add view model to sink. Error: {:?}", error));
}
return;
}
debug_log("[ScreenName] Expected to be view_model_sink not null but it's null".to_string());
}
and it's a good candidate to make it generics ( https://github.com/NightBlaze/generics-frb/blob/main/rust/src/api/screens/renderer.rs )
pub(crate) trait Renderable {
type ViewModel;
fn render(&self) -> Self::ViewModel;
}
pub(crate) fn render<T, U>(
sink: &Option<StreamSink<T>>,
state: &U,
screen_name: &str,
)
where
T: SseEncode,
U: Renderable<ViewModel = T>,
{
if let Some(sink) = sink.as_ref() {
if let Err(error) = sink.add(state.render()) {
println!("[{}] Fail to add view model to sink. Error: {:?}", screen_name, error);
}
return;
}
println!("[{}] Expected to be sink not null but it's null", screen_name);
}
flutter_rust_bridge_codegen generate works without any errors but there is an error in frb_generated.rs
cannot find type `ViewModel` in this scope
I tried to make all pub but still have the error.
So my questions are:
- How to use generic traits?
- Will there be an error "duplication of ViewModel name" in the code when I'll implemented the
Renderabletrait for another struct State?
I use frb v. 2.1.0
IMHO generics is not supported yet - thus it may not be able to be used currently. However, is good to have it implemented! Feel free to PR, alternatively I may work on it later, but since this is a nontrivial new feature, I cannot guarantee it will be done very soon.
Got it. Thanks.
I'll be glad to create a PR but don't have enough proficient in Rust and Dart :(
You are welcome and it's OK!
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new issue.