Support macro type in enum variant
This commit is contained in:
parent
aa15be435a
commit
fe77b329a0
|
@ -60,9 +60,14 @@ pub fn generate(union_args: &args::Union) -> GeneratorResult<TokenStream> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Type::Path(p) = &ty {
|
let mut ty = ty;
|
||||||
|
while let Type::Group(group) = ty {
|
||||||
|
ty = &*group.elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
if matches!(ty, Type::Path(_) | Type::Macro(_)) {
|
||||||
// This validates that the field type wasn't already used
|
// This validates that the field type wasn't already used
|
||||||
if !enum_items.insert(p) {
|
if !enum_items.insert(ty) {
|
||||||
return Err(
|
return Err(
|
||||||
Error::new_spanned(&ty, "This type already used in another variant").into(),
|
Error::new_spanned(&ty, "This type already used in another variant").into(),
|
||||||
);
|
);
|
||||||
|
@ -70,16 +75,16 @@ pub fn generate(union_args: &args::Union) -> GeneratorResult<TokenStream> {
|
||||||
|
|
||||||
enum_names.push(enum_name);
|
enum_names.push(enum_name);
|
||||||
|
|
||||||
let mut assert_ty = p.clone();
|
let mut assert_ty = ty.clone();
|
||||||
RemoveLifetime.visit_type_path_mut(&mut assert_ty);
|
RemoveLifetime.visit_type_mut(&mut assert_ty);
|
||||||
|
|
||||||
if !variant.flatten {
|
if !variant.flatten {
|
||||||
type_into_impls.push(quote! {
|
type_into_impls.push(quote! {
|
||||||
#crate_name::static_assertions::assert_impl_one!(#assert_ty: #crate_name::ObjectType);
|
#crate_name::static_assertions::assert_impl_one!(#assert_ty: #crate_name::ObjectType);
|
||||||
|
|
||||||
#[allow(clippy::all, clippy::pedantic)]
|
#[allow(clippy::all, clippy::pedantic)]
|
||||||
impl #impl_generics ::std::convert::From<#p> for #ident #ty_generics #where_clause {
|
impl #impl_generics ::std::convert::From<#ty> for #ident #ty_generics #where_clause {
|
||||||
fn from(obj: #p) -> Self {
|
fn from(obj: #ty) -> Self {
|
||||||
#ident::#enum_name(obj)
|
#ident::#enum_name(obj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,8 +94,8 @@ pub fn generate(union_args: &args::Union) -> GeneratorResult<TokenStream> {
|
||||||
#crate_name::static_assertions::assert_impl_one!(#assert_ty: #crate_name::UnionType);
|
#crate_name::static_assertions::assert_impl_one!(#assert_ty: #crate_name::UnionType);
|
||||||
|
|
||||||
#[allow(clippy::all, clippy::pedantic)]
|
#[allow(clippy::all, clippy::pedantic)]
|
||||||
impl #impl_generics ::std::convert::From<#p> for #ident #ty_generics #where_clause {
|
impl #impl_generics ::std::convert::From<#ty> for #ident #ty_generics #where_clause {
|
||||||
fn from(obj: #p) -> Self {
|
fn from(obj: #ty) -> Self {
|
||||||
#ident::#enum_name(obj)
|
#ident::#enum_name(obj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,15 +104,15 @@ pub fn generate(union_args: &args::Union) -> GeneratorResult<TokenStream> {
|
||||||
|
|
||||||
if !variant.flatten {
|
if !variant.flatten {
|
||||||
registry_types.push(quote! {
|
registry_types.push(quote! {
|
||||||
<#p as #crate_name::OutputType>::create_type_info(registry);
|
<#ty as #crate_name::OutputType>::create_type_info(registry);
|
||||||
});
|
});
|
||||||
possible_types.push(quote! {
|
possible_types.push(quote! {
|
||||||
possible_types.insert(<#p as #crate_name::OutputType>::type_name().into_owned());
|
possible_types.insert(<#ty as #crate_name::OutputType>::type_name().into_owned());
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
possible_types.push(quote! {
|
possible_types.push(quote! {
|
||||||
if let #crate_name::registry::MetaType::Union { possible_types: possible_types2, .. } =
|
if let #crate_name::registry::MetaType::Union { possible_types: possible_types2, .. } =
|
||||||
registry.create_fake_output_type::<#p>() {
|
registry.create_fake_output_type::<#ty>() {
|
||||||
possible_types.extend(possible_types2);
|
possible_types.extend(possible_types2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -115,11 +120,11 @@ pub fn generate(union_args: &args::Union) -> GeneratorResult<TokenStream> {
|
||||||
|
|
||||||
if !variant.flatten {
|
if !variant.flatten {
|
||||||
get_introspection_typename.push(quote! {
|
get_introspection_typename.push(quote! {
|
||||||
#ident::#enum_name(obj) => <#p as #crate_name::OutputType>::type_name()
|
#ident::#enum_name(obj) => <#ty as #crate_name::OutputType>::type_name()
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
get_introspection_typename.push(quote! {
|
get_introspection_typename.push(quote! {
|
||||||
#ident::#enum_name(obj) => <#p as #crate_name::OutputType>::introspection_type_name(obj)
|
#ident::#enum_name(obj) => <#ty as #crate_name::OutputType>::introspection_type_name(obj)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -419,3 +419,24 @@ pub async fn test_trait_object_in_union() {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! generate_union {
|
||||||
|
($name:ident, $variant_ty:ty) => {
|
||||||
|
#[derive(Union)]
|
||||||
|
pub enum $name {
|
||||||
|
Val($variant_ty),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn test_macro_generated_union() {
|
||||||
|
#[derive(SimpleObject)]
|
||||||
|
pub struct IntObj {
|
||||||
|
pub val: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_union!(MyEnum, IntObj);
|
||||||
|
|
||||||
|
let _ = MyEnum::Val(IntObj { val: 1 });
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue