mozilla / uniffi-rs

a multi-language bindings generator for rust
https://mozilla.github.io/uniffi-rs/
Mozilla Public License 2.0
2.48k stars 211 forks source link

First callback interface produces "expected value, found struct variant `Self::Other`" error #1994

Closed AArnott closed 4 months ago

AArnott commented 4 months ago

I added my first callback interface to my udl file, and now uniffi-rs generates code that won't compile.

Here is the UDL I added:

callback interface SyncUpdate {
    [Throws=LightWalletError]
    void update();
};

LightWalletError by the way is defined like this:

[Error]
enum LightWalletError {
    "InvalidUri",
    "InvalidHandle",
    "Other",
};

In rust, my error type is defined as:

#[derive(Debug, thiserror::Error)]
pub enum LightWalletError {
    #[error("Invalid URI")]
    InvalidUri,

    #[error("Invalid handle")]
    InvalidHandle,

    #[error("{message}")]
    Other { message: String },
}

The full error is:

    Checking nerdbank-zcash-rust v0.1.0 (C:\git\Nerdbank.Cryptocurrencies\src\nerdbank-zcash-rust)
error[E0533]: expected value, found struct variant `Self::Other`
  --> C:\git\Nerdbank.Cryptocurrencies\src\nerdbank-zcash-rust\target\x86_64-pc-windows-msvc\debug\build\nerdbank-zcash-rust-efcbc45fe26334c5\out/ffi.uniffi.rs:71:1
   |
71 | / #[::uniffi::derive_error_for_udl(
72 | |     flat_error,
73 | |     with_try_read,
74 | | )]
   | |__^ not a value
   |
   = note: this error originates in the attribute macro `::uniffi::derive_error_for_udl` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0533`.
error: could not compile `nerdbank-zcash-rust` (lib) due to previous error

The generated code around which the error was found is:


#[::uniffi::derive_error_for_udl(
    flat_error,
    with_try_read,
)]
enum r#LightWalletError {
    r#InvalidUri {
    },
    r#InvalidHandle {
    },
    r#Other {
    },
}

Am I doing something wrong?

AArnott commented 4 months ago

When I change the UDL to this:

[Enum]
interface LightWalletError {
    InvalidUri();
    InvalidHandle();
    Other(string message);
};

The error in the generated rust code goes away. But then uniffi-bindgen-cs generates invalid C#. It appears the error type above cannot be attributed as both an error and an enum, and uniffi-bindgen-cs cannot handle an enum interface like above being used as an error type.

mhammond commented 4 months ago

The problem is your Other { message: String }, - this kind of "flat" error must have plain variants. [Error] interface LightWalletError { should work.

AArnott commented 4 months ago

Yup, that worked. Thanks!