Fix async_graphql::Object does not work when inside macro after rust 1.48.0

This commit is contained in:
Sunli 2020-11-22 09:53:18 +08:00
parent 5c9f25662e
commit 12b3b0ee46
5 changed files with 97 additions and 38 deletions

View File

@ -7,8 +7,8 @@ use crate::args::{self, RenameRuleExt, RenameTarget};
use crate::output_type::OutputType;
use crate::utils::{
generate_default, generate_guards, generate_validator, get_cfg_attrs, get_crate_name,
get_param_getter_ident, get_rustdoc, parse_graphql_attrs, remove_graphql_attrs,
GeneratorResult,
get_param_getter_ident, get_rustdoc, get_type_path_and_name, parse_graphql_attrs,
remove_graphql_attrs, GeneratorResult,
};
pub fn generate(
@ -16,17 +16,7 @@ pub fn generate(
item_impl: &mut ItemImpl,
) -> GeneratorResult<TokenStream> {
let crate_name = get_crate_name(object_args.internal);
let (self_ty, self_name) = match item_impl.self_ty.as_ref() {
Type::Path(path) => (
path,
path.path
.segments
.last()
.map(|s| s.ident.to_string())
.unwrap(),
),
_ => return Err(Error::new_spanned(&item_impl.self_ty, "Invalid type").into()),
};
let (self_ty, self_name) = get_type_path_and_name(item_impl.self_ty.as_ref())?;
let generics = &item_impl.generics;
let where_clause = &item_impl.generics.where_clause;
let extends = object_args.extends;

View File

@ -1,24 +1,16 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::{Error, ItemImpl, Type};
use syn::ItemImpl;
use crate::args::{self, RenameTarget};
use crate::utils::{get_crate_name, get_rustdoc, GeneratorResult};
use crate::utils::{get_crate_name, get_rustdoc, get_type_path_and_name, GeneratorResult};
pub fn generate(
scalar_args: &args::Scalar,
item_impl: &mut ItemImpl,
) -> GeneratorResult<TokenStream> {
let crate_name = get_crate_name(scalar_args.internal);
let self_name = match item_impl.self_ty.as_ref() {
Type::Path(path) => path
.path
.segments
.last()
.map(|s| s.ident.to_string())
.unwrap(),
_ => return Err(Error::new_spanned(&item_impl.self_ty, "Invalid type").into()),
};
let self_name = get_type_path_and_name(item_impl.self_ty.as_ref())?.1;
let gql_typename = scalar_args
.name
.clone()

View File

@ -10,8 +10,8 @@ use crate::args::{self, RenameRuleExt, RenameTarget, SubscriptionField};
use crate::output_type::OutputType;
use crate::utils::{
generate_default, generate_guards, generate_validator, get_cfg_attrs, get_crate_name,
get_param_getter_ident, get_rustdoc, parse_graphql_attrs, remove_graphql_attrs,
GeneratorResult,
get_param_getter_ident, get_rustdoc, get_type_path_and_name, parse_graphql_attrs,
remove_graphql_attrs, GeneratorResult,
};
pub fn generate(
@ -19,17 +19,7 @@ pub fn generate(
item_impl: &mut ItemImpl,
) -> GeneratorResult<TokenStream> {
let crate_name = get_crate_name(subscription_args.internal);
let (self_ty, self_name) = match item_impl.self_ty.as_ref() {
Type::Path(path) => (
path,
path.path
.segments
.last()
.map(|s| s.ident.to_string())
.unwrap(),
),
_ => return Err(Error::new_spanned(&item_impl.self_ty, "Invalid type").into()),
};
let (self_ty, self_name) = get_type_path_and_name(item_impl.self_ty.as_ref())?;
let generics = &item_impl.generics;
let where_clause = &generics.where_clause;

View File

@ -2,7 +2,9 @@ use darling::FromMeta;
use proc_macro2::{Span, TokenStream, TokenTree};
use proc_macro_crate::crate_name;
use quote::quote;
use syn::{Attribute, Error, Expr, Ident, Lit, LitStr, Meta, NestedMeta};
use syn::{
Attribute, Error, Expr, Ident, Lit, LitStr, Meta, NestedMeta, Type, TypeGroup, TypePath,
};
use thiserror::Error;
use crate::args;
@ -372,3 +374,18 @@ pub fn remove_graphql_attrs(attrs: &mut Vec<Attribute>) {
attrs.remove(idx);
}
}
pub fn get_type_path_and_name(ty: &Type) -> GeneratorResult<(&TypePath, String)> {
match ty {
Type::Path(path) => Ok((
path,
path.path
.segments
.last()
.map(|s| s.ident.to_string())
.unwrap(),
)),
Type::Group(TypeGroup { elem, .. }) => get_type_path_and_name(&elem),
_ => return Err(Error::new_spanned(ty, "Invalid type").into()),
}
}

View File

@ -0,0 +1,70 @@
#[async_std::test]
pub async fn test_object() {
macro_rules! test_data {
($test_name:ident) => {
#[derive(Debug, Clone)]
pub struct $test_name {
value: i32,
}
#[async_graphql::Object]
impl $test_name {
async fn value(&self) -> i32 {
self.value
}
}
};
}
test_data!(A);
}
#[async_std::test]
pub async fn test_subscription() {
macro_rules! test_data {
($test_name:ident) => {
#[derive(Debug, Clone)]
pub struct $test_name {
value: i32,
}
#[async_graphql::Subscription]
impl $test_name {
async fn value(&self) -> impl futures_util::stream::Stream<Item = i32> + 'static {
let value = self.value;
futures_util::stream::once(async move { value })
}
}
};
}
test_data!(A);
}
#[async_std::test]
pub async fn test_scalar() {
macro_rules! test_data {
($test_name:ident) => {
#[derive(Debug, Clone)]
pub struct $test_name(i64);
#[async_graphql::Scalar]
impl async_graphql::ScalarType for $test_name {
fn parse(value: async_graphql::Value) -> async_graphql::InputValueResult<Self> {
match value {
async_graphql::Value::Number(n) if n.is_i64() => {
Ok($test_name(n.as_i64().unwrap()))
}
_ => Err(async_graphql::InputValueError::expected_type(value)),
}
}
fn to_value(&self) -> async_graphql::Value {
self.0.to_value()
}
}
};
}
test_data!(A);
}