From fda6ef5b7cc71f1c341fbdec2ca1e4db9e725e3f Mon Sep 17 00:00:00 2001 From: Kegan Dougal <7190048+kegsay@users.noreply.github.com> Date: Fri, 15 Mar 2024 09:22:42 +0000 Subject: [PATCH] bugfix: fix #36 by type-casting errors Produces code like this: ``` func (foreignCallbackCallbackInterfaceCallback) InvokeDoSomething(callback Callback, args []byte, outBuf *C.RustBuffer) uniffiCallbackResult { reader := bytes.NewReader(args) callback.DoSomething(FfiConverterTypeBoobyTrapErrorINSTANCE.Read(reader).(*BoobyTrapError)) return uniffiCallbackResultSuccess } func (foreignCallbackCallbackInterfaceCallback) InvokeDoSomethingElse(callback Callback, args []byte, outBuf *C.RustBuffer) uniffiCallbackResult { reader := bytes.NewReader(args) callback.DoSomethingElse(FfiConverterTypeSomeEnumINSTANCE.Read(reader)) return uniffiCallbackResultSuccess } ``` Note the type-cast on `Read(reader)` for errors. Signed-off-by: Kegan Dougal <7190048+kegsay@users.noreply.github.com> --- bindgen/src/gen_go/mod.rs | 13 +++++++++++-- bindgen/templates/CallbackInterfaceTemplate.go | 2 +- bindgen/templates/ErrorTemplate.go | 2 +- fixtures/errors/src/errors.udl | 10 ++++++++++ fixtures/errors/src/lib.rs | 10 ++++++++++ 5 files changed, 33 insertions(+), 4 deletions(-) diff --git a/bindgen/src/gen_go/mod.rs b/bindgen/src/gen_go/mod.rs index a1e0c44..ed4fd96 100644 --- a/bindgen/src/gen_go/mod.rs +++ b/bindgen/src/gen_go/mod.rs @@ -448,9 +448,18 @@ pub mod filters { // we want to pass around the `error` interface and let the caller type cast, but in // some cases (e.g when writing nested errors) we need to work with concrete error types // which involve type casting from `error` to `ConcreteError`. - pub fn error_type_cast(type_: &impl AsType) -> Result { + pub fn error_type_cast( + type_: &impl AsType, + is_name_used_as_error: bool, + ) -> Result { let result = match type_.as_type() { - Type::Enum { .. } => format!(".(*{})", oracle().find(type_).type_label()), + Type::Enum { name: n, .. } => { + if is_name_used_as_error { + format!(".(*{})", oracle().find(type_).type_label()) + } else { + String::from("") + } + } _ => String::from(""), }; Ok(result) diff --git a/bindgen/templates/CallbackInterfaceTemplate.go b/bindgen/templates/CallbackInterfaceTemplate.go index 6bc4a79..10bf275 100644 --- a/bindgen/templates/CallbackInterfaceTemplate.go +++ b/bindgen/templates/CallbackInterfaceTemplate.go @@ -69,7 +69,7 @@ func ({{ foreign_callback }}) {{ method_name }} (callback {{ type_name }}, args {%- endmatch -%} callback.{{ meth.name()|fn_name }}( {%- for arg in meth.arguments() -%} - {{ arg|read_fn }}(reader) + {{ arg|read_fn }}(reader){{arg|error_type_cast(ci.is_name_used_as_error(arg|type_name))}} {%- if !loop.last %}, {% endif -%} {%- endfor -%} ); diff --git a/bindgen/templates/ErrorTemplate.go b/bindgen/templates/ErrorTemplate.go index 2ea583e..84b202d 100644 --- a/bindgen/templates/ErrorTemplate.go +++ b/bindgen/templates/ErrorTemplate.go @@ -110,7 +110,7 @@ func (c {{ e|ffi_converter_name }}) Read(reader io.Reader) error { case {{ loop.index }}: return &{{ type_name|class_name }}{&{{ type_name|class_name }}{{ variant.name()|class_name }}{ {%- for field in variant.fields() %} - {{ field.name()|error_field_name }}: {{ field|read_fn }}(reader){{field|error_type_cast}}, + {{ field.name()|error_field_name }}: {{ field|read_fn }}(reader){{field|error_type_cast(true)}}, {%- endfor %} }} {%- endfor %} diff --git a/fixtures/errors/src/errors.udl b/fixtures/errors/src/errors.udl index 6c1d839..d1dda93 100644 --- a/fixtures/errors/src/errors.udl +++ b/fixtures/errors/src/errors.udl @@ -46,11 +46,21 @@ interface ComplexError { Option(i32? id_a, i32? id_b); }; +enum SomeEnum { + "One", + "Two", +}; + dictionary Vec2 { double x; double y; }; +callback interface Callback { + void do_something(BoobyTrapError error); + void do_something_else(SomeEnum e); +}; + namespace errors { [Throws=BoobyTrapError] diff --git a/fixtures/errors/src/lib.rs b/fixtures/errors/src/lib.rs index 91ccf79..4c51ea4 100644 --- a/fixtures/errors/src/lib.rs +++ b/fixtures/errors/src/lib.rs @@ -45,6 +45,11 @@ pub enum ComplexError { }, } +pub enum SomeEnum { + One, + Two, +} + #[derive(Debug, thiserror::Error)] pub enum NestedError { #[error(transparent)] @@ -182,4 +187,9 @@ fn error_timestamp() -> Result { Err(BoobyTrapError::IceSlip) } +pub trait Callback { + fn do_something(&self, error: BoobyTrapError); + fn do_something_else(&self, a: SomeEnum); +} + include!(concat!(env!("OUT_DIR"), "/errors.uniffi.rs"));