From 5ae4e1f1cdb22c7b8fc99c4db472058adbb91847 Mon Sep 17 00:00:00 2001 From: Dirk Van Haerenborgh Date: Fri, 5 Jul 2024 10:47:10 +0200 Subject: [PATCH] wip: parse futures --- .../api_dart/spec_generator/class/ty/mod.rs | 2 + .../generator/api_dart/spec_generator/info.rs | 14 + .../codegen/generator/codec/sse/ty/future.rs | 24 + .../codegen/generator/codec/sse/ty/mod.rs | 2 + .../codegen/generator/codec/sse/ty/pin.rs | 24 + .../src/library/codegen/generator/misc/mod.rs | 2 + .../codegen/generator/misc/structs_macro.rs | 4 + .../codec/cst/encoder/ty/future.rs | 129 ++++ .../codec/cst/encoder/ty/mod.rs | 2 + .../codec/cst/encoder/ty/pin.rs | 129 ++++ .../codec/dco/decoder/ty/future.rs | 38 ++ .../codec/dco/decoder/ty/mod.rs | 2 + .../codec/dco/decoder/ty/pin.rs | 38 ++ .../dart/spec_generator/misc/ty/future.rs | 4 + .../wire/dart/spec_generator/misc/ty/mod.rs | 2 + .../wire/dart/spec_generator/misc/ty/pin.rs | 4 + .../codec/cst/decoder/ty/future.rs | 14 + .../codec/cst/decoder/ty/mod.rs | 2 + .../codec/cst/decoder/ty/pin.rs | 14 + .../codec/dco/encoder/ty/future.rs | 4 + .../codec/dco/encoder/ty/mod.rs | 2 + .../codec/dco/encoder/ty/pin.rs | 4 + .../rust/spec_generator/misc/ty/future.rs | 4 + .../wire/rust/spec_generator/misc/ty/mod.rs | 2 + .../wire/rust/spec_generator/misc/ty/pin.rs | 4 + .../src/library/codegen/ir/mir/ty/future.rs | 59 ++ .../src/library/codegen/ir/mir/ty/mod.rs | 6 + .../src/library/codegen/ir/mir/ty/pin.rs | 59 ++ .../parser/mir/parser/function/real/mod.rs | 7 +- .../parser/mir/parser/function/real/output.rs | 9 + .../codegen/parser/mir/parser/ty/concrete.rs | 16 +- .../codegen/parser/mir/parser/ty/dart_fn.rs | 21 +- .../codegen/parser/mir/parser/ty/future.rs | 64 ++ .../codegen/parser/mir/parser/ty/mod.rs | 1 + .../codegen/parser/mir/parser/ty/optional.rs | 4 +- .../codegen/parser/mir/parser/ty/path.rs | 4 +- .../codegen/parser/mir/parser/ty/path_data.rs | 2 +- .../parser/mir/parser/ty/trait_object.rs | 2 +- .../codegen/parser/mir/parser/ty/ty.rs | 1 + .../lib/src/rust/api/minimal.dart | 27 + .../lib/src/rust/frb_generated.dart | 549 ++++++++++++++++- .../lib/src/rust/frb_generated.io.dart | 228 +++++++ .../lib/src/rust/frb_generated.web.dart | 206 ++++++- .../dart_minimal/rust/src/api/minimal.rs | 45 ++ .../dart_minimal/rust/src/frb_generated.io.rs | 50 ++ .../dart_minimal/rust/src/frb_generated.rs | 558 +++++++++++++++++- .../rust/src/frb_generated.web.rs | 52 ++ 47 files changed, 2426 insertions(+), 14 deletions(-) create mode 100644 frb_codegen/src/library/codegen/generator/codec/sse/ty/future.rs create mode 100644 frb_codegen/src/library/codegen/generator/codec/sse/ty/pin.rs create mode 100644 frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/cst/encoder/ty/future.rs create mode 100644 frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/cst/encoder/ty/pin.rs create mode 100644 frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/dco/decoder/ty/future.rs create mode 100644 frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/dco/decoder/ty/pin.rs create mode 100644 frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/misc/ty/future.rs create mode 100644 frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/misc/ty/pin.rs create mode 100644 frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/cst/decoder/ty/future.rs create mode 100644 frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/cst/decoder/ty/pin.rs create mode 100644 frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/dco/encoder/ty/future.rs create mode 100644 frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/dco/encoder/ty/pin.rs create mode 100644 frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/misc/ty/future.rs create mode 100644 frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/misc/ty/pin.rs create mode 100644 frb_codegen/src/library/codegen/ir/mir/ty/future.rs create mode 100644 frb_codegen/src/library/codegen/ir/mir/ty/pin.rs create mode 100644 frb_codegen/src/library/codegen/parser/mir/parser/ty/future.rs create mode 100644 frb_example/dart_minimal/rust/src/frb_generated.io.rs create mode 100644 frb_example/dart_minimal/rust/src/frb_generated.web.rs diff --git a/frb_codegen/src/library/codegen/generator/api_dart/spec_generator/class/ty/mod.rs b/frb_codegen/src/library/codegen/generator/api_dart/spec_generator/class/ty/mod.rs index ea90a2d02f..c93dd9ed7b 100644 --- a/frb_codegen/src/library/codegen/generator/api_dart/spec_generator/class/ty/mod.rs +++ b/frb_codegen/src/library/codegen/generator/api_dart/spec_generator/class/ty/mod.rs @@ -34,4 +34,6 @@ impl<'a> ApiDartGeneratorClassTrait for OptionalApiDartGenerator<'a> {} impl<'a> ApiDartGeneratorClassTrait for PrimitiveApiDartGenerator<'a> {} impl<'a> ApiDartGeneratorClassTrait for PrimitiveListApiDartGenerator<'a> {} impl<'a> ApiDartGeneratorClassTrait for RecordApiDartGenerator<'a> {} +impl<'a> ApiDartGeneratorClassTrait for FutureApiDartGenerator<'a> {} +impl<'a> ApiDartGeneratorClassTrait for PinApiDartGenerator<'a> {} impl<'a> ApiDartGeneratorClassTrait for RustAutoOpaqueImplicitApiDartGenerator<'a> {} diff --git a/frb_codegen/src/library/codegen/generator/api_dart/spec_generator/info.rs b/frb_codegen/src/library/codegen/generator/api_dart/spec_generator/info.rs index be09bdcde9..facf22d981 100644 --- a/frb_codegen/src/library/codegen/generator/api_dart/spec_generator/info.rs +++ b/frb_codegen/src/library/codegen/generator/api_dart/spec_generator/info.rs @@ -27,6 +27,20 @@ impl<'a> ApiDartGeneratorInfoTrait for BoxedApiDartGenerator<'a> { } } +impl<'a> ApiDartGeneratorInfoTrait for FutureApiDartGenerator<'a> { + fn dart_api_type(&self) -> String { + let inner = ApiDartGenerator::new(self.mir.output.clone(), self.context); + inner.dart_api_type() + } +} + +impl<'a> ApiDartGeneratorInfoTrait for PinApiDartGenerator<'a> { + fn dart_api_type(&self) -> String { + let inner = ApiDartGenerator::new(self.mir.inner.clone(), self.context); + inner.dart_api_type() + } +} + impl<'a> ApiDartGeneratorInfoTrait for DartFnApiDartGenerator<'a> { fn dart_api_type(&self) -> String { format!( diff --git a/frb_codegen/src/library/codegen/generator/codec/sse/ty/future.rs b/frb_codegen/src/library/codegen/generator/codec/sse/ty/future.rs new file mode 100644 index 0000000000..3fabb7935c --- /dev/null +++ b/frb_codegen/src/library/codegen/generator/codec/sse/ty/future.rs @@ -0,0 +1,24 @@ +use crate::codegen::generator::codec::sse::ty::delegate::simple_delegate_encode; +use crate::codegen::generator::codec::sse::ty::*; + +impl<'a> CodecSseTyTrait for FutureCodecSseTy<'a> { + fn generate_encode(&self, lang: &Lang) -> Option { + self.should_generate(lang).then(|| { + simple_delegate_encode( + lang, + &self.mir.get_delegate(), + &format!("encode_{}(self)", self.mir.safe_ident()), + ) + }) + } + + fn generate_decode(&self, _lang: &Lang) -> Option { + None + } +} + +impl<'a> FutureCodecSseTy<'a> { + fn should_generate(&self, lang: &Lang) -> bool { + !matches!(lang, Lang::RustLang(_)) + } +} diff --git a/frb_codegen/src/library/codegen/generator/codec/sse/ty/mod.rs b/frb_codegen/src/library/codegen/generator/codec/sse/ty/mod.rs index 89e3cc9910..67b5b46ba7 100644 --- a/frb_codegen/src/library/codegen/generator/codec/sse/ty/mod.rs +++ b/frb_codegen/src/library/codegen/generator/codec/sse/ty/mod.rs @@ -9,10 +9,12 @@ mod optional; mod primitive; mod primitive_list; mod record; +mod future; pub(crate) mod rust_auto_opaque_implicit; pub(crate) mod rust_opaque; mod structure; mod trait_def; +mod pin; use crate::codegen::generator::api_dart::internal_config::GeneratorApiDartInternalConfig; use crate::codegen::generator::api_dart::spec_generator::base::ApiDartGeneratorContext; diff --git a/frb_codegen/src/library/codegen/generator/codec/sse/ty/pin.rs b/frb_codegen/src/library/codegen/generator/codec/sse/ty/pin.rs new file mode 100644 index 0000000000..d33cf8be6e --- /dev/null +++ b/frb_codegen/src/library/codegen/generator/codec/sse/ty/pin.rs @@ -0,0 +1,24 @@ +use crate::codegen::generator::codec::sse::ty::delegate::simple_delegate_encode; +use crate::codegen::generator::codec::sse::ty::*; + +impl<'a> CodecSseTyTrait for PinCodecSseTy<'a> { + fn generate_encode(&self, lang: &Lang) -> Option { + self.should_generate(lang).then(|| { + simple_delegate_encode( + lang, + &self.mir.get_delegate(), + &format!("encode_{}(self)", self.mir.safe_ident()), + ) + }) + } + + fn generate_decode(&self, _lang: &Lang) -> Option { + None + } +} + +impl<'a> PinCodecSseTy<'a> { + fn should_generate(&self, lang: &Lang) -> bool { + !matches!(lang, Lang::RustLang(_)) + } +} diff --git a/frb_codegen/src/library/codegen/generator/misc/mod.rs b/frb_codegen/src/library/codegen/generator/misc/mod.rs index 19ac5334dc..79e10839fa 100644 --- a/frb_codegen/src/library/codegen/generator/misc/mod.rs +++ b/frb_codegen/src/library/codegen/generator/misc/mod.rs @@ -22,6 +22,8 @@ pub fn is_js_value(ty: &MirType) -> bool { | MirType::Delegate(MirTypeDelegate::RustAutoOpaqueExplicit(_)) | MirType::DartOpaque(_) | MirType::DartFn(_) + | MirType::Future(_) + | MirType::Pin(_) | MirType::Record(_) => true, MirType::Boxed(MirTypeBoxed { inner, .. }) => is_js_value(inner), MirType::Delegate(inner) => is_js_value(&inner.get_delegate()), diff --git a/frb_codegen/src/library/codegen/generator/misc/structs_macro.rs b/frb_codegen/src/library/codegen/generator/misc/structs_macro.rs index 65389b11b1..c4766e8bc7 100644 --- a/frb_codegen/src/library/codegen/generator/misc/structs_macro.rs +++ b/frb_codegen/src/library/codegen/generator/misc/structs_macro.rs @@ -23,6 +23,8 @@ macro_rules! codegen_generator_structs { RustOpaque, StructRef, TraitDef, + Future, + Pin, ); ); (@private $(#[$attribute:meta])* $generator_name:ident ; $($name:ident),*,) => ( @@ -36,12 +38,14 @@ macro_rules! codegen_generator_structs { use $crate::codegen::ir::mir::ty::general_list::MirTypeGeneralList; use $crate::codegen::ir::mir::ty::optional::MirTypeOptional; use $crate::codegen::ir::mir::ty::primitive::MirTypePrimitive; + use $crate::codegen::ir::mir::ty::future::MirTypeFuture; use $crate::codegen::ir::mir::ty::primitive_list::MirTypePrimitiveList; use $crate::codegen::ir::mir::ty::record::MirTypeRecord; use $crate::codegen::ir::mir::ty::rust_auto_opaque_implicit::MirTypeRustAutoOpaqueImplicit; use $crate::codegen::ir::mir::ty::rust_opaque::MirTypeRustOpaque; use $crate::codegen::ir::mir::ty::structure::MirTypeStructRef; use $crate::codegen::ir::mir::ty::trait_def::MirTypeTraitDef; + use $crate::codegen::ir::mir::ty::pin::MirTypePin; use $crate::codegen::ir::mir::ty::MirType; // cargo fix wrongly removes this import #[allow(unused_imports)] diff --git a/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/cst/encoder/ty/future.rs b/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/cst/encoder/ty/future.rs new file mode 100644 index 0000000000..f5f059f0de --- /dev/null +++ b/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/cst/encoder/ty/future.rs @@ -0,0 +1,129 @@ +use crate::codegen::generator::acc::Acc; +use crate::codegen::generator::misc::is_js_value; +use crate::codegen::generator::misc::target::Target; +use crate::codegen::generator::wire::dart::spec_generator::codec::cst::base::*; +use crate::codegen::generator::wire::dart::spec_generator::codec::cst::encoder::ty::primitive::dart_native_type_of_primitive; +use crate::codegen::generator::wire::dart::spec_generator::codec::cst::encoder::ty::WireDartCodecCstGeneratorEncoderTrait; +use crate::codegen::ir::mir::ty::delegate::MirTypeDelegate; +use crate::codegen::ir::mir::ty::MirType::StructRef; +use crate::codegen::ir::mir::ty::{MirType, MirTypeTrait}; + +impl<'a> WireDartCodecCstGeneratorEncoderTrait for FutureWireDartCodecCstGenerator<'a> { + fn generate_encode_func_body(&self) -> Acc> { + let mir_safe_ident = self.mir.safe_ident(); + let inner_safe_ident = self.mir.output.safe_ident(); + let empty_struct = is_empty_struct(self); + + Acc { + io: Some( + if self.mir.output.is_primitive() + || matches!( + *self.mir.output, + MirType::RustOpaque(_) + | MirType::RustAutoOpaqueImplicit(_) + | MirType::Delegate(MirTypeDelegate::RustAutoOpaqueExplicit(_)) + | MirType::DartOpaque(_) + ) + { + format!( + "return wire.cst_new_{mir_safe_ident}(cst_encode_{inner_safe_ident}(raw));" + ) + } else if self.mir.output.is_array() { + format!("return cst_encode_{inner_safe_ident}(raw);") + } else { + format!( + "final ptr = wire.cst_new_{mir_safe_ident}(); + {} + return ptr;", + if empty_struct { + "".to_owned() + } else { + format!("cst_api_fill_to_wire_{inner_safe_ident}(raw, ptr.ref);") + } + ) + }, + ), + web: Some(format!("return cst_encode_{inner_safe_ident}(raw);")), + ..Default::default() + } + } + + fn generate_encode_api_fill_to_wire_body(&self) -> Option { + let inner_safe_ident = self.mir.output.safe_ident(); + + if self.mir.output.is_array() { + Some(format!("wireObj = cst_encode_{inner_safe_ident}(apiObj);")) + } else if !self.mir.output.is_primitive() + && !matches!( + *self.mir.output, + MirType::RustOpaque(_) + | MirType::RustAutoOpaqueImplicit(_) + | MirType::Delegate(MirTypeDelegate::RustAutoOpaqueExplicit(_)) + | MirType::DartOpaque(_) + ) + && !is_empty_struct(self) + { + Some(format!( + "cst_api_fill_to_wire_{inner_safe_ident}(apiObj, wireObj.ref);" + )) + } else { + None + } + } + + fn dart_wire_type(&self, target: Target) -> String { + match target { + Target::Web => { + if is_js_value(&self.mir.output) + || self.mir.output.is_array() + || self.mir.output.is_primitive() + { + WireDartCodecCstGenerator::new(self.mir.output.clone(), self.context) + .dart_wire_type(target) + } else { + // Quick hack to remove seemingly dead code without causing any trouble ;) + + // frb-coverage:ignore-start + unreachable!("Codecov says this branch is never used. If you see this message, please create an issue and let's re-enable the logic here.") + // frb-coverage:ignore-end + + // format!( + // "int /* *{} */", + // WireRustCodecCstGenerator::new( + // self.mir.output.clone(), + // self.context.as_wire_rust_context() + // ) + // .rust_wire_type(target) + // ) + } + } + Target::Io => { + if self.mir.output.is_array() { + return WireDartCodecCstGenerator::new(self.mir.output.clone(), self.context) + .dart_wire_type(Target::Io); + } + let wire_type = self + .mir + .output + .as_primitive() + .map(|prim| dart_native_type_of_primitive(prim).to_owned()) + .unwrap_or_else(|| { + WireDartCodecCstGenerator::new(self.mir.output.clone(), self.context) + .dart_wire_type(target) + }); + format!("ffi.Pointer<{wire_type}>") + } + } + } +} + +// the function signature is not covered while the whole body is covered - looks like a bug in coverage tool +// frb-coverage:ignore-start +fn is_empty_struct(ty: &FutureWireDartCodecCstGenerator) -> bool { + // frb-coverage:ignore-end + if let StructRef(ref s) = ty.mir.output.as_ref() { + s.get(ty.context.mir_pack).fields.is_empty() + } else { + false + } +} diff --git a/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/cst/encoder/ty/mod.rs b/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/cst/encoder/ty/mod.rs index 206ce40513..5f7d7d44c5 100644 --- a/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/cst/encoder/ty/mod.rs +++ b/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/cst/encoder/ty/mod.rs @@ -13,6 +13,8 @@ mod rust_auto_opaque_implicit; mod rust_opaque; mod structure; mod trait_def; +mod future; +mod pin; use crate::codegen::generator::acc::Acc; use crate::codegen::generator::misc::target::Target; diff --git a/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/cst/encoder/ty/pin.rs b/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/cst/encoder/ty/pin.rs new file mode 100644 index 0000000000..a050501cb6 --- /dev/null +++ b/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/cst/encoder/ty/pin.rs @@ -0,0 +1,129 @@ +use crate::codegen::generator::acc::Acc; +use crate::codegen::generator::misc::is_js_value; +use crate::codegen::generator::misc::target::Target; +use crate::codegen::generator::wire::dart::spec_generator::codec::cst::base::*; +use crate::codegen::generator::wire::dart::spec_generator::codec::cst::encoder::ty::primitive::dart_native_type_of_primitive; +use crate::codegen::generator::wire::dart::spec_generator::codec::cst::encoder::ty::WireDartCodecCstGeneratorEncoderTrait; +use crate::codegen::ir::mir::ty::delegate::MirTypeDelegate; +use crate::codegen::ir::mir::ty::MirType::StructRef; +use crate::codegen::ir::mir::ty::{MirType, MirTypeTrait}; + +impl<'a> WireDartCodecCstGeneratorEncoderTrait for PinWireDartCodecCstGenerator<'a> { + fn generate_encode_func_body(&self) -> Acc> { + let mir_safe_ident = self.mir.safe_ident(); + let inner_safe_ident = self.mir.inner.safe_ident(); + let empty_struct = is_empty_struct(self); + + Acc { + io: Some( + if self.mir.inner.is_primitive() + || matches!( + *self.mir.inner, + MirType::RustOpaque(_) + | MirType::RustAutoOpaqueImplicit(_) + | MirType::Delegate(MirTypeDelegate::RustAutoOpaqueExplicit(_)) + | MirType::DartOpaque(_) + ) + { + format!( + "return wire.cst_new_{mir_safe_ident}(cst_encode_{inner_safe_ident}(raw));" + ) + } else if self.mir.inner.is_array() { + format!("return cst_encode_{inner_safe_ident}(raw);") + } else { + format!( + "final ptr = wire.cst_new_{mir_safe_ident}(); + {} + return ptr;", + if empty_struct { + "".to_owned() + } else { + format!("cst_api_fill_to_wire_{inner_safe_ident}(raw, ptr.ref);") + } + ) + }, + ), + web: Some(format!("return cst_encode_{inner_safe_ident}(raw);")), + ..Default::default() + } + } + + fn generate_encode_api_fill_to_wire_body(&self) -> Option { + let inner_safe_ident = self.mir.inner.safe_ident(); + + if self.mir.inner.is_array() { + Some(format!("wireObj = cst_encode_{inner_safe_ident}(apiObj);")) + } else if !self.mir.inner.is_primitive() + && !matches!( + *self.mir.inner, + MirType::RustOpaque(_) + | MirType::RustAutoOpaqueImplicit(_) + | MirType::Delegate(MirTypeDelegate::RustAutoOpaqueExplicit(_)) + | MirType::DartOpaque(_) + ) + && !is_empty_struct(self) + { + Some(format!( + "cst_api_fill_to_wire_{inner_safe_ident}(apiObj, wireObj.ref);" + )) + } else { + None + } + } + + fn dart_wire_type(&self, target: Target) -> String { + match target { + Target::Web => { + if is_js_value(&self.mir.inner) + || self.mir.inner.is_array() + || self.mir.inner.is_primitive() + { + WireDartCodecCstGenerator::new(self.mir.inner.clone(), self.context) + .dart_wire_type(target) + } else { + // Quick hack to remove seemingly dead code without causing any trouble ;) + + // frb-coverage:ignore-start + unreachable!("Codecov says this branch is never used. If you see this message, please create an issue and let's re-enable the logic here.") + // frb-coverage:ignore-end + + // format!( + // "int /* *{} */", + // WireRustCodecCstGenerator::new( + // self.mir.inner.clone(), + // self.context.as_wire_rust_context() + // ) + // .rust_wire_type(target) + // ) + } + } + Target::Io => { + if self.mir.inner.is_array() { + return WireDartCodecCstGenerator::new(self.mir.inner.clone(), self.context) + .dart_wire_type(Target::Io); + } + let wire_type = self + .mir + .inner + .as_primitive() + .map(|prim| dart_native_type_of_primitive(prim).to_owned()) + .unwrap_or_else(|| { + WireDartCodecCstGenerator::new(self.mir.inner.clone(), self.context) + .dart_wire_type(target) + }); + format!("ffi.Pointer<{wire_type}>") + } + } + } +} + +// the function signature is not covered while the whole body is covered - looks like a bug in coverage tool +// frb-coverage:ignore-start +fn is_empty_struct(ty: &PinWireDartCodecCstGenerator) -> bool { + // frb-coverage:ignore-end + if let StructRef(ref s) = ty.mir.inner.as_ref() { + s.get(ty.context.mir_pack).fields.is_empty() + } else { + false + } +} diff --git a/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/dco/decoder/ty/future.rs b/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/dco/decoder/ty/future.rs new file mode 100644 index 0000000000..e2e7edd9c9 --- /dev/null +++ b/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/dco/decoder/ty/future.rs @@ -0,0 +1,38 @@ +use crate::codegen::generator::wire::dart::spec_generator::codec::dco::base::*; +use crate::codegen::generator::wire::dart::spec_generator::codec::dco::decoder::misc::gen_decode_simple_type_cast; +use crate::codegen::generator::wire::dart::spec_generator::codec::dco::decoder::ty::WireDartCodecDcoGeneratorDecoderTrait; +use crate::codegen::ir::mir::ty::delegate::MirTypeDelegate; +use crate::codegen::ir::mir::ty::primitive::MirTypePrimitive; +use crate::codegen::ir::mir::ty::MirType; +use crate::codegen::ir::mir::ty::MirType::*; +use crate::library::codegen::ir::mir::ty::MirTypeTrait; + +impl<'a> WireDartCodecDcoGeneratorDecoderTrait for FutureWireDartCodecDcoGenerator<'a> { + // the function signature is not covered while the whole body is covered - looks like a bug in coverage tool + // frb-coverage:ignore-start + fn generate_impl_decode_body(&self) -> String { + // frb-coverage:ignore-end + match &*self.mir.output { + StructRef(_) + | DartOpaque(_) + | RustOpaque(_) + | MirType::Delegate(MirTypeDelegate::RustAutoOpaqueExplicit(_)) + | RustAutoOpaqueImplicit(_) + | EnumRef(_) + | Primitive( + MirTypePrimitive::I64 + | MirTypePrimitive::Isize + | MirTypePrimitive::U64 + | MirTypePrimitive::Usize, + ) + | Delegate(MirTypeDelegate::Array(_) | MirTypeDelegate::PrimitiveEnum { .. }) => { + format!("return dco_decode_{}(raw);", self.mir.output.safe_ident()) + } + // TODO merge with above + Delegate(MirTypeDelegate::Time(time)) => { + format!("return dco_decode_Chrono_{}(raw);", time) + } + _ => gen_decode_simple_type_cast(self.mir.clone().into(), self.context), + } + } +} diff --git a/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/dco/decoder/ty/mod.rs b/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/dco/decoder/ty/mod.rs index 9d11ed442f..a825f6e5ea 100644 --- a/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/dco/decoder/ty/mod.rs +++ b/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/dco/decoder/ty/mod.rs @@ -13,6 +13,8 @@ mod rust_auto_opaque_implicit; mod rust_opaque; mod structure; mod trait_def; +mod future; +mod pin; use crate::codegen::generator::wire::dart::spec_generator::codec::dco::base::*; use enum_dispatch::enum_dispatch; diff --git a/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/dco/decoder/ty/pin.rs b/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/dco/decoder/ty/pin.rs new file mode 100644 index 0000000000..3649219dfa --- /dev/null +++ b/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/codec/dco/decoder/ty/pin.rs @@ -0,0 +1,38 @@ +use crate::codegen::generator::wire::dart::spec_generator::codec::dco::base::*; +use crate::codegen::generator::wire::dart::spec_generator::codec::dco::decoder::misc::gen_decode_simple_type_cast; +use crate::codegen::generator::wire::dart::spec_generator::codec::dco::decoder::ty::WireDartCodecDcoGeneratorDecoderTrait; +use crate::codegen::ir::mir::ty::delegate::MirTypeDelegate; +use crate::codegen::ir::mir::ty::primitive::MirTypePrimitive; +use crate::codegen::ir::mir::ty::MirType; +use crate::codegen::ir::mir::ty::MirType::*; +use crate::library::codegen::ir::mir::ty::MirTypeTrait; + +impl<'a> WireDartCodecDcoGeneratorDecoderTrait for PinWireDartCodecDcoGenerator<'a> { + // the function signature is not covered while the whole body is covered - looks like a bug in coverage tool + // frb-coverage:ignore-start + fn generate_impl_decode_body(&self) -> String { + // frb-coverage:ignore-end + match &*self.mir.inner { + StructRef(_) + | DartOpaque(_) + | RustOpaque(_) + | MirType::Delegate(MirTypeDelegate::RustAutoOpaqueExplicit(_)) + | RustAutoOpaqueImplicit(_) + | EnumRef(_) + | Primitive( + MirTypePrimitive::I64 + | MirTypePrimitive::Isize + | MirTypePrimitive::U64 + | MirTypePrimitive::Usize, + ) + | Delegate(MirTypeDelegate::Array(_) | MirTypeDelegate::PrimitiveEnum { .. }) => { + format!("return dco_decode_{}(raw);", self.mir.inner.safe_ident()) + } + // TODO merge with above + Delegate(MirTypeDelegate::Time(time)) => { + format!("return dco_decode_Chrono_{}(raw);", time) + } + _ => gen_decode_simple_type_cast(self.mir.clone().into(), self.context), + } + } +} diff --git a/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/misc/ty/future.rs b/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/misc/ty/future.rs new file mode 100644 index 0000000000..8ab04573b1 --- /dev/null +++ b/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/misc/ty/future.rs @@ -0,0 +1,4 @@ +use crate::codegen::generator::wire::dart::spec_generator::base::*; +use crate::codegen::generator::wire::dart::spec_generator::misc::ty::WireDartGeneratorMiscTrait; + +impl<'a> WireDartGeneratorMiscTrait for FutureWireDartGenerator<'a> {} diff --git a/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/misc/ty/mod.rs b/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/misc/ty/mod.rs index 3f931fd555..ed5cccc959 100644 --- a/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/misc/ty/mod.rs +++ b/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/misc/ty/mod.rs @@ -15,6 +15,8 @@ mod rust_auto_opaque_implicit; mod rust_opaque; mod structure; mod trait_def; +mod future; +mod pin; use crate::codegen::generator::acc::Acc; use crate::codegen::generator::wire::dart::spec_generator::output_code::WireDartOutputCode; diff --git a/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/misc/ty/pin.rs b/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/misc/ty/pin.rs new file mode 100644 index 0000000000..b15d1a631f --- /dev/null +++ b/frb_codegen/src/library/codegen/generator/wire/dart/spec_generator/misc/ty/pin.rs @@ -0,0 +1,4 @@ +use crate::codegen::generator::wire::dart::spec_generator::base::*; +use crate::codegen::generator::wire::dart::spec_generator::misc::ty::WireDartGeneratorMiscTrait; + +impl<'a> WireDartGeneratorMiscTrait for PinWireDartGenerator<'a> {} diff --git a/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/cst/decoder/ty/future.rs b/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/cst/decoder/ty/future.rs new file mode 100644 index 0000000000..621b2ab5af --- /dev/null +++ b/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/cst/decoder/ty/future.rs @@ -0,0 +1,14 @@ +use crate::codegen::generator::misc::target::Target; +use crate::codegen::generator::wire::rust::spec_generator::codec::cst::base::*; +use crate::codegen::generator::wire::rust::spec_generator::codec::cst::decoder::ty::WireRustCodecCstGeneratorDecoderTrait; +use crate::codegen::ir::mir::ty::MirTypeTrait; + +impl<'a> WireRustCodecCstGeneratorDecoderTrait for FutureWireRustCodecCstGenerator<'a> { + fn generate_wire_func_param_api_type(&self) -> Option { + Some(self.mir.get_delegate().rust_api_type()) + } + + fn rust_wire_type(&self, target: Target) -> String { + WireRustCodecCstGenerator::new(self.mir.get_delegate(), self.context).rust_wire_type(target) + } +} diff --git a/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/cst/decoder/ty/mod.rs b/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/cst/decoder/ty/mod.rs index 6b8a71ca45..9e4539d69f 100644 --- a/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/cst/decoder/ty/mod.rs +++ b/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/cst/decoder/ty/mod.rs @@ -13,6 +13,8 @@ mod rust_auto_opaque_implicit; mod rust_opaque; mod structure; mod trait_def; +mod future; +mod pin; use crate::codegen::generator::acc::Acc; use crate::codegen::generator::misc::target::Target; diff --git a/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/cst/decoder/ty/pin.rs b/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/cst/decoder/ty/pin.rs new file mode 100644 index 0000000000..cbd2f324e4 --- /dev/null +++ b/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/cst/decoder/ty/pin.rs @@ -0,0 +1,14 @@ +use crate::codegen::generator::misc::target::Target; +use crate::codegen::generator::wire::rust::spec_generator::codec::cst::base::*; +use crate::codegen::generator::wire::rust::spec_generator::codec::cst::decoder::ty::WireRustCodecCstGeneratorDecoderTrait; +use crate::codegen::ir::mir::ty::MirTypeTrait; + +impl<'a> WireRustCodecCstGeneratorDecoderTrait for PinWireRustCodecCstGenerator<'a> { + fn generate_wire_func_param_api_type(&self) -> Option { + Some(self.mir.get_delegate().rust_api_type()) + } + + fn rust_wire_type(&self, target: Target) -> String { + WireRustCodecCstGenerator::new(self.mir.get_delegate(), self.context).rust_wire_type(target) + } +} diff --git a/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/dco/encoder/ty/future.rs b/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/dco/encoder/ty/future.rs new file mode 100644 index 0000000000..cc95be8e26 --- /dev/null +++ b/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/dco/encoder/ty/future.rs @@ -0,0 +1,4 @@ +use crate::codegen::generator::wire::rust::spec_generator::codec::dco::base::*; +use crate::codegen::generator::wire::rust::spec_generator::codec::dco::encoder::ty::WireRustCodecDcoGeneratorEncoderTrait; + +impl<'a> WireRustCodecDcoGeneratorEncoderTrait for FutureWireRustCodecDcoGenerator<'a> {} diff --git a/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/dco/encoder/ty/mod.rs b/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/dco/encoder/ty/mod.rs index 5e3f1d6269..8109479c82 100644 --- a/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/dco/encoder/ty/mod.rs +++ b/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/dco/encoder/ty/mod.rs @@ -13,6 +13,8 @@ mod rust_auto_opaque_implicit; mod rust_opaque; mod structure; mod trait_def; +mod future; +mod pin; use crate::codegen::generator::wire::rust::spec_generator::codec::dco::base::*; use enum_dispatch::enum_dispatch; diff --git a/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/dco/encoder/ty/pin.rs b/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/dco/encoder/ty/pin.rs new file mode 100644 index 0000000000..1d2eb6e601 --- /dev/null +++ b/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/codec/dco/encoder/ty/pin.rs @@ -0,0 +1,4 @@ +use crate::codegen::generator::wire::rust::spec_generator::codec::dco::base::*; +use crate::codegen::generator::wire::rust::spec_generator::codec::dco::encoder::ty::WireRustCodecDcoGeneratorEncoderTrait; + +impl<'a> WireRustCodecDcoGeneratorEncoderTrait for PinWireRustCodecDcoGenerator<'a> {} diff --git a/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/misc/ty/future.rs b/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/misc/ty/future.rs new file mode 100644 index 0000000000..9b4b4b9d5d --- /dev/null +++ b/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/misc/ty/future.rs @@ -0,0 +1,4 @@ +use crate::codegen::generator::wire::rust::spec_generator::base::*; +use crate::codegen::generator::wire::rust::spec_generator::misc::ty::WireRustGeneratorMiscTrait; + +impl<'a> WireRustGeneratorMiscTrait for FutureWireRustGenerator<'a> {} diff --git a/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/misc/ty/mod.rs b/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/misc/ty/mod.rs index fe5231dfd4..ac1c9cce5d 100644 --- a/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/misc/ty/mod.rs +++ b/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/misc/ty/mod.rs @@ -15,6 +15,8 @@ mod rust_auto_opaque_implicit; mod rust_opaque; mod structure; mod trait_def; +mod future; +mod pin; use crate::codegen::generator::acc::Acc; use crate::codegen::generator::wire::rust::spec_generator::output_code::WireRustOutputCode; diff --git a/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/misc/ty/pin.rs b/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/misc/ty/pin.rs new file mode 100644 index 0000000000..acb0da874e --- /dev/null +++ b/frb_codegen/src/library/codegen/generator/wire/rust/spec_generator/misc/ty/pin.rs @@ -0,0 +1,4 @@ +use crate::codegen::generator::wire::rust::spec_generator::base::*; +use crate::codegen::generator::wire::rust::spec_generator::misc::ty::WireRustGeneratorMiscTrait; + +impl<'a> WireRustGeneratorMiscTrait for PinWireRustGenerator<'a> {} diff --git a/frb_codegen/src/library/codegen/ir/mir/ty/future.rs b/frb_codegen/src/library/codegen/ir/mir/ty/future.rs new file mode 100644 index 0000000000..c030a06fa0 --- /dev/null +++ b/frb_codegen/src/library/codegen/ir/mir/ty/future.rs @@ -0,0 +1,59 @@ +use crate::codegen::ir::mir::ty::{MirContext, MirType, MirTypeTrait}; +use crate::codegen::ir::mir::ty::boxed::MirTypeBoxed; +use crate::codegen::ir::mir::ty::MirType::Boxed; + +crate::mir! { +pub struct MirTypeFuture { + pub output: Box, +} +} + + +impl MirTypeTrait for MirTypeFuture { + fn visit_children_types bool>( + &self, + f: &mut F, + mir_context: &impl MirContext, + ) { + self.output.visit_types(f, mir_context); + } + + fn safe_ident(&self) -> String { + format!("fut_{}", self.output.safe_ident()) + } + + fn rust_api_type(&self) -> String { + format!("impl Future<{}>", self.output.rust_api_type()) + } + + fn cloned_getter_semantics_reasonable(&self) -> bool { + self.output.cloned_getter_semantics_reasonable() + } +} + +impl MirTypeFuture { + pub(crate) fn new(output: MirType) -> Self { + Self { + output: Box::new(output), + } + } + + pub(crate) fn get_delegate(&self) -> MirType { + self.output.clone().into() + } + + pub(crate) fn new_with_boxed_wrapper(output: MirType) -> Self { + Self::new(Boxed(MirTypeBoxed { + exist_in_real_api: false, + inner: Box::new(output), + })) + } + + pub(crate) fn is_primitive(&self) -> bool { + matches!(&*self.output, Boxed(boxed) if !boxed.exist_in_real_api && boxed.inner.is_primitive()) + } + + pub(crate) fn is_boxed_primitive(&self) -> bool { + matches!(&*self.output, Boxed(boxed) if boxed.exist_in_real_api && boxed.inner.is_primitive()) + } +} diff --git a/frb_codegen/src/library/codegen/ir/mir/ty/mod.rs b/frb_codegen/src/library/codegen/ir/mir/ty/mod.rs index 815e12e81d..3796f94c53 100644 --- a/frb_codegen/src/library/codegen/ir/mir/ty/mod.rs +++ b/frb_codegen/src/library/codegen/ir/mir/ty/mod.rs @@ -13,6 +13,8 @@ pub(crate) mod rust_auto_opaque_implicit; pub(crate) mod rust_opaque; pub(crate) mod structure; pub(crate) mod trait_def; +pub(crate) mod future; +pub(crate) mod pin; use crate::codegen::ir::mir::pack::{MirEnumPool, MirPack, MirStructPool}; use crate::codegen::ir::mir::ty::delegate::MirTypeDelegate; @@ -30,6 +32,8 @@ pub enum MirType { // alphabetical order Boxed(boxed::MirTypeBoxed), DartFn(dart_fn::MirTypeDartFn), + Future(future::MirTypeFuture), + Pin(pin::MirTypePin), DartOpaque(dart_opaque::MirTypeDartOpaque), Delegate(delegate::MirTypeDelegate), Dynamic(dynamic::MirTypeDynamic), @@ -139,11 +143,13 @@ impl Serialize for MirType { match self { MirType::Boxed(inner) => ser::(&mut state, "Boxed", inner), MirType::DartFn(inner) => ser::(&mut state, "DartFn", inner), + MirType::Future(inner) => ser::(&mut state, "Future", inner), MirType::DartOpaque(inner) => ser::(&mut state, "DartOpaque", inner), MirType::Delegate(inner) => ser::(&mut state, "Delegate", inner), MirType::Dynamic(inner) => ser::(&mut state, "Dynamic", inner), MirType::EnumRef(inner) => ser::(&mut state, "EnumRef", inner), MirType::GeneralList(inner) => ser::(&mut state, "GeneralList", inner), + MirType::Pin(inner) => ser::(&mut state, "Pin", inner), MirType::Optional(inner) => ser::(&mut state, "Optional", inner), MirType::Primitive(inner) => ser::(&mut state, "Primitive", inner), MirType::PrimitiveList(inner) => ser::(&mut state, "PrimitiveList", inner), diff --git a/frb_codegen/src/library/codegen/ir/mir/ty/pin.rs b/frb_codegen/src/library/codegen/ir/mir/ty/pin.rs new file mode 100644 index 0000000000..922e2784c8 --- /dev/null +++ b/frb_codegen/src/library/codegen/ir/mir/ty/pin.rs @@ -0,0 +1,59 @@ +use crate::codegen::ir::mir::ty::{MirContext, MirType, MirTypeTrait}; +use crate::codegen::ir::mir::ty::boxed::MirTypeBoxed; +use crate::codegen::ir::mir::ty::MirType::Boxed; + +crate::mir! { +pub struct MirTypePin { + pub inner: Box, +} +} + + +impl MirTypeTrait for MirTypePin { + fn visit_children_types bool>( + &self, + f: &mut F, + mir_context: &impl MirContext, + ) { + self.inner.visit_types(f, mir_context); + } + + fn safe_ident(&self) -> String { + format!("pin_{}", self.inner.safe_ident()) + } + + fn rust_api_type(&self) -> String { + format!("Pin<{}>", self.inner.rust_api_type()) + } + + fn cloned_getter_semantics_reasonable(&self) -> bool { + self.inner.cloned_getter_semantics_reasonable() + } +} + +impl MirTypePin { + pub(crate) fn new(inner: MirType) -> Self { + Self { + inner: Box::new(inner), + } + } + + pub(crate) fn get_delegate(&self) -> MirType { + self.inner.clone().into() + } + + pub(crate) fn new_with_boxed_wrapper(inner: MirType) -> Self { + Self::new(Boxed(MirTypeBoxed { + exist_in_real_api: false, + inner: Box::new(inner), + })) + } + + pub(crate) fn is_primitive(&self) -> bool { + matches!(&*self.inner, Boxed(boxed) if !boxed.exist_in_real_api && boxed.inner.is_primitive()) + } + + pub(crate) fn is_boxed_primitive(&self) -> bool { + matches!(&*self.inner, Boxed(boxed) if boxed.exist_in_real_api && boxed.inner.is_primitive()) + } +} diff --git a/frb_codegen/src/library/codegen/parser/mir/parser/function/real/mod.rs b/frb_codegen/src/library/codegen/parser/mir/parser/function/real/mod.rs index 30af903541..69bf1bf5e8 100644 --- a/frb_codegen/src/library/codegen/parser/mir/parser/function/real/mod.rs +++ b/frb_codegen/src/library/codegen/parser/mir/parser/function/real/mod.rs @@ -136,6 +136,7 @@ impl<'a, 'b> FunctionParser<'a, 'b> { default_dart_async: bool, parse_mode: ParseMode, ) -> anyhow::Result { + let func_name = func.item_fn.name(); debug!("parse_function function name: {:?}", func.item_fn.name()); if func.is_public() == Some(false) { @@ -241,6 +242,8 @@ impl<'a, 'b> FunctionParser<'a, 'b> { return Ok(create_output_skip(func, ignore_func)); } + let rust_async = info.is_async || func.item_fn.sig().asyncness.is_some(); + Ok(IrValueOrSkip::Value(MirFunc { name: NamespacedName::new(namespace_refined, func_name), dart_name, @@ -250,7 +253,7 @@ impl<'a, 'b> FunctionParser<'a, 'b> { owner, mode, stream_dart_await, - rust_async: func.item_fn.sig().asyncness.is_some(), + rust_async, initializer: attributes.init(), accessor, arg_mode: if attributes.positional() { @@ -311,6 +314,7 @@ pub(crate) fn parse_effective_function_name_of_method(method: &MirFuncOwnerInfoM #[derive(Debug, Default)] struct FunctionPartialInfo { + is_async: bool, inputs: Vec, ok_output: Option, error_output: Option, @@ -321,6 +325,7 @@ struct FunctionPartialInfo { impl FunctionPartialInfo { fn merge(self, other: Self) -> anyhow::Result { Ok(Self { + is_async: self.is_async || other.is_async, inputs: concat([self.inputs, other.inputs]), ok_output: merge_option(self.ok_output, other.ok_output).context("ok_output type")?, error_output: merge_option(self.error_output, other.error_output) diff --git a/frb_codegen/src/library/codegen/parser/mir/parser/function/real/output.rs b/frb_codegen/src/library/codegen/parser/mir/parser/function/real/output.rs index 5ba14bcf47..4655acc0f7 100644 --- a/frb_codegen/src/library/codegen/parser/mir/parser/function/real/output.rs +++ b/frb_codegen/src/library/codegen/parser/mir/parser/function/real/output.rs @@ -38,11 +38,19 @@ impl<'a, 'b> FunctionParser<'a, 'b> { attributes: &FrbAttributes, ) -> anyhow::Result { let mir = self.type_parser.parse_type(ty, context)?; + + let (mir, is_async) = if let MirType::Future(mir_future) = &mir { + (*mir_future.output.clone(), true) + } else { + (mir, false) + }; + let mir = parse_maybe_proxy_return_type(mir, owner, attributes)?; let info = parse_type_maybe_result(&mir, self.type_parser, context)?; Ok(FunctionPartialInfo { ok_output: Some(info.ok_output), error_output: info.error_output, + is_async, ..Default::default() }) } @@ -116,6 +124,7 @@ fn parse_proxy_return_type(mir: MirType, owner: &MirFuncOwnerInfo) -> anyhow::Re } } } + // This will stop the whole generator and tell the users, so we do not care about testing it // frb-coverage:ignore-start bail!("This return type is not currently compatible with `#[frb(proxy)]` yet") diff --git a/frb_codegen/src/library/codegen/parser/mir/parser/ty/concrete.rs b/frb_codegen/src/library/codegen/parser/mir/parser/ty/concrete.rs index 3c7219d9d3..a1ae6c7df9 100644 --- a/frb_codegen/src/library/codegen/parser/mir/parser/ty/concrete.rs +++ b/frb_codegen/src/library/codegen/parser/mir/parser/ty/concrete.rs @@ -8,8 +8,9 @@ use crate::codegen::ir::mir::ty::delegate::{ }; use crate::codegen::ir::mir::ty::dynamic::MirTypeDynamic; use crate::codegen::ir::mir::ty::general_list::mir_list; +use crate::codegen::ir::mir::ty::pin::MirTypePin; use crate::codegen::ir::mir::ty::MirType; -use crate::codegen::ir::mir::ty::MirType::{Boxed, DartOpaque, Delegate, Dynamic}; +use crate::codegen::ir::mir::ty::MirType::{Boxed, DartOpaque, Delegate, Dynamic, Pin}; use crate::codegen::parser::mir::parser::ty::path_data::extract_path_data; use crate::codegen::parser::mir::parser::ty::unencodable::{splay_segments, SplayedSegment}; use crate::codegen::parser::mir::parser::ty::TypeParserWithContext; @@ -54,6 +55,19 @@ impl<'a, 'b, 'c> TypeParserWithContext<'a, 'b, 'c> { // ) => Delegate(MirTypeDelegate::ZeroCopyBufferVecPrimitive( // primitive.clone(), // )), + ("Pin", [inner]) => { + let inner = self.parse_type(inner)?; + match inner { + MirType::RustAutoOpaqueImplicit(ty_raw) => self.transform_rust_auto_opaque( + &ty_raw, + |raw| format!("Pin<{raw}>"), + )?, + _ => Pin(MirTypePin { + inner: Box::new(inner), + }) + } + }, + ("Box", [inner]) => { let inner = self.parse_type(inner)?; diff --git a/frb_codegen/src/library/codegen/parser/mir/parser/ty/dart_fn.rs b/frb_codegen/src/library/codegen/parser/mir/parser/ty/dart_fn.rs index d47a5cb8b1..7e26f5206f 100644 --- a/frb_codegen/src/library/codegen/parser/mir/parser/ty/dart_fn.rs +++ b/frb_codegen/src/library/codegen/parser/mir/parser/ty/dart_fn.rs @@ -1,7 +1,9 @@ use crate::codegen::ir::mir::ty::dart_fn::MirDartFnOutput; use crate::codegen::ir::mir::ty::dart_fn::MirTypeDartFn; use crate::codegen::ir::mir::ty::delegate::MirTypeDelegate; +use crate::codegen::ir::mir::ty::future::MirTypeFuture; use crate::codegen::ir::mir::ty::MirType; +use crate::codegen::parser::mir::parser::ty::path_data::parse_angle_bracketed_generic_arguments; use crate::codegen::parser::mir::parser::ty::result::{parse_type_maybe_result, ResultTypeInfo}; use crate::codegen::parser::mir::parser::ty::TypeParserWithContext; use crate::if_then_some; @@ -29,7 +31,11 @@ impl<'a, 'b, 'c> TypeParserWithContext<'a, 'b, 'c> { match &segment_ident[..] { // TODO Currently, we treat `FnOnce` same as `Fn`, // but in the future we can optimize this because we no longer need Arc or Clone for this case. - "FnOnce" | "Fn" => {} // Ok + "FnOnce" | "Fn" => {}, // Ok + + // When the return type is an `impl Future`, we have to fetch the `Output` type and mark the function as `async` + "Future" => {} // Ok + // This will stop the whole generator and tell the users, so we do not care about testing it // frb-coverage:ignore-start _ => bail!("Unknown ident: {segment_ident}"), @@ -56,6 +62,18 @@ impl<'a, 'b, 'c> TypeParserWithContext<'a, 'b, 'c> { // frb-coverage:ignore-start } + if let PathArguments::AngleBracketed(arguments) = &segment.arguments { + // Since Fn/FnOnce are handled by `Parenthesized`, here we can assume the bracketed type is indeed a `Future`, and + // we can safely grab the `Output=` associated type. There should be only one. + + let output = match arguments.args.first() { + Some( GenericArgument::AssocType(assoc_ty)) => self.parse_type(&assoc_ty.ty).context("cannot parse future output type"), + _ => bail!("Unknown type args for: {segment_ident}"), + }?; + + return Ok(MirType::Future(MirTypeFuture{ output: Box::new(output) })); + } + bail!("Fail to parse DartFn") // frb-coverage:ignore-end } @@ -91,6 +109,7 @@ impl<'a, 'b, 'c> TypeParserWithContext<'a, 'b, 'c> { bail!("DartFn does not support return types except `DartFnFuture` yet") // frb-coverage:ignore-end } + } const FALLBACK_ERROR_TYPE: MirType = MirType::Delegate(MirTypeDelegate::AnyhowException); diff --git a/frb_codegen/src/library/codegen/parser/mir/parser/ty/future.rs b/frb_codegen/src/library/codegen/parser/mir/parser/ty/future.rs new file mode 100644 index 0000000000..c19023c08e --- /dev/null +++ b/frb_codegen/src/library/codegen/parser/mir/parser/ty/future.rs @@ -0,0 +1,64 @@ +use crate::codegen::ir::mir::ty::delegate::MirTypeDelegate; +use crate::codegen::ir::mir::ty::future::MirTypeFuture; +use crate::codegen::ir::mir::ty::MirType; +use crate::codegen::ir::mir::ty::MirType::{ + Boxed, DartFn, DartOpaque, Delegate, Dynamic, EnumRef, GeneralList, Optional, Primitive, + PrimitiveList, Record, RustAutoOpaqueImplicit, RustOpaque, StructRef, Future, Pin, +}; +use crate::codegen::parser::mir::parser::ty::unencodable::SplayedSegment; +use crate::codegen::parser::mir::parser::ty::TypeParserWithContext; +use anyhow::ensure; +use quote::ToTokens; +use syn::TypePath; + +impl<'a, 'b, 'c> TypeParserWithContext<'a, 'b, 'c> { + pub(crate) fn parse_type_path_data_future( + &mut self, + type_path: &TypePath, + last_segment: &SplayedSegment, + ) -> anyhow::Result> { + Ok(Some(match last_segment { + ("DartFnFuture", [inner]) => { + let inner = self.parse_type(inner)?; + + // This will stop the whole generator and tell the users, so we do not care about testing it + // frb-coverage:ignore-start + ensure!( + !matches!(inner, Future(_)), + "Nested futures without indirection are not supported. {}", + type_path.to_token_stream() + ); + // frb-coverage:ignore-end + + Future(match inner { + StructRef(..) + | EnumRef(..) + | RustAutoOpaqueImplicit(..) + | RustOpaque(..) + | DartOpaque(..) + | DartFn(..) + | Primitive(..) + | Record(..) + | Optional(..) + | Pin(..) + | Delegate(MirTypeDelegate::PrimitiveEnum(..)) => { + MirTypeFuture::new_with_boxed_wrapper(inner.clone()) + } + Delegate(MirTypeDelegate::Time(..)) => { + MirTypeFuture::new_with_boxed_wrapper(inner.clone()) + } + PrimitiveList(_) | GeneralList(_) | Boxed(_) | Dynamic(_) | Delegate(_) => { + MirTypeFuture::new(inner.clone()) + } + // frb-coverage:ignore-start + Future(_) | MirType::TraitDef(_) => unreachable!(), + // frb-coverage:ignore-end + }) + } + + // TODO: parse pin> here? + + _ => return Ok(None), + })) + } +} diff --git a/frb_codegen/src/library/codegen/parser/mir/parser/ty/mod.rs b/frb_codegen/src/library/codegen/parser/mir/parser/ty/mod.rs index d51bfb5582..12ed9997bd 100644 --- a/frb_codegen/src/library/codegen/parser/mir/parser/ty/mod.rs +++ b/frb_codegen/src/library/codegen/parser/mir/parser/ty/mod.rs @@ -37,6 +37,7 @@ pub(crate) mod lifetimeable; pub(crate) mod misc; mod namespace; pub(crate) mod optional; +pub(crate) mod future; pub(crate) mod path; pub(crate) mod path_data; pub(crate) mod primitive; diff --git a/frb_codegen/src/library/codegen/parser/mir/parser/ty/optional.rs b/frb_codegen/src/library/codegen/parser/mir/parser/ty/optional.rs index 40818bcd0b..3a97e0b282 100644 --- a/frb_codegen/src/library/codegen/parser/mir/parser/ty/optional.rs +++ b/frb_codegen/src/library/codegen/parser/mir/parser/ty/optional.rs @@ -3,7 +3,7 @@ use crate::codegen::ir::mir::ty::optional::MirTypeOptional; use crate::codegen::ir::mir::ty::MirType; use crate::codegen::ir::mir::ty::MirType::{ Boxed, DartFn, DartOpaque, Delegate, Dynamic, EnumRef, GeneralList, Optional, Primitive, - PrimitiveList, Record, RustAutoOpaqueImplicit, RustOpaque, StructRef, + PrimitiveList, Record, RustAutoOpaqueImplicit, RustOpaque, StructRef, Future, Pin, }; use crate::codegen::parser::mir::parser::ty::unencodable::SplayedSegment; use crate::codegen::parser::mir::parser::ty::TypeParserWithContext; @@ -37,7 +37,9 @@ impl<'a, 'b, 'c> TypeParserWithContext<'a, 'b, 'c> { | RustOpaque(..) | DartOpaque(..) | DartFn(..) + | Future(..) | Primitive(..) + | Pin(..) | Record(..) | Delegate(MirTypeDelegate::PrimitiveEnum(..)) => { MirTypeOptional::new_with_boxed_wrapper(inner.clone()) diff --git a/frb_codegen/src/library/codegen/parser/mir/parser/ty/path.rs b/frb_codegen/src/library/codegen/parser/mir/parser/ty/path.rs index e243c6e948..668490d62f 100644 --- a/frb_codegen/src/library/codegen/parser/mir/parser/ty/path.rs +++ b/frb_codegen/src/library/codegen/parser/mir/parser/ty/path.rs @@ -62,7 +62,9 @@ impl<'a, 'b, 'c> TypeParserWithContext<'a, 'b, 'c> { if let Some(ans) = self.parse_type_path_data_optional(type_path, last_segment)? { return Ok(ans); } - + if let Some(ans) = self.parse_type_path_data_future(type_path, last_segment)? { + return Ok(ans); + } // this bracket is weirdly not covered, while everything else is // frb-coverage:ignore-start } diff --git a/frb_codegen/src/library/codegen/parser/mir/parser/ty/path_data.rs b/frb_codegen/src/library/codegen/parser/mir/parser/ty/path_data.rs index a2f0c11a2c..3d6164f556 100644 --- a/frb_codegen/src/library/codegen/parser/mir/parser/ty/path_data.rs +++ b/frb_codegen/src/library/codegen/parser/mir/parser/ty/path_data.rs @@ -37,7 +37,7 @@ fn parse_path_segment(segment: &PathSegment) -> Result { Ok(NameComponent { ident, args }) } -fn parse_angle_bracketed_generic_arguments(args: &AngleBracketedGenericArguments) -> Vec { +pub fn parse_angle_bracketed_generic_arguments(args: &AngleBracketedGenericArguments) -> Vec { args.args .iter() .filter_map(|arg| if_then_some!(let GenericArgument::Type(ty) = arg, ty.to_owned())) diff --git a/frb_codegen/src/library/codegen/parser/mir/parser/ty/trait_object.rs b/frb_codegen/src/library/codegen/parser/mir/parser/ty/trait_object.rs index f7b267e36a..3d3118a374 100644 --- a/frb_codegen/src/library/codegen/parser/mir/parser/ty/trait_object.rs +++ b/frb_codegen/src/library/codegen/parser/mir/parser/ty/trait_object.rs @@ -67,7 +67,7 @@ impl<'a, 'b, 'c> TypeParserWithContext<'a, 'b, 'c> { fn extract_trait_name_path(type_trait_object: &TypeTraitObject) -> Option { let bounds = &type_trait_object.bounds; - if bounds.len() != 1 { + if bounds.len() < 1 { return None; } diff --git a/frb_codegen/src/library/codegen/parser/mir/parser/ty/ty.rs b/frb_codegen/src/library/codegen/parser/mir/parser/ty/ty.rs index 64a7628930..e81b950cd2 100644 --- a/frb_codegen/src/library/codegen/parser/mir/parser/ty/ty.rs +++ b/frb_codegen/src/library/codegen/parser/mir/parser/ty/ty.rs @@ -7,6 +7,7 @@ use syn::Type; impl<'a, 'b, 'c> TypeParserWithContext<'a, 'b, 'c> { pub(crate) fn parse_type(&mut self, ty: &Type) -> anyhow::Result { + let tystr = ty_to_string(ty); let resolve_ty = self.resolve_alias(ty); let ans = self.parse_type_inner(&resolve_ty)?; log::debug!( diff --git a/frb_example/dart_minimal/lib/src/rust/api/minimal.dart b/frb_example/dart_minimal/lib/src/rust/api/minimal.dart index db2ee24315..87386a45d7 100644 --- a/frb_example/dart_minimal/lib/src/rust/api/minimal.dart +++ b/frb_example/dart_minimal/lib/src/rust/api/minimal.dart @@ -8,3 +8,30 @@ import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart'; Future minimalAdder({required int a, required int b}) => RustLib.instance.api.crateApiMinimalMinimalAdder(a: a, b: b); + +// Rust type: RustOpaqueMoi> +abstract class MyStruct implements RustOpaqueInterface { + Future exampleAsyncFuture(); + + Future exampleAsyncFuture2(); + + Future exampleAsyncMethod(); + + Future exampleInstanceMethod(); + + static Future exampleStaticMethod() => + RustLib.instance.api.crateApiMinimalMyStructExampleStaticMethod(); +} + +// Rust type: RustOpaqueMoi + Send + 'static > >>> +abstract class PinBoxFutureOutputString implements RustOpaqueInterface {} + +abstract class MyAsyncTrait { + Future exampleAsyncMethod( + {required int argOne, required int argTwo, required List argThree}); +} + +enum MyErr { + oops, + ; +} diff --git a/frb_example/dart_minimal/lib/src/rust/frb_generated.dart b/frb_example/dart_minimal/lib/src/rust/frb_generated.dart index 1e36e2b0e8..6e9a86f7da 100644 --- a/frb_example/dart_minimal/lib/src/rust/frb_generated.dart +++ b/frb_example/dart_minimal/lib/src/rust/frb_generated.dart @@ -58,7 +58,7 @@ class RustLib extends BaseEntrypoint { String get codegenVersion => '2.0.0'; @override - int get rustContentHash => -2119384465; + int get rustContentHash => -1511532083; static const kDefaultExternalLibraryLoaderConfig = ExternalLibraryLoaderConfig( @@ -69,9 +69,40 @@ class RustLib extends BaseEntrypoint { } abstract class RustLibApi extends BaseApi { + Future crateApiMinimalMyStructExampleAsyncFuture( + {required MyStruct that}); + + Future crateApiMinimalMyStructExampleAsyncFuture2( + {required MyStruct that}); + + Future crateApiMinimalMyStructExampleAsyncMethod( + {required MyStruct that}); + + Future crateApiMinimalMyStructExampleInstanceMethod( + {required MyStruct that}); + + Future crateApiMinimalMyStructExampleStaticMethod(); + Future crateApiMinimalInitApp(); Future crateApiMinimalMinimalAdder({required int a, required int b}); + + RustArcIncrementStrongCountFnType + get rust_arc_increment_strong_count_MyStruct; + + RustArcDecrementStrongCountFnType + get rust_arc_decrement_strong_count_MyStruct; + + CrossPlatformFinalizerArg get rust_arc_decrement_strong_count_MyStructPtr; + + RustArcIncrementStrongCountFnType + get rust_arc_increment_strong_count_PinBoxFutureOutputString; + + RustArcDecrementStrongCountFnType + get rust_arc_decrement_strong_count_PinBoxFutureOutputString; + + CrossPlatformFinalizerArg + get rust_arc_decrement_strong_count_PinBoxFutureOutputStringPtr; } class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { @@ -83,13 +114,146 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { }); @override - Future crateApiMinimalInitApp() { + Future crateApiMinimalMyStructExampleAsyncFuture( + {required MyStruct that}) { return handler.executeNormal(NormalTask( callFfi: (port_) { final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + that, serializer); pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 1, port: port_); }, + codec: SseCodec( + decodeSuccessData: sse_decode_String, + decodeErrorData: null, + ), + constMeta: kCrateApiMinimalMyStructExampleAsyncFutureConstMeta, + argValues: [that], + apiImpl: this, + )); + } + + TaskConstMeta get kCrateApiMinimalMyStructExampleAsyncFutureConstMeta => + const TaskConstMeta( + debugName: "MyStruct_example_async_future", + argNames: ["that"], + ); + + @override + Future crateApiMinimalMyStructExampleAsyncFuture2( + {required MyStruct that}) { + return handler.executeNormal(NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + that, serializer); + pdeCallFfi(generalizedFrbRustBinding, serializer, + funcId: 2, port: port_); + }, + codec: SseCodec( + decodeSuccessData: + sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic, + decodeErrorData: null, + ), + constMeta: kCrateApiMinimalMyStructExampleAsyncFuture2ConstMeta, + argValues: [that], + apiImpl: this, + )); + } + + TaskConstMeta get kCrateApiMinimalMyStructExampleAsyncFuture2ConstMeta => + const TaskConstMeta( + debugName: "MyStruct_example_async_future2", + argNames: ["that"], + ); + + @override + Future crateApiMinimalMyStructExampleAsyncMethod( + {required MyStruct that}) { + return handler.executeNormal(NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + that, serializer); + pdeCallFfi(generalizedFrbRustBinding, serializer, + funcId: 3, port: port_); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_String, + decodeErrorData: sse_decode_my_err, + ), + constMeta: kCrateApiMinimalMyStructExampleAsyncMethodConstMeta, + argValues: [that], + apiImpl: this, + )); + } + + TaskConstMeta get kCrateApiMinimalMyStructExampleAsyncMethodConstMeta => + const TaskConstMeta( + debugName: "MyStruct_example_async_method", + argNames: ["that"], + ); + + @override + Future crateApiMinimalMyStructExampleInstanceMethod( + {required MyStruct that}) { + return handler.executeNormal(NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + that, serializer); + pdeCallFfi(generalizedFrbRustBinding, serializer, + funcId: 4, port: port_); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_unit, + decodeErrorData: null, + ), + constMeta: kCrateApiMinimalMyStructExampleInstanceMethodConstMeta, + argValues: [that], + apiImpl: this, + )); + } + + TaskConstMeta get kCrateApiMinimalMyStructExampleInstanceMethodConstMeta => + const TaskConstMeta( + debugName: "MyStruct_example_instance_method", + argNames: ["that"], + ); + + @override + Future crateApiMinimalMyStructExampleStaticMethod() { + return handler.executeNormal(NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + pdeCallFfi(generalizedFrbRustBinding, serializer, + funcId: 5, port: port_); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_unit, + decodeErrorData: null, + ), + constMeta: kCrateApiMinimalMyStructExampleStaticMethodConstMeta, + argValues: [], + apiImpl: this, + )); + } + + TaskConstMeta get kCrateApiMinimalMyStructExampleStaticMethodConstMeta => + const TaskConstMeta( + debugName: "MyStruct_example_static_method", + argNames: [], + ); + + @override + Future crateApiMinimalInitApp() { + return handler.executeNormal(NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + pdeCallFfi(generalizedFrbRustBinding, serializer, + funcId: 7, port: port_); + }, codec: SseCodec( decodeSuccessData: sse_decode_unit, decodeErrorData: null, @@ -113,7 +277,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { sse_encode_i_32(a, serializer); sse_encode_i_32(b, serializer); pdeCallFfi(generalizedFrbRustBinding, serializer, - funcId: 2, port: port_); + funcId: 8, port: port_); }, codec: SseCodec( decodeSuccessData: sse_decode_i_32, @@ -131,49 +295,428 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { argNames: ["a", "b"], ); + RustArcIncrementStrongCountFnType + get rust_arc_increment_strong_count_MyStruct => wire + .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct; + + RustArcDecrementStrongCountFnType + get rust_arc_decrement_strong_count_MyStruct => wire + .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct; + + RustArcIncrementStrongCountFnType + get rust_arc_increment_strong_count_PinBoxFutureOutputString => wire + .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic; + + RustArcDecrementStrongCountFnType + get rust_arc_decrement_strong_count_PinBoxFutureOutputString => wire + .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic; + + @protected + MyStruct + dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return MyStructImpl.frbInternalDcoDecode(raw as List); + } + + @protected + PinBoxFutureOutputString + dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return PinBoxFutureOutputStringImpl.frbInternalDcoDecode( + raw as List); + } + + @protected + MyStruct + dco_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return MyStructImpl.frbInternalDcoDecode(raw as List); + } + + @protected + MyStruct + dco_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return MyStructImpl.frbInternalDcoDecode(raw as List); + } + + @protected + MyStruct + dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return MyStructImpl.frbInternalDcoDecode(raw as List); + } + + @protected + PinBoxFutureOutputString + dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return PinBoxFutureOutputStringImpl.frbInternalDcoDecode( + raw as List); + } + + @protected + String dco_decode_String(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return raw as String; + } + + @protected + MyAsyncTrait dco_decode_TraitDef_MyAsyncTrait(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + throw UnimplementedError(); + } + @protected int dco_decode_i_32(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs return raw as int; } + @protected + List dco_decode_list_prim_u_8_loose(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return raw as List; + } + + @protected + Uint8List dco_decode_list_prim_u_8_strict(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return raw as Uint8List; + } + + @protected + MyErr dco_decode_my_err(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return MyErr.values[raw as int]; + } + + @protected + int dco_decode_u_32(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return raw as int; + } + + @protected + int dco_decode_u_8(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return raw as int; + } + @protected void dco_decode_unit(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs return; } + @protected + BigInt dco_decode_usize(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return dcoDecodeU64(raw); + } + + @protected + MyStruct + sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + return MyStructImpl.frbInternalSseDecode( + sse_decode_usize(deserializer), sse_decode_i_32(deserializer)); + } + + @protected + PinBoxFutureOutputString + sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + return PinBoxFutureOutputStringImpl.frbInternalSseDecode( + sse_decode_usize(deserializer), sse_decode_i_32(deserializer)); + } + + @protected + MyStruct + sse_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + return MyStructImpl.frbInternalSseDecode( + sse_decode_usize(deserializer), sse_decode_i_32(deserializer)); + } + + @protected + MyStruct + sse_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + return MyStructImpl.frbInternalSseDecode( + sse_decode_usize(deserializer), sse_decode_i_32(deserializer)); + } + + @protected + MyStruct + sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + return MyStructImpl.frbInternalSseDecode( + sse_decode_usize(deserializer), sse_decode_i_32(deserializer)); + } + + @protected + PinBoxFutureOutputString + sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + return PinBoxFutureOutputStringImpl.frbInternalSseDecode( + sse_decode_usize(deserializer), sse_decode_i_32(deserializer)); + } + + @protected + String sse_decode_String(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + var inner = sse_decode_list_prim_u_8_strict(deserializer); + return utf8.decoder.convert(inner); + } + @protected int sse_decode_i_32(SseDeserializer deserializer) { // Codec=Sse (Serialization based), see doc to use other codecs return deserializer.buffer.getInt32(); } + @protected + List sse_decode_list_prim_u_8_loose(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + var len_ = sse_decode_i_32(deserializer); + return deserializer.buffer.getUint8List(len_); + } + + @protected + Uint8List sse_decode_list_prim_u_8_strict(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + var len_ = sse_decode_i_32(deserializer); + return deserializer.buffer.getUint8List(len_); + } + + @protected + MyErr sse_decode_my_err(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + var inner = sse_decode_i_32(deserializer); + return MyErr.values[inner]; + } + + @protected + int sse_decode_u_32(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + return deserializer.buffer.getUint32(); + } + + @protected + int sse_decode_u_8(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + return deserializer.buffer.getUint8(); + } + @protected void sse_decode_unit(SseDeserializer deserializer) { // Codec=Sse (Serialization based), see doc to use other codecs } + @protected + BigInt sse_decode_usize(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + return deserializer.buffer.getBigUint64(); + } + @protected bool sse_decode_bool(SseDeserializer deserializer) { // Codec=Sse (Serialization based), see doc to use other codecs return deserializer.buffer.getUint8() != 0; } + @protected + void + sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + MyStruct self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_usize( + (self as MyStructImpl).frbInternalSseEncode(move: true), serializer); + } + + @protected + void + sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + PinBoxFutureOutputString self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_usize( + (self as PinBoxFutureOutputStringImpl).frbInternalSseEncode(move: true), + serializer); + } + + @protected + void + sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + MyStruct self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_usize( + (self as MyStructImpl).frbInternalSseEncode(move: false), serializer); + } + + @protected + void + sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + MyStruct self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_usize( + (self as MyStructImpl).frbInternalSseEncode(move: false), serializer); + } + + @protected + void + sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + MyStruct self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_usize( + (self as MyStructImpl).frbInternalSseEncode(move: null), serializer); + } + + @protected + void + sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + PinBoxFutureOutputString self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_usize( + (self as PinBoxFutureOutputStringImpl).frbInternalSseEncode(move: null), + serializer); + } + + @protected + void sse_encode_String(String self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_list_prim_u_8_strict(utf8.encoder.convert(self), serializer); + } + @protected void sse_encode_i_32(int self, SseSerializer serializer) { // Codec=Sse (Serialization based), see doc to use other codecs serializer.buffer.putInt32(self); } + @protected + void sse_encode_list_prim_u_8_loose( + List self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_i_32(self.length, serializer); + serializer.buffer + .putUint8List(self is Uint8List ? self : Uint8List.fromList(self)); + } + + @protected + void sse_encode_list_prim_u_8_strict( + Uint8List self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_i_32(self.length, serializer); + serializer.buffer.putUint8List(self); + } + + @protected + void sse_encode_my_err(MyErr self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_i_32(self.index, serializer); + } + + @protected + void sse_encode_u_32(int self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + serializer.buffer.putUint32(self); + } + + @protected + void sse_encode_u_8(int self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + serializer.buffer.putUint8(self); + } + @protected void sse_encode_unit(void self, SseSerializer serializer) { // Codec=Sse (Serialization based), see doc to use other codecs } + @protected + void sse_encode_usize(BigInt self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + serializer.buffer.putBigUint64(self); + } + @protected void sse_encode_bool(bool self, SseSerializer serializer) { // Codec=Sse (Serialization based), see doc to use other codecs serializer.buffer.putUint8(self ? 1 : 0); } } + +@sealed +class MyStructImpl extends RustOpaque implements MyStruct { + // Not to be used by end users + MyStructImpl.frbInternalDcoDecode(List wire) + : super.frbInternalDcoDecode(wire, _kStaticData); + + // Not to be used by end users + MyStructImpl.frbInternalSseDecode(BigInt ptr, int externalSizeOnNative) + : super.frbInternalSseDecode(ptr, externalSizeOnNative, _kStaticData); + + static final _kStaticData = RustArcStaticData( + rustArcIncrementStrongCount: + RustLib.instance.api.rust_arc_increment_strong_count_MyStruct, + rustArcDecrementStrongCount: + RustLib.instance.api.rust_arc_decrement_strong_count_MyStruct, + rustArcDecrementStrongCountPtr: + RustLib.instance.api.rust_arc_decrement_strong_count_MyStructPtr, + ); + + Future exampleAsyncFuture() => + RustLib.instance.api.crateApiMinimalMyStructExampleAsyncFuture( + that: this, + ); + + Future exampleAsyncFuture2() => + RustLib.instance.api.crateApiMinimalMyStructExampleAsyncFuture2( + that: this, + ); + + Future exampleAsyncMethod() => + RustLib.instance.api.crateApiMinimalMyStructExampleAsyncMethod( + that: this, + ); + + Future exampleInstanceMethod() => + RustLib.instance.api.crateApiMinimalMyStructExampleInstanceMethod( + that: this, + ); +} + +@sealed +class PinBoxFutureOutputStringImpl extends RustOpaque + implements PinBoxFutureOutputString { + // Not to be used by end users + PinBoxFutureOutputStringImpl.frbInternalDcoDecode(List wire) + : super.frbInternalDcoDecode(wire, _kStaticData); + + // Not to be used by end users + PinBoxFutureOutputStringImpl.frbInternalSseDecode( + BigInt ptr, int externalSizeOnNative) + : super.frbInternalSseDecode(ptr, externalSizeOnNative, _kStaticData); + + static final _kStaticData = RustArcStaticData( + rustArcIncrementStrongCount: RustLib + .instance.api.rust_arc_increment_strong_count_PinBoxFutureOutputString, + rustArcDecrementStrongCount: RustLib + .instance.api.rust_arc_decrement_strong_count_PinBoxFutureOutputString, + rustArcDecrementStrongCountPtr: RustLib.instance.api + .rust_arc_decrement_strong_count_PinBoxFutureOutputStringPtr, + ); +} diff --git a/frb_example/dart_minimal/lib/src/rust/frb_generated.io.dart b/frb_example/dart_minimal/lib/src/rust/frb_generated.io.dart index ba09d9752d..6272c9e962 100644 --- a/frb_example/dart_minimal/lib/src/rust/frb_generated.io.dart +++ b/frb_example/dart_minimal/lib/src/rust/frb_generated.io.dart @@ -18,27 +18,191 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { required super.portManager, }); + CrossPlatformFinalizerArg get rust_arc_decrement_strong_count_MyStructPtr => wire + ._rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStructPtr; + + CrossPlatformFinalizerArg + get rust_arc_decrement_strong_count_PinBoxFutureOutputStringPtr => wire + ._rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstaticPtr; + + @protected + MyStruct + dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + dynamic raw); + + @protected + PinBoxFutureOutputString + dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + dynamic raw); + + @protected + MyStruct + dco_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + dynamic raw); + + @protected + MyStruct + dco_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + dynamic raw); + + @protected + MyStruct + dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + dynamic raw); + + @protected + PinBoxFutureOutputString + dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + dynamic raw); + + @protected + String dco_decode_String(dynamic raw); + + @protected + MyAsyncTrait dco_decode_TraitDef_MyAsyncTrait(dynamic raw); + @protected int dco_decode_i_32(dynamic raw); + @protected + List dco_decode_list_prim_u_8_loose(dynamic raw); + + @protected + Uint8List dco_decode_list_prim_u_8_strict(dynamic raw); + + @protected + MyErr dco_decode_my_err(dynamic raw); + + @protected + int dco_decode_u_32(dynamic raw); + + @protected + int dco_decode_u_8(dynamic raw); + @protected void dco_decode_unit(dynamic raw); + @protected + BigInt dco_decode_usize(dynamic raw); + + @protected + MyStruct + sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + SseDeserializer deserializer); + + @protected + PinBoxFutureOutputString + sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + SseDeserializer deserializer); + + @protected + MyStruct + sse_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + SseDeserializer deserializer); + + @protected + MyStruct + sse_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + SseDeserializer deserializer); + + @protected + MyStruct + sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + SseDeserializer deserializer); + + @protected + PinBoxFutureOutputString + sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + SseDeserializer deserializer); + + @protected + String sse_decode_String(SseDeserializer deserializer); + @protected int sse_decode_i_32(SseDeserializer deserializer); + @protected + List sse_decode_list_prim_u_8_loose(SseDeserializer deserializer); + + @protected + Uint8List sse_decode_list_prim_u_8_strict(SseDeserializer deserializer); + + @protected + MyErr sse_decode_my_err(SseDeserializer deserializer); + + @protected + int sse_decode_u_32(SseDeserializer deserializer); + + @protected + int sse_decode_u_8(SseDeserializer deserializer); + @protected void sse_decode_unit(SseDeserializer deserializer); + @protected + BigInt sse_decode_usize(SseDeserializer deserializer); + @protected bool sse_decode_bool(SseDeserializer deserializer); + @protected + void + sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + MyStruct self, SseSerializer serializer); + + @protected + void + sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + PinBoxFutureOutputString self, SseSerializer serializer); + + @protected + void + sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + MyStruct self, SseSerializer serializer); + + @protected + void + sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + MyStruct self, SseSerializer serializer); + + @protected + void + sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + MyStruct self, SseSerializer serializer); + + @protected + void + sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + PinBoxFutureOutputString self, SseSerializer serializer); + + @protected + void sse_encode_String(String self, SseSerializer serializer); + @protected void sse_encode_i_32(int self, SseSerializer serializer); + @protected + void sse_encode_list_prim_u_8_loose(List self, SseSerializer serializer); + + @protected + void sse_encode_list_prim_u_8_strict( + Uint8List self, SseSerializer serializer); + + @protected + void sse_encode_my_err(MyErr self, SseSerializer serializer); + + @protected + void sse_encode_u_32(int self, SseSerializer serializer); + + @protected + void sse_encode_u_8(int self, SseSerializer serializer); + @protected void sse_encode_unit(void self, SseSerializer serializer); + @protected + void sse_encode_usize(BigInt self, SseSerializer serializer); + @protected void sse_encode_bool(bool self, SseSerializer serializer); } @@ -56,4 +220,68 @@ class RustLibWire implements BaseWire { /// The symbols are looked up in [dynamicLibrary]. RustLibWire(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup; + + void + rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + ffi.Pointer ptr, + ) { + return _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + ptr, + ); + } + + late final _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStructPtr = + _lookup)>>( + 'frbgen_frb_example_dart_minimal_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct'); + late final _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct = + _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStructPtr + .asFunction)>(); + + void + rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + ffi.Pointer ptr, + ) { + return _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + ptr, + ); + } + + late final _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStructPtr = + _lookup)>>( + 'frbgen_frb_example_dart_minimal_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct'); + late final _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct = + _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStructPtr + .asFunction)>(); + + void + rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + ffi.Pointer ptr, + ) { + return _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + ptr, + ); + } + + late final _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstaticPtr = + _lookup)>>( + 'frbgen_frb_example_dart_minimal_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic'); + late final _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic = + _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstaticPtr + .asFunction)>(); + + void + rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + ffi.Pointer ptr, + ) { + return _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + ptr, + ); + } + + late final _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstaticPtr = + _lookup)>>( + 'frbgen_frb_example_dart_minimal_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic'); + late final _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic = + _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstaticPtr + .asFunction)>(); } diff --git a/frb_example/dart_minimal/lib/src/rust/frb_generated.web.dart b/frb_example/dart_minimal/lib/src/rust/frb_generated.web.dart index aa2362f15d..0b777d11c7 100644 --- a/frb_example/dart_minimal/lib/src/rust/frb_generated.web.dart +++ b/frb_example/dart_minimal/lib/src/rust/frb_generated.web.dart @@ -20,27 +20,191 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { required super.portManager, }); + CrossPlatformFinalizerArg get rust_arc_decrement_strong_count_MyStructPtr => wire + .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct; + + CrossPlatformFinalizerArg + get rust_arc_decrement_strong_count_PinBoxFutureOutputStringPtr => wire + .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic; + + @protected + MyStruct + dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + dynamic raw); + + @protected + PinBoxFutureOutputString + dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + dynamic raw); + + @protected + MyStruct + dco_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + dynamic raw); + + @protected + MyStruct + dco_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + dynamic raw); + + @protected + MyStruct + dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + dynamic raw); + + @protected + PinBoxFutureOutputString + dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + dynamic raw); + + @protected + String dco_decode_String(dynamic raw); + + @protected + MyAsyncTrait dco_decode_TraitDef_MyAsyncTrait(dynamic raw); + @protected int dco_decode_i_32(dynamic raw); + @protected + List dco_decode_list_prim_u_8_loose(dynamic raw); + + @protected + Uint8List dco_decode_list_prim_u_8_strict(dynamic raw); + + @protected + MyErr dco_decode_my_err(dynamic raw); + + @protected + int dco_decode_u_32(dynamic raw); + + @protected + int dco_decode_u_8(dynamic raw); + @protected void dco_decode_unit(dynamic raw); + @protected + BigInt dco_decode_usize(dynamic raw); + + @protected + MyStruct + sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + SseDeserializer deserializer); + + @protected + PinBoxFutureOutputString + sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + SseDeserializer deserializer); + + @protected + MyStruct + sse_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + SseDeserializer deserializer); + + @protected + MyStruct + sse_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + SseDeserializer deserializer); + + @protected + MyStruct + sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + SseDeserializer deserializer); + + @protected + PinBoxFutureOutputString + sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + SseDeserializer deserializer); + + @protected + String sse_decode_String(SseDeserializer deserializer); + @protected int sse_decode_i_32(SseDeserializer deserializer); + @protected + List sse_decode_list_prim_u_8_loose(SseDeserializer deserializer); + + @protected + Uint8List sse_decode_list_prim_u_8_strict(SseDeserializer deserializer); + + @protected + MyErr sse_decode_my_err(SseDeserializer deserializer); + + @protected + int sse_decode_u_32(SseDeserializer deserializer); + + @protected + int sse_decode_u_8(SseDeserializer deserializer); + @protected void sse_decode_unit(SseDeserializer deserializer); + @protected + BigInt sse_decode_usize(SseDeserializer deserializer); + @protected bool sse_decode_bool(SseDeserializer deserializer); + @protected + void + sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + MyStruct self, SseSerializer serializer); + + @protected + void + sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + PinBoxFutureOutputString self, SseSerializer serializer); + + @protected + void + sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + MyStruct self, SseSerializer serializer); + + @protected + void + sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + MyStruct self, SseSerializer serializer); + + @protected + void + sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + MyStruct self, SseSerializer serializer); + + @protected + void + sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + PinBoxFutureOutputString self, SseSerializer serializer); + + @protected + void sse_encode_String(String self, SseSerializer serializer); + @protected void sse_encode_i_32(int self, SseSerializer serializer); + @protected + void sse_encode_list_prim_u_8_loose(List self, SseSerializer serializer); + + @protected + void sse_encode_list_prim_u_8_strict( + Uint8List self, SseSerializer serializer); + + @protected + void sse_encode_my_err(MyErr self, SseSerializer serializer); + + @protected + void sse_encode_u_32(int self, SseSerializer serializer); + + @protected + void sse_encode_u_8(int self, SseSerializer serializer); + @protected void sse_encode_unit(void self, SseSerializer serializer); + @protected + void sse_encode_usize(BigInt self, SseSerializer serializer); + @protected void sse_encode_bool(bool self, SseSerializer serializer); } @@ -49,6 +213,30 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { class RustLibWire implements BaseWire { RustLibWire.fromExternalLibrary(ExternalLibrary lib); + + void rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + int ptr) => + wasmModule + .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + ptr); + + void rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + int ptr) => + wasmModule + .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + ptr); + + void rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + int ptr) => + wasmModule + .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + ptr); + + void rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + int ptr) => + wasmModule + .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + ptr); } @JS('wasm_bindgen') @@ -56,4 +244,20 @@ external RustLibWasmModule get wasmModule; @JS() @anonymous -extension type RustLibWasmModule._(JSObject _) implements JSObject {} +extension type RustLibWasmModule._(JSObject _) implements JSObject { + external void + rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + int ptr); + + external void + rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + int ptr); + + external void + rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + int ptr); + + external void + rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + int ptr); +} diff --git a/frb_example/dart_minimal/rust/src/api/minimal.rs b/frb_example/dart_minimal/rust/src/api/minimal.rs index 517e29973f..57dcdf3def 100644 --- a/frb_example/dart_minimal/rust/src/api/minimal.rs +++ b/frb_example/dart_minimal/rust/src/api/minimal.rs @@ -1,4 +1,7 @@ use flutter_rust_bridge::frb; +pub use flutter_rust_bridge::DartFnFuture; +pub use std::future::Future; +pub use std::pin::Pin; #[frb(init)] pub fn init_app() { @@ -8,3 +11,45 @@ pub fn init_app() { pub fn minimal_adder(a: i32, b: i32) -> i32 { a + b } + +#[frb(opaque)] +pub struct MyStruct {} + +impl MyStruct { + pub fn example_static_method() {} + + pub fn example_instance_method(&self) {} + + pub fn example_async_method(&mut self) -> impl Future> { + async { + "result_value".to_string() + } + } + + pub fn example_async_future(&mut self) -> DartFnFuture { + async { + "result_value".to_string() + } + } + + pub fn example_async_future2(&mut self) -> Pin + Send + 'static>> { + async { + "result_value".to_string() + } + } + +} + +pub enum MyErr{ + Oops, +} + +pub trait MyAsyncTrait { + fn example_async_method( + &mut self, + arg_one: u8, + arg_two: u32, + arg_three: Vec, + ) -> impl Future, MyErr>>; + +} diff --git a/frb_example/dart_minimal/rust/src/frb_generated.io.rs b/frb_example/dart_minimal/rust/src/frb_generated.io.rs new file mode 100644 index 0000000000..657460c49f --- /dev/null +++ b/frb_example/dart_minimal/rust/src/frb_generated.io.rs @@ -0,0 +1,50 @@ +// This file is automatically generated, so please do not edit it. +// Generated by `flutter_rust_bridge`@ 2.0.0. + +// Section: imports + +use super::*; +use crate::api::minimal::*; +use flutter_rust_bridge::for_generated::byteorder::{NativeEndian, ReadBytesExt, WriteBytesExt}; +use flutter_rust_bridge::for_generated::{transform_result_dco, Lifetimeable, Lockable}; +use flutter_rust_bridge::{Handler, IntoIntoDart}; + +// Section: boilerplate + +flutter_rust_bridge::frb_generated_boilerplate_io!(); + +#[no_mangle] +pub extern "C" fn frbgen_frb_example_dart_minimal_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + ptr: *const std::ffi::c_void, +) { + MoiArc::>::increment_strong_count(ptr as _); +} + +#[no_mangle] +pub extern "C" fn frbgen_frb_example_dart_minimal_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + ptr: *const std::ffi::c_void, +) { + MoiArc::>::decrement_strong_count(ptr as _); +} + +#[no_mangle] +pub extern "C" fn frbgen_frb_example_dart_minimal_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + ptr: *const std::ffi::c_void, +) { + MoiArc::< + flutter_rust_bridge::for_generated::RustAutoOpaqueInner< + Pin + Send + 'static>>, + >, + >::increment_strong_count(ptr as _); +} + +#[no_mangle] +pub extern "C" fn frbgen_frb_example_dart_minimal_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + ptr: *const std::ffi::c_void, +) { + MoiArc::< + flutter_rust_bridge::for_generated::RustAutoOpaqueInner< + Pin + Send + 'static>>, + >, + >::decrement_strong_count(ptr as _); +} diff --git a/frb_example/dart_minimal/rust/src/frb_generated.rs b/frb_example/dart_minimal/rust/src/frb_generated.rs index 62dd178b09..3bb101ee4f 100644 --- a/frb_example/dart_minimal/rust/src/frb_generated.rs +++ b/frb_example/dart_minimal/rust/src/frb_generated.rs @@ -25,6 +25,7 @@ // Section: imports +use crate::api::minimal::*; use flutter_rust_bridge::for_generated::byteorder::{NativeEndian, ReadBytesExt, WriteBytesExt}; use flutter_rust_bridge::for_generated::{transform_result_dco, Lifetimeable, Lockable}; use flutter_rust_bridge::{Handler, IntoIntoDart}; @@ -37,7 +38,7 @@ flutter_rust_bridge::frb_generated_boilerplate!( default_rust_auto_opaque = RustAutoOpaqueMoi, ); pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.0.0"; -pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = -2119384465; +pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = -1511532083; // Section: executor @@ -45,6 +46,260 @@ flutter_rust_bridge::frb_generated_default_handler!(); // Section: wire_funcs +fn wire__crate__api__minimal__MyStruct_example_async_future_impl( + port_: flutter_rust_bridge::for_generated::MessagePort, + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "MyStruct_example_async_future", + port: Some(port_), + mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_that = , + >>::sse_decode(&mut deserializer); + deserializer.end(); + move |context| async move { + transform_result_sse::<_, ()>( + (move || async move { + let mut api_that_guard = None; + let decode_indices_ = + flutter_rust_bridge::for_generated::lockable_compute_decode_order( + vec![flutter_rust_bridge::for_generated::LockableOrderInfo::new( + &api_that, 0, true, + )], + ); + for i in decode_indices_ { + match i { + 0 => { + api_that_guard = + Some(api_that.lockable_decode_async_ref_mut().await) + } + _ => unreachable!(), + } + } + let mut api_that_guard = api_that_guard.unwrap(); + let output_ok = Result::<_, ()>::Ok( + crate::api::minimal::MyStruct::example_async_future( + &mut *api_that_guard, + ) + .await, + )?; + Ok(output_ok) + })() + .await, + ) + } + }, + ) +} +fn wire__crate__api__minimal__MyStruct_example_async_future2_impl( + port_: flutter_rust_bridge::for_generated::MessagePort, + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "MyStruct_example_async_future2", + port: Some(port_), + mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_that = , + >>::sse_decode(&mut deserializer); + deserializer.end(); + move |context| { + transform_result_sse::<_, ()>((move || { + let mut api_that_guard = None; + let decode_indices_ = + flutter_rust_bridge::for_generated::lockable_compute_decode_order(vec![ + flutter_rust_bridge::for_generated::LockableOrderInfo::new( + &api_that, 0, true, + ), + ]); + for i in decode_indices_ { + match i { + 0 => api_that_guard = Some(api_that.lockable_decode_sync_ref_mut()), + _ => unreachable!(), + } + } + let mut api_that_guard = api_that_guard.unwrap(); + let output_ok = Result::<_, ()>::Ok( + crate::api::minimal::MyStruct::example_async_future2(&mut *api_that_guard), + )?; + Ok(output_ok) + })()) + } + }, + ) +} +fn wire__crate__api__minimal__MyStruct_example_async_method_impl( + port_: flutter_rust_bridge::for_generated::MessagePort, + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "MyStruct_example_async_method", + port: Some(port_), + mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_that = , + >>::sse_decode(&mut deserializer); + deserializer.end(); + move |context| async move { + transform_result_sse::<_, crate::api::minimal::MyErr>( + (move || async move { + let mut api_that_guard = None; + let decode_indices_ = + flutter_rust_bridge::for_generated::lockable_compute_decode_order( + vec![flutter_rust_bridge::for_generated::LockableOrderInfo::new( + &api_that, 0, true, + )], + ); + for i in decode_indices_ { + match i { + 0 => { + api_that_guard = + Some(api_that.lockable_decode_async_ref_mut().await) + } + _ => unreachable!(), + } + } + let mut api_that_guard = api_that_guard.unwrap(); + let output_ok = crate::api::minimal::MyStruct::example_async_method( + &mut *api_that_guard, + ) + .await?; + Ok(output_ok) + })() + .await, + ) + } + }, + ) +} +fn wire__crate__api__minimal__MyStruct_example_instance_method_impl( + port_: flutter_rust_bridge::for_generated::MessagePort, + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "MyStruct_example_instance_method", + port: Some(port_), + mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_that = , + >>::sse_decode(&mut deserializer); + deserializer.end(); + move |context| { + transform_result_sse::<_, ()>((move || { + let mut api_that_guard = None; + let decode_indices_ = + flutter_rust_bridge::for_generated::lockable_compute_decode_order(vec![ + flutter_rust_bridge::for_generated::LockableOrderInfo::new( + &api_that, 0, false, + ), + ]); + for i in decode_indices_ { + match i { + 0 => api_that_guard = Some(api_that.lockable_decode_sync_ref()), + _ => unreachable!(), + } + } + let api_that_guard = api_that_guard.unwrap(); + let output_ok = Result::<_, ()>::Ok({ + crate::api::minimal::MyStruct::example_instance_method(&*api_that_guard); + })?; + Ok(output_ok) + })()) + } + }, + ) +} +fn wire__crate__api__minimal__MyStruct_example_static_method_impl( + port_: flutter_rust_bridge::for_generated::MessagePort, + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "MyStruct_example_static_method", + port: Some(port_), + mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + deserializer.end(); + move |context| { + transform_result_sse::<_, ()>((move || { + let output_ok = Result::<_, ()>::Ok({ + crate::api::minimal::MyStruct::example_static_method(); + })?; + Ok(output_ok) + })()) + } + }, + ) +} fn wire__crate__api__minimal__init_app_impl( port_: flutter_rust_bridge::for_generated::MessagePort, ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, @@ -115,8 +370,73 @@ fn wire__crate__api__minimal__minimal_adder_impl( ) } +// Section: related_funcs + +flutter_rust_bridge::frb_generated_moi_arc_impl_value!( + flutter_rust_bridge::for_generated::RustAutoOpaqueInner +); +flutter_rust_bridge::frb_generated_moi_arc_impl_value!( + flutter_rust_bridge::for_generated::RustAutoOpaqueInner< + Pin + Send + 'static>>, + > +); + // Section: dart2rust +impl SseDecode for MyStruct { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + let mut inner = , + >>::sse_decode(deserializer); + return flutter_rust_bridge::for_generated::rust_auto_opaque_decode_owned(inner); + } +} + +impl SseDecode for Pin + Send + 'static>> { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + let mut inner = + Send + 'static>>, + >, + >>::sse_decode(deserializer); + return flutter_rust_bridge::for_generated::rust_auto_opaque_decode_owned(inner); + } +} + +impl SseDecode + for RustOpaqueMoi> +{ + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + let mut inner = ::sse_decode(deserializer); + return decode_rust_opaque_moi(inner); + } +} + +impl SseDecode + for RustOpaqueMoi< + flutter_rust_bridge::for_generated::RustAutoOpaqueInner< + Pin + Send + 'static>>, + >, + > +{ + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + let mut inner = ::sse_decode(deserializer); + return decode_rust_opaque_moi(inner); + } +} + +impl SseDecode for String { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + let mut inner = >::sse_decode(deserializer); + return String::from_utf8(inner).unwrap(); + } +} + impl SseDecode for i32 { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { @@ -124,11 +444,55 @@ impl SseDecode for i32 { } } +impl SseDecode for Vec { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + let mut len_ = ::sse_decode(deserializer); + let mut ans_ = vec![]; + for idx_ in 0..len_ { + ans_.push(::sse_decode(deserializer)); + } + return ans_; + } +} + +impl SseDecode for crate::api::minimal::MyErr { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + let mut inner = ::sse_decode(deserializer); + return match inner { + 0 => crate::api::minimal::MyErr::Oops, + _ => unreachable!("Invalid variant for MyErr: {}", inner), + }; + } +} + +impl SseDecode for u32 { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + deserializer.cursor.read_u32::().unwrap() + } +} + +impl SseDecode for u8 { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + deserializer.cursor.read_u8().unwrap() + } +} + impl SseDecode for () { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {} } +impl SseDecode for usize { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + deserializer.cursor.read_u64::().unwrap() as _ + } +} + impl SseDecode for bool { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { @@ -145,8 +509,38 @@ fn pde_ffi_dispatcher_primary_impl( ) { // Codec=Pde (Serialization + dispatch), see doc to use other codecs match func_id { - 1 => wire__crate__api__minimal__init_app_impl(port, ptr, rust_vec_len, data_len), - 2 => wire__crate__api__minimal__minimal_adder_impl(port, ptr, rust_vec_len, data_len), + 1 => wire__crate__api__minimal__MyStruct_example_async_future_impl( + port, + ptr, + rust_vec_len, + data_len, + ), + 2 => wire__crate__api__minimal__MyStruct_example_async_future2_impl( + port, + ptr, + rust_vec_len, + data_len, + ), + 3 => wire__crate__api__minimal__MyStruct_example_async_method_impl( + port, + ptr, + rust_vec_len, + data_len, + ), + 4 => wire__crate__api__minimal__MyStruct_example_instance_method_impl( + port, + ptr, + rust_vec_len, + data_len, + ), + 5 => wire__crate__api__minimal__MyStruct_example_static_method_impl( + port, + ptr, + rust_vec_len, + data_len, + ), + 7 => wire__crate__api__minimal__init_app_impl(port, ptr, rust_vec_len, data_len), + 8 => wire__crate__api__minimal__minimal_adder_impl(port, ptr, rust_vec_len, data_len), _ => unreachable!(), } } @@ -165,6 +559,115 @@ fn pde_ffi_dispatcher_sync_impl( // Section: rust2dart +// Codec=Dco (DartCObject based), see doc to use other codecs +impl flutter_rust_bridge::IntoDart for FrbWrapper { + fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { + flutter_rust_bridge::for_generated::rust_auto_opaque_encode::<_, MoiArc<_>>(self.0) + .into_dart() + } +} +impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive for FrbWrapper {} + +impl flutter_rust_bridge::IntoIntoDart> for MyStruct { + fn into_into_dart(self) -> FrbWrapper { + self.into() + } +} + +// Codec=Dco (DartCObject based), see doc to use other codecs +impl flutter_rust_bridge::IntoDart + for FrbWrapper + Send + 'static>>> +{ + fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { + flutter_rust_bridge::for_generated::rust_auto_opaque_encode::<_, MoiArc<_>>(self.0) + .into_dart() + } +} +impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive + for FrbWrapper + Send + 'static>>> +{ +} + +impl + flutter_rust_bridge::IntoIntoDart< + FrbWrapper + Send + 'static>>>, + > for Pin + Send + 'static>> +{ + fn into_into_dart(self) -> FrbWrapper + Send + 'static>>> { + self.into() + } +} + +// Codec=Dco (DartCObject based), see doc to use other codecs +impl flutter_rust_bridge::IntoDart for crate::api::minimal::MyErr { + fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { + match self { + Self::Oops => 0.into_dart(), + _ => unreachable!(), + } + } +} +impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive for crate::api::minimal::MyErr {} +impl flutter_rust_bridge::IntoIntoDart for crate::api::minimal::MyErr { + fn into_into_dart(self) -> crate::api::minimal::MyErr { + self + } +} + +impl SseEncode for MyStruct { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + >>::sse_encode(flutter_rust_bridge::for_generated::rust_auto_opaque_encode::<_, MoiArc<_>>(self), serializer); + } +} + +impl SseEncode for Pin + Send + 'static>> { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + + Send + 'static>>, + >, + >>::sse_encode( + flutter_rust_bridge::for_generated::rust_auto_opaque_encode::<_, MoiArc<_>>(self), + serializer, + ); + } +} + +impl SseEncode + for RustOpaqueMoi> +{ + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + let (ptr, size) = self.sse_encode_raw(); + ::sse_encode(ptr, serializer); + ::sse_encode(size, serializer); + } +} + +impl SseEncode + for RustOpaqueMoi< + flutter_rust_bridge::for_generated::RustAutoOpaqueInner< + Pin + Send + 'static>>, + >, + > +{ + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + let (ptr, size) = self.sse_encode_raw(); + ::sse_encode(ptr, serializer); + ::sse_encode(size, serializer); + } +} + +impl SseEncode for String { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + >::sse_encode(self.into_bytes(), serializer); + } +} + impl SseEncode for i32 { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { @@ -172,11 +675,60 @@ impl SseEncode for i32 { } } +impl SseEncode for Vec { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + ::sse_encode(self.len() as _, serializer); + for item in self { + ::sse_encode(item, serializer); + } + } +} + +impl SseEncode for crate::api::minimal::MyErr { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + ::sse_encode( + match self { + crate::api::minimal::MyErr::Oops => 0, + _ => { + unimplemented!(""); + } + }, + serializer, + ); + } +} + +impl SseEncode for u32 { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + serializer.cursor.write_u32::(self).unwrap(); + } +} + +impl SseEncode for u8 { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + serializer.cursor.write_u8(self).unwrap(); + } +} + impl SseEncode for () { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {} } +impl SseEncode for usize { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + serializer + .cursor + .write_u64::(self as _) + .unwrap(); + } +} + impl SseEncode for bool { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { diff --git a/frb_example/dart_minimal/rust/src/frb_generated.web.rs b/frb_example/dart_minimal/rust/src/frb_generated.web.rs new file mode 100644 index 0000000000..99611155a0 --- /dev/null +++ b/frb_example/dart_minimal/rust/src/frb_generated.web.rs @@ -0,0 +1,52 @@ +// This file is automatically generated, so please do not edit it. +// Generated by `flutter_rust_bridge`@ 2.0.0. + +// Section: imports + +use super::*; +use crate::api::minimal::*; +use flutter_rust_bridge::for_generated::byteorder::{NativeEndian, ReadBytesExt, WriteBytesExt}; +use flutter_rust_bridge::for_generated::wasm_bindgen; +use flutter_rust_bridge::for_generated::wasm_bindgen::prelude::*; +use flutter_rust_bridge::for_generated::{transform_result_dco, Lifetimeable, Lockable}; +use flutter_rust_bridge::{Handler, IntoIntoDart}; + +// Section: boilerplate + +flutter_rust_bridge::frb_generated_boilerplate_web!(); + +#[wasm_bindgen] +pub fn rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + ptr: *const std::ffi::c_void, +) { + MoiArc::>::increment_strong_count(ptr as _); +} + +#[wasm_bindgen] +pub fn rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMyStruct( + ptr: *const std::ffi::c_void, +) { + MoiArc::>::decrement_strong_count(ptr as _); +} + +#[wasm_bindgen] +pub fn rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + ptr: *const std::ffi::c_void, +) { + MoiArc::< + flutter_rust_bridge::for_generated::RustAutoOpaqueInner< + Pin + Send + 'static>>, + >, + >::increment_strong_count(ptr as _); +} + +#[wasm_bindgen] +pub fn rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerPinBoxdynFutureOutputStringSendstatic( + ptr: *const std::ffi::c_void, +) { + MoiArc::< + flutter_rust_bridge::for_generated::RustAutoOpaqueInner< + Pin + Send + 'static>>, + >, + >::decrement_strong_count(ptr as _); +}