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

The right way to send a large buffer Vec<u8> from rust to dart #5

Closed
chertov opened this issue Jul 6, 2021 · 6 comments
Closed

The right way to send a large buffer Vec<u8> from rust to dart #5

chertov opened this issue Jul 6, 2021 · 6 comments
Labels
question Further information is requested

Comments

@chertov
Copy link
Collaborator

chertov commented Jul 6, 2021

For example, in my use case i need to connect to backend via websockets from rust.
I start the connection process in Store::create() function in a new thread, i want to load jpeg pictures and render them with flutter. I can't create #[rid::reply] enum Replay with variant contains Vec<u8> field
error: For replies with a single field it needs to be a u64 or String, i.e. 'Started(u64) or Started(String)'
to use it like here https://github.com/thlorenz/rid-examples/blob/49de40408064833823aad08dbd4e03b928ff3265/flutter/todo_cubit/lib/blocs/cubit/todo_cubit.dart#L31
And #[rid::replay] can't be a struct: error: rid::reply attribute can only be applied to enums
I can keep data in the state, but it's not very convenient.. i need to send 'update' message and get replay back to clear the buffer in the store. How to do this right way? Is this possible today? Thanks!

@chertov
Copy link
Collaborator Author

chertov commented Jul 6, 2021

seems Vec<u8> fields in the state don't work now

plugin/lib/generated/rid_api.dart:321:20: Error: Type 'ffigen_bind.Vec_Rawu8' not found.
  dart_ffi.Pointer<ffigen_bind.Vec_Rawu8> get jpeg_data => rid_ffi.rid_store_jpeg_data(this);
                   ^^^^^^^^^^^^^^^^^^^^^

only vectors of struct #[rid::model] are working

@chertov
Copy link
Collaborator Author

chertov commented Jul 6, 2021

seems Vec<u8> fields in the state don't work now

the problem is here:

"{dart_ffi}.Pointer<{ffigen_bind}.Vec_Raw{ty}>",

my dirty little hack for Vec:

            DartType::Vec(inner) => {
                let raw = if inner == "u8" {
                    ""
                } else {
                    "Raw"
                };
                format!(
                    "{dart_ffi}.Pointer<{ffigen_bind}.Vec_{raw}{ty}>",
                    dart_ffi = DART_FFI,
                    ffigen_bind = FFI_GEN_BIND,
                    raw = raw,
                    ty = inner
                )
            },

it might be better to do this with recursively nested types, but I haven't learned enough of the structure of the codegen yet

@thlorenz
Copy link
Owner

thlorenz commented Jul 7, 2021

I'm sorry you're running into these problems, but I'm happy you're digging in and are encountering work arounds.
rid is still in somewhat early stage (which is why I'm happy to have sponsors so I can dig in more).

The whole Raw business may go away soon since Dart 2.13 added typedefs which we could use to rename dangerous types on the Dart side. I think having this in Rust makes things a lot more complex.

If you want to share the code you're working on so I can use it to extract test cases to fix please do.

@thlorenz
Copy link
Owner

thlorenz commented Aug 3, 2021

I fixed a lot of field access cases for vecs. Which means a vec attached to a struct like the store can now be sent if the item is a primitive or String as well as the cases that worked before.
If you want to see which specifically, please consult this test.

For exported functions not all of those are supported yet since that is a different case as the returned Vec is no longer accessible from the Rust side and also needs to be cleaned up from Dart.

I'm looking into adding support for HashMap and similar data types yet. In order to address the case you need first could you please provide a small sample of code that you would like to work with Rid @chertov ?

@chertov
Copy link
Collaborator Author

chertov commented Aug 8, 2021

I haven't tried the updated version yet and I don't fully understand the concept of my app using rid. This will change a lot of things in my app.
Initially, I had a Flutter application and only a small part of the cryptography was in Rust. I was sending data from rust to dart via callbacks (ffi, wasm). But now with rid I don't need to implement logic and connections in dart. It looks like in dart, I need to leave only the rendering of the state, and transfer everything else to rust.

My library is used by several applications. It looks like I can't do several different states in the same code right now. With cfg! it is possible with cargo features, but in one application you cannot have several states now.

@thlorenz
Copy link
Owner

See #13 which adds lots more types you can return from an export.
Namely Vec<&u8> is supported as you're expected to hold on to the actual data (the u8s) on the rust side.
LMK if that addressed part of your needs and if not which return type you'd need.

@thlorenz thlorenz added the question Further information is requested label Oct 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants