-
-
Notifications
You must be signed in to change notification settings - Fork 210
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
Rewrite the ToGodot
and FromGodot
derive macros
#452
Comments
Current behavior: Every type has
Some notes. We could use a The default would likely be a dictionary, like we do currently. If the type also derives Some ideas for reprs, names up for bikeshedding
|
Maybe a general design question, how much configurability should the Some features like choosing int/string for enums seem to be quite common, but others like representing a struct with named fields as an array are very niche. I would stay we start with opinionated defaults (no configurability beyond enum) and then add extra features one at a time, individually motivated by use cases.
I think those are a good start, but we might need more data to see whether these are good defaults (e.g. whether the type name is often required). |
I think implementation could guide usage, there's a pretty solid case imo for not including the name by default. For instance if you were to nest structs to create a nested dictionary, you'd probably want the key names (ie. struct fields) to correspond directly to the underlying dict, instead of a dict containing it's name and fields. If the name is included by default, you'd have to opt out of that either at the field level (which I would deem unacceptable) or at the struct level, unless we want to dynamically determine whether any given instance is inside another struct. To me, passing out a dict with one member listed by name seems like a less common pattern than using them in a way that actually emulates a struct. Enums and tuple structs are where I'd expect to see names used on occasion, but even then, I think common usage would be using them as variables and using the enum variants or inner field of a tuple struct directly. In fact, we should consider the usecase for |
Fully agree, I think including the name by default is the wrong choice. Ideally we approach a new design in a pragmatic way:
What makes these derive macros painful is to get generics right with all the syntax like |
Maybe It may not be the most idiomatic (what a surprise in godot-rust 😁) -- but it's likely what 95% of users need, and it's similar to what we already do with |
LOL I was actually typing exactly the same sentiments (concerns about idiomatic rust and the futility of worrying too much about idiomatic rust in godot-rust included). I'm wondering is what's the use case for The opt out would handle the case where you have a more optimized/customized implementation of one of the traits pretty nicely, and I think that the first error the engine gives you is about |
If |
Honestly my most common use-case for manually implementing these is for making enums that i wanna use with godot, and have them either become strings or ints.
Im not sure how this should work. You should not implement both
most of the time you want both. but sometimes you can only really have one. like |
I won't pretend I realized all of that, but I did realize that the traits were somewhat orthogonal, which is why I crossed it out. It might be possible to error on anything that contained a lifetime or reference when trying to derive both, but I still think the auto-deriving idea has legs. The string-int case for enums is honestly probably useful and common enough to be a feature straight away. |
So initially i think we can support these cases:
that should cover at least the main use-cases that i think have been brought up (at least the ones i face mostly). most other cases for converting between rust types and godot types are likely better covered by |
Sounds good! However, if we're changing this, we should probably move away from mixing Rust's We will anyway need customization beyond what's supported in I'm not sure what we could use; gdnative used |
i dont think
initially we will only support:
We can also require explicit discriminants in the last case, or that there's either only inferred or only explicit discriminants. I think doing some simple inference here is fine, it's not very complicated and is more convenient. So some examples: // -----------------------
// newtype structs
#[derive(GodotConvert, ToGodot, FromGodot)]
#[godot(transparent)]
// Via = Vector2
struct MyVector2(Vector2);
#[derive(GodotConvert, ToGodot, FromGodot)]
#[godot(transparent)]
// Via = Dictionary
struct DictionaryWrapper {
dictionary: Dictionary,
}
// this would error:
#[derive(GodotConvert, ToGodot, FromGodot)]
#[godot(transparent)]
struct DictionaryWrapper {
dictionary: Dictionary,
extra_info: SomeData,
}
// -----------------------
// stringy enums
#[derive(GodotConvert, ToGodot, FromGodot)]
#[godot(via = GString)]
pub enum MyEnum {
A = 0, // becomes "A"
B = 1 + 1, // becomes "B"
SomeVariant, // becomes "SomeVariant"
// would error:
// C(u64),
// C { value: u64 },
}
// -----------------------
// inty enums
#[derive(GodotConvert, ToGodot, FromGodot)]
#[godot(via = i32)]
pub enum MyEnum {
A = 3,
B, // inferred to be 1, since 0 is taken
C, // inferred to be 2, since 0 and 1 are taken
D = 0,
E, // inferred to be 4, since 0, 1, and 2, are now taken
// not allowed:
// F = (10 * 2),
// F(u64),
// F { value: u64 }
} Future possibilities
|
That looks great! I like the
|
The current
ToGodot
andFromGodot
derive macros are as of #421 just a hacky adaptation of the previousToVariant
andFromVariant
derive macros.We should rewrite this and possibly merge it with the
Property
derive macro to create conversions that use more than justVariant
as the backing type.We might want to wait with this until #451 is done.
The text was updated successfully, but these errors were encountered: