Replies: 3 comments 1 reply
-
Some resources shared by Helix on the Rust discord:
Other resources I've found on the topic: |
Beta Was this translation helpful? Give feedback.
-
Hey @NyxCode, I seem to remember an issue asking about |
Beta Was this translation helpful? Give feedback.
-
About the CLI, I believe that if we get it right before we merge, it's probably not gonna be needing to many updates, as, at the end of the day, all it does is gather some config flags and turn them into a |
Beta Was this translation helpful? Give feedback.
-
I initially just wanted to share a few interesting crates i found, but this ended up as a place for me to explore different approaches of how we could achieve coordination between macro invocations, possibly as an alternative to the CLI.
For a while, we've had #304 and #334 open.
I have to admit that I'm somewhat hesitant to get them merged at this time.
For one, I don't really like CLIs. It's an separate tool, yet an other executable users need to install, keep up to date, etc. I feel like the problem we're trying to solve is simple enough that we should get by without one. At least that's my hope.
This doesn't mean I definitely don't want the CLI, but I'm still curious if we can do without.
The main motivation for the CLI is to coordinate between macro invocations. That would allow
The old approach
The obvious solution to all this is to require the exports to be done in one place.
Very early versions had this feature, and we could bring it back in a backwards-compatible fashion.
A problem I had with this in my projects was visibility. All modules and types ended up
pub
lic, just so I could refer to them in one place.That's not a huge deal, but I strongly felt that a tool to generate bindings shouldn't force me to give up encapsulation of modules.
Also, our
#[ts(export)]
is just so damn convenient, and i think it would be sad to make any of this more complicated for our users.The manual approach
To keep encapsulation, modules could export a
pub fn export_bindings(ctx: &mut ExportContext)
, but not their actual types.That could look something like this:
This keeps encapsulation, but is extremely verbose - Especially compared to how convenient our current
#[ts(export)]
is!Maybe a better API and macros could reduce this boilerplate. But I feel like having any boilerplate might be unacceptable to just get some bindings.
The magic approach
There are crates like ctor, inventory, and linkme, which seem very promising although somewhat magical (and hacky) to me.
ctor
ctor allows to run code "before main".
That would, for example, allow us to do shenanigans like this, allowing users to define a global config within rust:
linkme
I do not fully understand how linkme works, but it can "collect"
static
s scattered around the codebase into one single collection.We would define this static collection within ts_rs:
And modify our derive macro to generate the following, which would insert something (a function pointer to the export function, in this example) into that collection:
Now, we would need some entrypoint to start exporting.
Users could define a
#[test] fn export() { ts_rs::export_everything(); }
, or do that in some other fashion.Or we could keep generating export
#[test]
s for every type, but making sure only the first one runs and all subsequent tests do nothing.Whatever the entrypoint would be, there'd only be one call to
ts_rs::export_everything()
.That function would then iterate through the
ts_rs::EXPORTED_TYPES
collection, exporting all the types at once.linkme
could allow users to globally define the config using a macro as well, similar to thector
example above.That macro would also put something into a global collection, which we'd then read when exporting.
The more that I think about this, the more excited I get about
linkme
. But there are still concerns.For one,
linkme
manually supports a variety of platforms. The big ones are supported, but WebAssembly does not seem to be amongst them currently.The whole library seems to work by somewhat abusing the linker, which does seem a bit hacky (though I don't understand it enough to make that judgement). If we only had this capability in the standard library..
inventory
inventory seems like it would provide us with the same affordances as
linkme
, though possibly with less concerns about platform support (and general hackiness).Beta Was this translation helpful? Give feedback.
All reactions