From a725594cd1e8f5fc2ebbf15f112092d65fd0f5ab Mon Sep 17 00:00:00 2001 From: Sunli Date: Sun, 27 Sep 2020 16:05:25 +0800 Subject: [PATCH] Add `remote` attribute for Enum macro. #276 --- derive/src/args.rs | 12 +++++++++++ derive/src/enum.rs | 54 ++++++++++++++++++++++++++++++++++++++++------ tests/enum.rs | 22 +++++++++++++++++++ 3 files changed, 81 insertions(+), 7 deletions(-) diff --git a/derive/src/args.rs b/derive/src/args.rs index e16694fb..62507a14 100644 --- a/derive/src/args.rs +++ b/derive/src/args.rs @@ -326,6 +326,7 @@ pub struct Enum { pub internal: bool, pub name: Option, pub desc: Option, + pub remote: Option, } impl Enum { @@ -333,6 +334,7 @@ impl Enum { let mut internal = false; let mut name = None; let mut desc = None; + let mut remote = None; for arg in args { match arg { @@ -358,6 +360,15 @@ impl Enum { "Attribute 'desc' should be a string.", )); } + } else if nv.path.is_ident("remote") { + if let syn::Lit::Str(lit) = nv.lit { + remote = Some(lit.value()); + } else { + return Err(Error::new_spanned( + &nv.lit, + "Attribute 'remote' should be a string.", + )); + } } } _ => {} @@ -368,6 +379,7 @@ impl Enum { internal, name, desc, + remote, }) } } diff --git a/derive/src/enum.rs b/derive/src/enum.rs index f2d350c3..0fab3b0f 100644 --- a/derive/src/enum.rs +++ b/derive/src/enum.rs @@ -1,5 +1,5 @@ use crate::args; -use crate::utils::{get_crate_name, get_rustdoc}; +use crate::utils::{get_cfg_attrs, get_crate_name, get_rustdoc}; use inflector::Inflector; use proc_macro::TokenStream; use quote::quote; @@ -39,11 +39,6 @@ pub fn generate(enum_args: &args::Enum, input: &DeriveInput) -> Result>(); let mut item_args = args::EnumItem::parse(&variant.attrs)?; let gql_item_name = item_args .name @@ -59,7 +54,7 @@ pub fn generate(enum_args: &args::Enum, input: &DeriveInput) -> Result Result(remote) { + ty + } else { + return Err(Error::new_spanned( + remote, + format!("Invalid remote type: '{}'", remote), + )); + }; + + let local_to_remote_items = enum_items.iter().map(|(cfg_attrs, item)| { + quote! { + #(#cfg_attrs)* + #ident::#item => #remote_ty::#item, + } + }); + let remote_to_local_items = enum_items.iter().map(|(cfg_attrs, item)| { + quote! { + #(#cfg_attrs)* + #remote_ty::#item => #ident::#item, + } + }); + Some(quote! { + impl ::std::convert::From<#ident> for #remote_ty { + fn from(value: #ident) -> Self { + match value { + #(#local_to_remote_items)* + } + } + } + + impl ::std::convert::From<#remote_ty> for #ident { + fn from(value: #remote_ty) -> Self { + match value { + #(#remote_to_local_items)* + } + } + } + }) + } else { + None + }; + let expanded = quote! { #[allow(clippy::all, clippy::pedantic)] impl #crate_name::resolver_utils::EnumType for #ident { @@ -122,6 +160,8 @@ pub fn generate(enum_args: &args::Enum, input: &DeriveInput) -> Result