NordSecurity / uniffi-bindgen-go

Uniffi bindings generator for Golang
Mozilla Public License 2.0
75 stars 21 forks source link

invalid map key type `{type}` #52

Open pacu opened 3 months ago

pacu commented 3 months ago

when generating bindings for Go, the generated code fails with invalid map key type ParticipantIdentifier

Example:

this struct is equatable yet, GoLang bindings don't generate code to make ParticipantIdentifier comparable in GoLang

note: this is not an issue on generated Swift Bindings

#[derive(uniffi::Record, Hash, Eq, PartialEq, Clone)]
pub struct ParticipantIdentifier {
    pub data: Vec<u8>,
}

#[derive(uniffi::Record)]
pub struct TrustedKeyGeneration {
    pub secret_shares: HashMap<ParticipantIdentifier, FrostSecretKeyShare>,
    pub public_key_package: FrostPublicKeyPackage,
}

This generates these two types in Go

type TrustedKeyGeneration struct {
    SecretShares     map[ParticipantIdentifier]FrostSecretKeyShare
    PublicKeyPackage FrostPublicKeyPackage
}

type ParticipantIdentifier struct {
    Data []byte
}

But there is not generated code to honor the Eq proc macro and make it possible for ParticipantIdentifier to be used as key on a map because the byte[] type is not comparable.

Edit: This might not have a simple solution. If someone is running into this problem you probably want to encode your bytes into a comparable primitive type. It's not ideal, but it works. For example, encode the data into a hex string using hex crate in Rust

arg0d commented 3 months ago

In Go, slices can't be used as map keys. Any ideas what to do in this case?

pacu commented 3 months ago

I ended up using a String but it's not ideal. Maybe the FFI code could actually create an intermediate type that it's actually comparable?

arg0d commented 3 months ago

I'm not super deep into Go, but from some light reading and asking ChatGPT, it does not seem possible to make arbitrary types compatible as map keys. In Go fixed-size arrays are valid map keys, but variable sized-arrays (slices) are not.

I think for your use case a fixed size array would work just as well, but unfortunately it looks like uniffi-rs upstream does not support fixed-size arrays.