-
-
Notifications
You must be signed in to change notification settings - Fork 88
Improve FromMeta implementation for enums
#260
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
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
233b60c
Improve FromMeta implementation for enums
davidsemakula 95232f2
Revert FromMeta::from_string implementation and impl Default to fix M…
davidsemakula 5648926
Add #[darling(word)] for unit enum variants
davidsemakula 2356ac2
FromMeta implementation style improvements
davidsemakula 99f3597
Improve #[darling(word)] validation
davidsemakula e28928b
Add another #[darling(word)] ui test
davidsemakula f34bce6
Update #[darling(word)] duplicate error message and fix ui tests
davidsemakula 3a5a633
Revert FromMeta::from_list behaviour for empty lists
davidsemakula 778b58b
Refactor FromMeta enum tests
davidsemakula 3160677
Update changelog
davidsemakula 3f07d29
Add example for deriving FromMeta for heterogeneous enums and using t…
davidsemakula b95551c
Update custom error to use #[darling(word)]
davidsemakula 03d781a
Update #[darling(word)] ui test
davidsemakula e27d2f7
Style and docs improvements
davidsemakula File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| //! This example demonstrates: | ||
| //! | ||
| //! - The behavior of a derived `FromMeta` implementation for heterogeneous enums | ||
| //! (i.e. enums that include a mix of unit, newtype and struct variants). | ||
| //! - Using `#[darling(word)]` to specify a unit variant to use when a receiver field | ||
| //! is specified without a value (i.e. a unit variant to use for deriving the | ||
| //! `FromMeta::from_word` method). | ||
| //! - Using `#[darling(default)]` on a receiver field to fall back to `Default::default()` | ||
| //! for the enum's value when the receiver field is not specified by the caller. | ||
|
|
||
| use darling::{Error, FromDeriveInput, FromMeta}; | ||
| use syn::parse_quote; | ||
|
|
||
| /// A playback volume. | ||
| #[derive(Debug, FromMeta, PartialEq, Eq)] | ||
| enum Volume { | ||
| Normal, | ||
| #[darling(word)] | ||
| Low, | ||
| High, | ||
| #[darling(rename = "dB")] | ||
| Decibels(u8), | ||
| } | ||
|
|
||
| impl Default for Volume { | ||
| fn default() -> Self { | ||
| Volume::Normal | ||
| } | ||
| } | ||
|
|
||
| #[derive(Debug, FromDeriveInput)] | ||
| #[darling(attributes(play))] | ||
| struct PlayReceiver { | ||
| #[darling(default)] | ||
| volume: Volume, | ||
| } | ||
|
|
||
| fn main() { | ||
| // `Default::default()` is used when `volume` is not specified. | ||
| let missing_volume = PlayReceiver::from_derive_input(&parse_quote! { | ||
| #[play] | ||
| struct Player; | ||
| }) | ||
| .unwrap(); | ||
| assert_eq!(Volume::Normal, missing_volume.volume); | ||
|
|
||
| // `#[darling(word)]` unit variant is used when `volume` is specified as a word with no value. | ||
| let empty_volume = PlayReceiver::from_derive_input(&parse_quote! { | ||
| #[play(volume)] | ||
| struct Player; | ||
| }) | ||
| .unwrap(); | ||
| assert_eq!(Volume::Low, empty_volume.volume); | ||
|
|
||
| // Specified `volume` value is used when provided. | ||
| let unit_variant_volume = PlayReceiver::from_derive_input(&parse_quote! { | ||
| #[play(volume(high))] | ||
| struct Player; | ||
| }) | ||
| .unwrap(); | ||
| assert_eq!(Volume::High, unit_variant_volume.volume); | ||
| let newtype_volume = PlayReceiver::from_derive_input(&parse_quote! { | ||
| #[play(volume(dB = 100))] | ||
| struct Player; | ||
| }) | ||
| .unwrap(); | ||
| assert_eq!(Volume::Decibels(100), newtype_volume.volume); | ||
|
|
||
| // Multiple `volume` values result in an error. | ||
| let err = PlayReceiver::from_derive_input(&parse_quote! { | ||
| #[play(volume(low, dB = 20))] | ||
| struct Player; | ||
| }) | ||
| .unwrap_err(); | ||
| assert_eq!( | ||
| err.to_string(), | ||
| Error::too_many_items(1).at("volume").to_string() | ||
| ); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| use darling::FromMeta; | ||
|
|
||
| #[derive(FromMeta)] | ||
| enum Choice { | ||
| #[darling(word)] | ||
| A, | ||
| #[darling(word)] | ||
| B, | ||
| C, | ||
| } | ||
|
|
||
| fn main() {} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| error: `#[darling(word)]` can only be applied to one variant | ||
| --> tests/compile-fail/duplicate_word_across_variants.rs:5:15 | ||
| | | ||
| 5 | #[darling(word)] | ||
| | ^^^^ | ||
|
|
||
| error: `#[darling(word)]` can only be applied to one variant | ||
| --> tests/compile-fail/duplicate_word_across_variants.rs:7:15 | ||
| | | ||
| 7 | #[darling(word)] | ||
| | ^^^^ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| use darling::FromMeta; | ||
|
|
||
| #[derive(FromMeta)] | ||
| enum Choice { | ||
| #[darling(word, word)] | ||
| A, | ||
| B, | ||
| } | ||
|
|
||
| fn main() {} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| error: Duplicate field `word` | ||
| --> tests/compile-fail/duplicate_word_on_variant.rs:5:21 | ||
| | | ||
| 5 | #[darling(word, word)] | ||
| | ^^^^ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| use darling::FromMeta; | ||
|
|
||
| #[derive(FromMeta)] | ||
| enum Meta { | ||
| Unit, | ||
| #[darling(word)] | ||
| NotUnit(String) | ||
| } | ||
|
|
||
| fn main() {} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| error: Unexpected field: `word`. `#[darling(word)]` can only be applied to a unit variant | ||
| --> tests/compile-fail/word_on_wrong_variant_type.rs:6:15 | ||
| | | ||
| 6 | #[darling(word)] | ||
| | ^^^^ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| use darling::{FromDeriveInput, FromMeta}; | ||
| use syn::parse_quote; | ||
|
|
||
| #[derive(Debug, FromMeta, PartialEq, Eq)] | ||
| enum Dolor { | ||
| Sit, | ||
| #[darling(word)] | ||
| Amet, | ||
| } | ||
|
|
||
| impl Default for Dolor { | ||
| fn default() -> Self { | ||
| Dolor::Sit | ||
| } | ||
| } | ||
|
|
||
| #[derive(FromDeriveInput)] | ||
| #[darling(attributes(hello))] | ||
| struct Receiver { | ||
| #[darling(default)] | ||
| example: Dolor, | ||
| } | ||
|
|
||
| #[test] | ||
| fn missing_meta() { | ||
| let di = Receiver::from_derive_input(&parse_quote! { | ||
| #[hello] | ||
| struct Example; | ||
| }) | ||
| .unwrap(); | ||
|
|
||
| assert_eq!(Dolor::Sit, di.example); | ||
| } | ||
|
|
||
| #[test] | ||
| fn empty_meta() { | ||
| let di = Receiver::from_derive_input(&parse_quote! { | ||
| #[hello(example)] | ||
| struct Example; | ||
| }) | ||
| .unwrap(); | ||
|
|
||
| assert_eq!(Dolor::Amet, di.example); | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.