Closed VladTheJunior closed 1 week ago
That sounds reasonable. Currently, you can utilize https://cjycode.com/flutter_rust_bridge/guides/types/translatable/custom and add a dozen of lines in your code to support that conversion.
I tried to add custom encoder but it fails now, because in frb_generated.rs there are 2 encoders for Ipv4Address:
impl SseEncode for Ipv4Addr {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<RustOpaqueNom<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Ipv4Addr>>>::sse_encode(flutter_rust_bridge::for_generated::rust_auto_opaque_encode::<_, StdArc<_>>(self), serializer);
}
}
...
impl SseEncode for Ipv4Addr {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<String>::sse_encode(crate::api::device::encode_ipv4_type(self), serializer);
}
}
my custom encoder
#[frb(rust2dart(
dart_type = "InternetAddress",
dart_code = "InternetAddress.fromRawAddress({})"
))]
pub fn encode_ipv4_type(raw: Ipv4Addr) -> Vec<u8> {
return raw.octets().to_vec();
}
#[frb(dart2rust(dart_type = "InternetAddress", dart_code = "{}.address"))]
pub fn decode_ipv4_type(raw: String) -> Ipv4Addr {
raw.parse().unwrap()
}
I tried to create sample for you, but it has another error, idk how to fix it
SEVERE: error[E0599]: no method named `into_into_dart` found for struct `Ipv4Addr` in the current scope
SEVERE: error[E0277]: the trait bound `*mut wire_cst_list_prim_u_8_strict: frb_generated::CstDecode<Ipv4Addr>` is not satisfied
SEVERE : error : could not compile `rust_lib_test` (lib) due to 2 previous errors [C:\Users\vladt\Desktop\test\build\windows\x64\plugins\rust_lib_test\rust_lib_test_cargokit.vcxproj]
Hmm, firstly maybe try to let the encode and decode have the same time (currently it is Vec and String in the two scenarios)
In addition, does the demo in the doc work? If so maybe we can try to mimic that demo.
Another possibility is that, maybe Ipv4Addr
is used as both opaque and non-opaque, which confuses frb.
Hmm, firstly maybe try to let the encode and decode have the same time (currently it is Vec and String in the two scenarios)
I used it in test example in my previous comment
Another possibility is that, maybe
Ipv4Addr
is used as both opaque and non-opaque, which confuses frb.
How can I check or fix that
Okay, I will add some summary. After create new frb project, I added these lines to simple.rs
file:
use std::net::Ipv4Addr;
use flutter_rust_bridge::frb;
#[flutter_rust_bridge::frb(sync)] // Synchronous mode for simplicity of the demo
pub fn greet(name: Ipv4Addr) -> String {
format!("Hello, {}!", name.to_string())
}
#[frb(rust2dart(
dart_type = "InternetAddress",
dart_code = "InternetAddress({})"
))]
pub fn encode_ipv4_type(raw: Ipv4Addr) -> String {
return raw.to_string();
}
#[frb(dart2rust(dart_type = "InternetAddress", dart_code = "{}.address"))]
pub fn decode_ipv4_type(raw: String) -> Ipv4Addr {
raw.parse().unwrap()
}
and this to flutter_rust_bridge.yaml
:
rust_preamble: use std::net::Ipv4Addr;
dart_preamble: import 'dart:io';
and in Dart:
greet(name: InternetAddress("10.0.11.1"))
All of this works perfectly. But when I add struct Device with Ipv4Addr field it starts to generate error no method named `into_into_dart` found for struct `Ipv4Addr` in the current scope
#[flutter_rust_bridge::frb(sync)] // Synchronous mode for simplicity of the demo
pub fn greet(name: Device) -> String {
format!("Hello, {}!", name.ip.to_string())
}
pub struct Device{
pub ip: Ipv4Addr
}
greet(name: Device(ip: InternetAddress("10.0.11.1")))
Idk why, but I figured out why it thinks about opaque type. When I add Debug derive to Device struct it becomes autoopaque:
#[derive(Debug)]
pub struct Device{
pub ip: Ipv4Addr
}
But when I add struct Device with Ipv4Addr field it starts to generate error
Also try full_dep: false
in case you are using the dco codec which is not supoorted yet
Also try
full_dep: false
in case you are using the dco codec which is not supoorted yet
I thought full_dep is false by default. When I added full_dep: false
, with enabled Derive(Debug) it stops generate my custom encoders, only autoopaque one.
When Derive(Debug) is removed it still generate error no method named `into_into_dart` found for struct `Ipv4Addr` in the current scope
I updated me test example in this repo: https://github.com/VladTheJunior/test_frb
Why into_into_dart
is not auto generated used by my custom encoder/decoder?
A workaround about the into_into_dart thing before it is fixed/implemented may be that, implement the into_into_dart manually (which only takes a few lines). Another temporary workaround is to change the type used.
implement the into_into_dart manually
What is correct way to do it? I tried
impl flutter_rust_bridge::IntoIntoDart<std::net::Ipv4Addr> for std::net::Ipv4Addr {
fn into_into_dart(self) -> std::net::Ipv4Addr {
self
}
}
but got this:
SEVERE: error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
SEVERE: error[E0277]: the trait bound `allo_isolate::ffi::DartCObject: From<Ipv4Addr>` is not satisfied
Maybe mimic how a third party type (via mirroring) is implemented.
I think it's better to wait fixes/adding Ipv4 by default in frb. Thank you for all responses and your big work on this project
Looks reasonable, and you are welcome
I cannot reproduce the into_into_dart problem. The following code compiles without any issue:
pub fn greet(name: Ipv4Addr) -> String {
unimplemented!()
}
#[frb(rust2dart(dart_type = "InternetAddress", dart_code = "InternetAddress({})"))]
pub fn encode_ipv4_type(raw: Ipv4Addr) -> String {
return raw.to_string();
}
#[frb(dart2rust(dart_type = "InternetAddress", dart_code = "{}.address"))]
pub fn decode_ipv4_type(raw: String) -> Ipv4Addr {
raw.parse().unwrap()
}
On the other hand, for fields inside structs, if a field has custom serialization type, it is not understood. I will fix that now.
EDIT: After fixing that one, the into_into_dart issue finally reproduces. Fix it as well.
I found, that there is no default rust to dart conversion for Network types Such as Ipv4Addr, Ipv6Addr to dart InternetAddressType since frb converts it to opaque struct. Can you add this conversion by default in frb? Rust IpAddr Dart InternetAddressType