redbadger / crux

Cross-platform app development in Rust
https://redbadger.github.io/crux/
Apache License 2.0
1.66k stars 56 forks source link

Guide to using Crux with Flutter #78

Open duttaoindril opened 1 year ago

duttaoindril commented 1 year ago

There are no docs for using Crux with Flutter. Based on Crux's architecture, this should be relatively easy, since Flutter can take over UI, replacing 3 platform languages and their respective UI frameworks, allowing Crux to handle the core of the logic in the app. All Flutter would have to do is react to and trigger events. Would you have any thoughts on how to do this / get started?

StuartHarris commented 1 year ago

This sounds like a great idea! I've not done any Flutter but would be well up for trying. If you would like to contribute an example, or add Flutter to one of the existing examples then please feel free to. Otherwise we'll definitely do this soon.

patmuk commented 1 year ago

@StuartHarris I highly appreciate your efforts to support flutter! I created a flutter-rust-bridge project (https://github.com/patmuk/flutter-rust-bridge_crux_style), for which I followed their guide, but made tiny changes to implement it in the crux style. It is quite fresh, so maybe this can give you a head start in exploring how crux can communicate with Flutter.

I am not deep enough into either project, but happy to help!

StuartHarris commented 1 year ago

@patmuk thank you so much! 👍 I'll have a play with it over the weekend and let's see if we can get it in :-)

patmuk commented 1 year ago

@StuartHarris I am glad I can help :) I had a try myself today to combine both. See the three new commits in the linked project. But I didn't succeeded: The flutter-rust-bridge codegen (which is started with "just all" in the main directory conflicts with the crux codegen, with this error message:

Failed to parse function argument type &[u8]

So, the initial commit is flutter-rust-bridge only, and works. In the other commits I added a "cli shell" from a crux setup (which works) and the rest of the crux configuration. While the crux codegen works, the flutter-rust-bridge doesn't.

I did not touch the flutter app - did not try to use the crux generated files here. Maybe this is the next step, and not the flutter-rust-bridge codegen.

Got too tired now to think straight though - wish you success!!

StuartHarris commented 1 year ago

:-) Thanks @patmuk , yeah I got to the same point earlier in the week. I'm getting further with owned types (i.e. Vec<u8> instead of &[u8]). Will keep you posted

patmuk commented 1 year ago

Hi @StuartHarris, a small update: I refactored the git tree and made a branch for the work on integrating crux, see: https://github.com/patmuk/flutter-rust-bridge_crux_style/branches Apologies for messing around with the history!

StuartHarris commented 1 year ago

Thanks Patrick! I got quite far with this, but then hit a wall. The problem I'm seeing is that it's not as straightforward as I thought to deserialise the list of Requests (effects) we get back from the core (simply because they're in a list).

As well as learning some Dart and Flutter, which has been useful, it's also prompted us to work backwards a bit and rethink how we do this in general. I'm going to keep this on the back burner for a week or two while we have a look at how we hide this detail (serialisation and deserialisation).

patmuk commented 1 year ago

Hey, sorry for the late reply ... I first wanted to make it work. I extended the example and implemented a small flutter app. I used flutter_rust_bridge, with the idea of crux (but without really using crux). It is in my repo in a branch.

I didn't use any de/serialisation. I am not deep enough into "zero copy" - I know that serde can do that. The guys from Appflowy had some performance problems with exchanging pictures over FFI (something I intend to do).

flutter_rust_bridge is not using serde, and has zero copy for streams.

While serialising is more interoperable, I was wondering if mapping the types wouldn't be more practical? I for one plan to do all UIs in Flutter.

Nevertheless, I hope my code helps you to either progress in making crux compatible to flutter - or be more confirmed in your design! Let me know if I can do something to help further. And many thanks for the concept!

aaronisme commented 1 year ago

I really love the idea of crux and currently I am building an app with flutter and would like to introduce crux as the core. May I know how this issue goes and any plan to officially support dart/Flutter on Crux ?

jawadkalia commented 11 months ago

Oh this would be wonderful!

bachrc commented 11 months ago

Bumping this as this would be really helpful!

charypar commented 11 months ago

I'd personally love it, if someone who knows Dart quite well had a go at making one of the examples work.

As far as I can tell without really looking at it closely, and @StuartHarris and @patmuk can keep me honest here - there are two main challenges to figure out:

  1. The linking of the core into the app - that seems to almost work...?
  2. The Dart code generation - I suspect this depedns on #145, which we've been mulling over for a while, and I just logged it to have it written down

If someone would like to pick this up and run with it, we'd be very happy to support however we can, but please be aware it's not the most trivial thing to make happen.

patmuk commented 6 months ago

Again, please excuse my late reply!

As mentioned before, I implemented Rust <-> Flutter with Flutter-Rust-Bridge (FRB), but in the concept of crux. FRB has Dave a big upgrade to version 2, which reduced the complexity a lot. I updated my Repo to that latest version.

@charypar AFAIK you are right that crux utilizes serde-reflect. FRB does this different: They use FFI-gen to create the dart classes from rust - I think it is done here.

Binding the rust lib into a iOS/Android binary is done with cargokit.

I hope this helps! I hope my mentioning of FRB here is ok. As I see it, the projects are quite different: Crux offers multiple integrations, but the event-driven concept has to be followed (which implementation I like a lot!), while FRB is a one-trick pony integrating only rust and Flutter - but is totally open how you do that conceptually (any dart/rust function can be called from either side).