-
Notifications
You must be signed in to change notification settings - Fork 212
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
Implement derive macro for ToVariant and FromVariant #189
Conversation
This is really cool, I like it! Apart from the code for the generic bounds this is also relatively simple to follow, it's nice :) |
The code for the generic bounds are initially adapted from |
Yes I saw the comment that it was taken from serde, so no worries. I think this approach is fine and once this is out of draft phase I would have no problem merging this. |
Added derive macro for Rebased on |
If we want fn from_variant(variant: &Variant) -> Option<Self> {
if variant.is_nil() {
Some(None)
}
else {
T::from_variant(variant).map(Some)
}
} ...so it returns But then we can no longer write Added one. |
The macro does the following mapping between Rust structures and Godot types: - `Newtype(inner)` are mapped to `inner` - `Tuple(a, b, c)` are mapped to `[a, b, c]` - `Struct { a, b, c }` are mapped to `{ "a": a, "b": b, "c": c }` - `Unit` are mapped to `{}` - `Enum::Variant(a, b, c)` are mapped to `{ "Variant": [a, b, c] }`
Allows taking and returning `Option<T>`, `Result<T, E>`, and `Vec<T>` directly. Added `FromVariant` wrapper `MaybeNot<T>` with looser semantic than `Option`. Fixes #186.
With Variant conversion traits becoming derivable, type errors are no longer limited to `VariantType` mismatches. The error message is expanded to be more informative for non-primitive types.
The derive macro does the following mapping between Rust structures and Godot types:
Newtype(inner)
is unwrapped toinner
Tuple(a, b, c)
is represented as aVariantArray
([a, b, c]
)Struct { a, b, c }
is represented as aDictionary
({ "a": a, "b": b, "c": c }
)Unit
is represented as an emptyDictionary
({}
)Enum::Variant(a, b, c)
is represented as an externally taggedDictionary
({ "Variant": [a, b, c] }
)For ease of use,
ToVariant
andFromVariant
are also implemented forOption<T>
,Result<T, E>
andVec<T>
.Vec<T>
silently drops values for whichfrom_variant
failed, but the composition withOption<T>
works nicely, in case it's necessary to know which items failed.Support for more collections should probably come in the form of iterator support for Godot types, as there is no real way to return or take a
BTreeMap
from Godot, and maps in general can probably have surprising behaviors when their keys are non-primitive (value equality in Rust vs possibly reference equality in other languages).Fixes #186.