Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for opaque type aliases in generated bindings #1868

Open
arg0d opened this issue Nov 27, 2023 · 3 comments
Open

Support for opaque type aliases in generated bindings #1868

arg0d opened this issue Nov 27, 2023 · 3 comments

Comments

@arg0d
Copy link
Contributor

arg0d commented Nov 27, 2023

With the current type alias implementation, the generated bindings contain transparent type aliases, i.e. new type is not created, its a different name for the underlying type, the alias and the underlying type are the same, and both type alias and the underlying type can be used interchangeably. In Rust, transparent type alias is type A = B;.

It would be useful to also support opaque types, i.e. type alias is an entirely new type, type alias and the underlying type can't be used interchangeably. In Rust, opaque type alias is struct B(A);.

We ran into this in NordSecurity/uniffi-bindgen-cs#40 and NordSecurity/uniffi-bindgen-cs#54, where it would be preferrable to only support opaque type aliases, because transparent type aliases don't work across source files, so transparent type aliases can't be used as External types.

@mhammond
Copy link
Member

Sorry for being so dense on a Monday morning, but what exactly would you like to see changed here? Or point to exactly what the "current type alias implementation" is? I understand that we do use the Rust newtype idiom when defining external types, but don't see how that impacts what binding generators need to do with them.

@Andrepuel
Copy link

On the user guide, on custom types section, the following example is given:

pub struct Handle(i64);

On Python, this is generated as:

# Type alias
Handle = int

Kotlin:

public typealias Handle = Long

Swift:

public typealias Handle = Int64

While on Rust side, we do have a new type. On the generated languages, we have type-aliases. This is undesired on certain API designs were one would like to hide the details.

For instance, suppose you want to expose UUID using uniffi as [Custom] typedef string Uuid. Not any string is a valid UUID. Only those returned by some Uuid generate_v4(); function. And it is very easy to accidentally for the user to provide any string where the original API was expecting an UUID.

For that kind of scenarios, opaque typedef would be more desirable.

The bindgen implementations could make the breaking change of doing opaque typedef anyway. Or alternatively, a new decorator (perhaps [Opaque]) could be added.

@ptitjes
Copy link
Contributor

ptitjes commented Nov 27, 2023

It would really be helpful it those were represented as value classes in Kotlin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants