-
-
Notifications
You must be signed in to change notification settings - Fork 521
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
DeriveDisplay macro for enum #1726
Merged
Merged
Changes from 10 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
1f8565e
WIP
darkmmon 2e19da1
WIP
darkmmon 6f1c8f8
WIP
darkmmon 283917d
changed from storing ident to storing TokenStream internally
darkmmon f70b89a
Push for code sharing
darkmmon c1976a8
fmt
darkmmon d52f5a8
changing test target to string
darkmmon 8be294b
updated Display not showing extra single quote, fixed clippy
darkmmon cc7af88
removed DeriveDisplay for test case not using display trait
darkmmon 38ccd41
Merge remote-tracking branch 'sea-orm/master' into DeriveDisplay
darkmmon 9cf66d1
added test cases for display_value attribute
darkmmon 148b718
Merge branch 'master' into pr/1726
billy1624 c85ce1d
Remove useless clone
billy1624 01ab380
Add comment
billy1624 4a2b742
Remove useless clone
billy1624 b28246a
Rename method
billy1624 49d1d3b
Refactoring
billy1624 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 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 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,106 @@ | ||
use proc_macro2::TokenStream; | ||
use quote::{quote, quote_spanned, ToTokens}; | ||
use syn::{LitInt, LitStr}; | ||
|
||
enum Error { | ||
InputNotEnum, | ||
Syn(syn::Error), | ||
} | ||
|
||
struct Display { | ||
ident: syn::Ident, | ||
variants: Vec<DisplayVariant>, | ||
} | ||
|
||
struct DisplayVariant { | ||
ident: syn::Ident, | ||
display_value: TokenStream, | ||
} | ||
|
||
impl Display { | ||
fn new(input: syn::DeriveInput) -> Result<Self, Error> { | ||
let ident = input.ident; | ||
|
||
let variant_vec = match input.data { | ||
syn::Data::Enum(syn::DataEnum { variants, .. }) => variants, | ||
_ => return Err(Error::InputNotEnum), | ||
}; | ||
|
||
let mut variants = Vec::new(); | ||
for variant in variant_vec { | ||
let mut display_value = variant.ident.clone().to_string().to_token_stream(); | ||
for attr in variant.attrs.iter() { | ||
if !attr.path().is_ident("sea_orm") { | ||
continue; | ||
} | ||
attr.parse_nested_meta(|meta| { | ||
if meta.path.is_ident("string_value") { | ||
meta.value()?.parse::<LitStr>()?; | ||
} else if meta.path.is_ident("num_value") { | ||
meta.value()?.parse::<LitInt>()?; | ||
} else if meta.path.is_ident("display_value") { | ||
display_value = meta.value()?.parse::<LitStr>()?.to_token_stream(); | ||
} else { | ||
return Err(meta.error(format!( | ||
"Unknown attribute parameter found: {:?}", | ||
meta.path.get_ident() | ||
))); | ||
} | ||
|
||
Ok(()) | ||
}) | ||
.map_err(Error::Syn)?; | ||
} | ||
variants.push(DisplayVariant { | ||
ident: variant.ident, | ||
display_value, | ||
}); | ||
} | ||
Ok(Display { ident, variants }) | ||
} | ||
|
||
fn expand(&self) -> syn::Result<TokenStream> { | ||
let expanded_impl_active_enum = self.impl_active_enum(); | ||
|
||
Ok(expanded_impl_active_enum) | ||
} | ||
|
||
fn impl_active_enum(&self) -> TokenStream { | ||
let Self { ident, variants } = self; | ||
|
||
let variant_idents: Vec<syn::Ident> = variants | ||
.iter() | ||
.map(|variant| variant.ident.clone()) | ||
.collect(); | ||
|
||
let variant_display: Vec<TokenStream> = variants | ||
.iter() | ||
.map(|variant| variant.display_value.to_owned()) | ||
.collect(); | ||
|
||
quote!( | ||
#[automatically_derived] | ||
impl std::fmt::Display for #ident { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
let v = match self { | ||
#( Self::#variant_idents => #variant_display, )* | ||
} | ||
.to_owned(); | ||
write!(f, "{}", v) | ||
} | ||
} | ||
) | ||
} | ||
} | ||
|
||
pub fn expand_derive_active_enum_display(input: syn::DeriveInput) -> syn::Result<TokenStream> { | ||
let ident_span = input.ident.span(); | ||
|
||
match Display::new(input) { | ||
Ok(model) => model.expand(), | ||
Err(Error::InputNotEnum) => Ok(quote_spanned! { | ||
ident_span => compile_error!("you can only derive EnumDisplay on enums"); | ||
}), | ||
Err(Error::Syn(e)) => Err(e), | ||
} | ||
} |
This file contains 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 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 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 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 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 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
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh wait, actually, did I miss the test case for this? There are no corresponding asserts?
As this is the only place the
display_value
attribute is used.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is the test case.
https://github.com/SeaQL/sea-orm/pull/1726/files#diff-a85e90f626db076a34bb42800eafe047a773a6ef5fe19d05f3a284efb3c16f3aR802-R808