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

DISCUSS: Proc macro / UDL for Swift property wrappers and macro annotations #2097

Closed
cadnza opened this issue May 8, 2024 · 6 comments
Closed

Comments

@cadnza
Copy link

cadnza commented May 8, 2024

As far as I can tell, UniFFI doesn't have a way to apply property wrappers or macro annotations to types and properties in Swift, so generating this example of the @ObservedObject property wrapper using UniFFI is impossible:

struct BookView: View {
    @ObservedObject var book: Book
    
    var body: some View {
        Text(book.title)
    }
}

Generating this example of the @Observable macro is also impossible:

@Observable class Library {
    var books: [Book] = [Book(), Book(), Book()]
}

Property wrappers and macro annotations are used extensively in SwiftUI, so being able to specify them via proc macro or UDL would be wonderful.

To be clear: Property wrappers and macro annotations have uses outside SwiftUI, but SwiftUI is my primary interest.

Two considerations:

  1. Naturally this is Swift-specific, so it would likely need to be either generalized into a feature that applies to all supported languages or tagged in the declaration as only applying to Swift.
  2. The fact that something like this doesn't exist yet in spite of UniFFI's popularity seems to imply that either 1) it actually does exist and I just don't know about it or 2) it doesn't exist, but there's already a UniFFI convention for generating SwiftUI-ready Swift code that makes this feature unneeded.

Anyway, I'm happy to write the feature if it'd be useful, but first it's worth asking:

  • Would this be useful at all? Or is there already something that more or less does this?
  • If this would be useful, how would we like to see it done: as a Swift-specific feature or as something more general?
@cadnza
Copy link
Author

cadnza commented May 8, 2024

Property wrappers and macro annotations should also accept parameters such that it would be possible to generate this example of the @SmallNumber property wrapper defined in tutorial:

struct NarrowRectangle {
    @SmallNumber(wrappedValue: 2, maximum: 5) var height: Int
    @SmallNumber(wrappedValue: 3, maximum: 4) var width: Int
}

@cadnza
Copy link
Author

cadnza commented May 8, 2024

Also, I don't see much of a need for UniFFI to define Swift property wrappers or macros—it should only need to apply them. So if you attach e.g. #[uniffi::swift_macro(tasty(tastiness = 3))] to a struct, it should take it on faith that the @tasty macro already has a definition somewhere on the Swift side and then proceed to blindly apply the @tasty(tastiness: 3) annotation to the generated Swift type. Done that way, UniFFI can remain reasonably decoupled from the Swift release cycle in terms of property wrappers and macros, and UniFFI can apply any property wrapper or macro that exists anywhere on the Swift side.

@cadnza cadnza changed the title Proc macro / UDL for Swift property wrappers and macro annotations DISCUSS: Proc macro / UDL for Swift property wrappers and macro annotations May 8, 2024
@mhammond
Copy link
Member

That sounds great, but difficult to express in UniFFI's model. Happy to help if you want to have a start at this though.

@cadnza
Copy link
Author

cadnza commented May 22, 2024

@mhammond Thanks! Turns out there's already a convention for writing SwiftUI code with UniFFI, and it's a lot less complicated and more sustainable than this feature would be 😄 Thanks for humoring my whim. Closing as not planned.

@cadnza cadnza closed this as not planned Won't fix, can't repro, duplicate, stale May 22, 2024
@GraniteLake
Copy link

@cadnza What is the convention for writing SwiftUI code with UniFFI with regard to having a view update when a field in a UniFFi Interface / rust struct changes?

@cadnza
Copy link
Author

cadnza commented Jun 5, 2024

@cadnza What is the convention for writing SwiftUI code with UniFFI with regard to having a view update when a field in a UniFFi Interface / rust struct changes?

@GraniteLake As far as I understand—first pointing out how wide and varied my lack of experience is with this—the way it's usually done is by writing an intermediary stuct/class in Swift that wraps UniFFI's class and adds SwiftUI's property wrappers and macro annotations. As far as how you get UniFFI to update the struct based on those wrappers and annotations, I'm not sure, but something along those lines is what I've been seeing going through other peoples' code.

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

3 participants