Field method must be async asynchronous

Support for synchronization functions doe provide performance improvement
This commit is contained in:
sunli 2020-03-28 20:11:26 +08:00
parent 169e32555f
commit 643213206b
7 changed files with 41 additions and 40 deletions

View File

@ -39,7 +39,13 @@ pub fn generate(object_args: &args::Object, item_impl: &mut ItemImpl) -> Result<
for item in &mut item_impl.items {
if let ImplItem::Method(method) = item {
if let Some(field) = args::Field::parse(&method.attrs)? {
let is_async = method.sig.asyncness.is_some();
if method.sig.asyncness.is_none() {
return Err(Error::new_spanned(
&method.sig.output,
"Must be asynchronous",
));
}
let field_name = field
.name
.clone()
@ -196,18 +202,13 @@ pub fn generate(object_args: &args::Object, item_impl: &mut ItemImpl) -> Result<
};
let field_ident = &method.sig.ident;
let await_resolve = if is_async {
quote! { .await }
} else {
quote! {}
};
let resolve_obj = match &ty {
OutputType::Value(_) => quote! {
self.#field_ident(#ctx_field #(#use_params),*)#await_resolve
self.#field_ident(#ctx_field #(#use_params),*).await
},
OutputType::Result(_, _) => {
quote! {
self.#field_ident(#ctx_field #(#use_params),*)#await_resolve.
self.#field_ident(#ctx_field #(#use_params),*).await.
map_err(|err| err.with_position(field.position))?
}
}

View File

@ -79,22 +79,22 @@ In some cases, you need to provide options to alter GraphQL's execution behavior
)]
impl<'a> __Directive<'a> {
#[field]
fn name(&self) -> String {
async fn name(&self) -> String {
self.directive.name.to_string()
}
#[field]
fn description(&self) -> Option<String> {
async fn description(&self) -> Option<String> {
self.directive.description.map(|s| s.to_string())
}
#[field]
fn locations(&self) -> &Vec<__DirectiveLocation> {
async fn locations(&self) -> &Vec<__DirectiveLocation> {
&self.directive.locations
}
#[field]
fn args(&self) -> Vec<__InputValue<'a>> {
async fn args(&self) -> Vec<__InputValue<'a>> {
self.directive
.args
.values()

View File

@ -12,22 +12,22 @@ pub struct __EnumValue<'a> {
)]
impl<'a> __EnumValue<'a> {
#[field]
fn name(&self, _: &Context<'_>) -> String {
async fn name(&self, _: &Context<'_>) -> String {
self.value.name.to_string()
}
#[field]
fn description(&self, _: &Context<'_>) -> Option<String> {
async fn description(&self, _: &Context<'_>) -> Option<String> {
self.value.description.map(|s| s.to_string())
}
#[field]
fn is_deprecated(&self, _: &Context<'_>) -> bool {
async fn is_deprecated(&self, _: &Context<'_>) -> bool {
self.value.deprecation.is_some()
}
#[field]
fn deprecation_reason(&self, _: &Context<'_>) -> Option<String> {
async fn deprecation_reason(&self, _: &Context<'_>) -> Option<String> {
self.value.deprecation.map(|s| s.to_string())
}
}

View File

@ -13,17 +13,17 @@ pub struct __Field<'a> {
)]
impl<'a> __Field<'a> {
#[field]
fn name(&self) -> String {
async fn name(&self) -> String {
self.field.name.to_string()
}
#[field]
fn description(&self) -> Option<String> {
async fn description(&self) -> Option<String> {
self.field.description.map(|s| s.to_string())
}
#[field]
fn args(&self) -> Vec<__InputValue<'a>> {
async fn args(&self) -> Vec<__InputValue<'a>> {
let mut args = self
.field
.args
@ -38,17 +38,17 @@ impl<'a> __Field<'a> {
}
#[field(name = "type")]
fn ty(&self) -> __Type<'a> {
async fn ty(&self) -> __Type<'a> {
__Type::new(self.registry, &self.field.ty)
}
#[field]
fn is_deprecated(&self) -> bool {
async fn is_deprecated(&self) -> bool {
self.field.deprecation.is_some()
}
#[field]
fn deprecation_reason(&self) -> Option<String> {
async fn deprecation_reason(&self) -> Option<String> {
self.field.deprecation.map(|s| s.to_string())
}
}

View File

@ -13,22 +13,22 @@ pub struct __InputValue<'a> {
)]
impl<'a> __InputValue<'a> {
#[field]
fn name(&self) -> String {
async fn name(&self) -> String {
self.input_value.name.to_string()
}
#[field]
fn description(&self) -> Option<String> {
async fn description(&self) -> Option<String> {
self.input_value.description.map(|s| s.to_string())
}
#[field(name = "type")]
fn ty(&self) -> __Type<'a> {
async fn ty(&self) -> __Type<'a> {
__Type::new(self.registry, &self.input_value.ty)
}
#[field]
fn default_value(&self) -> Option<String> {
async fn default_value(&self) -> Option<String> {
self.input_value.default_value.map(|s| s.to_string())
}
}

View File

@ -12,7 +12,7 @@ pub struct __Schema<'a> {
)]
impl<'a> __Schema<'a> {
#[field(desc = "A list of all types supported by this server.")]
fn types(&self) -> Vec<__Type<'a>> {
async fn types(&self) -> Vec<__Type<'a>> {
self.registry
.types
.values()
@ -21,7 +21,7 @@ impl<'a> __Schema<'a> {
}
#[field(desc = "The type that query operations will be rooted at.")]
fn query_type(&self) -> __Type<'a> {
async fn query_type(&self) -> __Type<'a> {
__Type::new_simple(
self.registry,
&self.registry.types[&self.registry.query_type],
@ -31,7 +31,7 @@ impl<'a> __Schema<'a> {
#[field(
desc = "If this server supports mutation, the type that mutation operations will be rooted at."
)]
fn mutation_type(&self) -> Option<__Type<'a>> {
async fn mutation_type(&self) -> Option<__Type<'a>> {
if let Some(ty) = &self.registry.mutation_type {
Some(__Type::new_simple(self.registry, &self.registry.types[ty]))
} else {
@ -42,7 +42,7 @@ impl<'a> __Schema<'a> {
#[field(
desc = "If this server support subscription, the type that subscription operations will be rooted at."
)]
fn subscription_type(&self) -> Option<__Type<'a>> {
async fn subscription_type(&self) -> Option<__Type<'a>> {
if let Some(ty) = &self.registry.subscription_type {
Some(__Type::new_simple(self.registry, &self.registry.types[ty]))
} else {
@ -51,7 +51,7 @@ impl<'a> __Schema<'a> {
}
#[field(desc = "A list of all directives supported by this server.")]
fn directives(&self) -> Vec<__Directive<'a>> {
async fn directives(&self) -> Vec<__Directive<'a>> {
self.registry
.directives
.values()

View File

@ -49,7 +49,7 @@ Depending on the kind of a type, certain fields describe information about that
)]
impl<'a> __Type<'a> {
#[field]
fn kind(&self) -> __TypeKind {
async fn kind(&self) -> __TypeKind {
match &self.detail {
TypeDetail::Simple(ty) => match ty {
registry::Type::Scalar { .. } => __TypeKind::Scalar,
@ -65,7 +65,7 @@ impl<'a> __Type<'a> {
}
#[field]
fn name(&self) -> Option<String> {
async fn name(&self) -> Option<String> {
match &self.detail {
TypeDetail::Simple(ty) => Some(ty.name().to_string()),
TypeDetail::NonNull(_) => None,
@ -74,7 +74,7 @@ impl<'a> __Type<'a> {
}
#[field]
fn description(&self) -> Option<String> {
async fn description(&self) -> Option<String> {
match &self.detail {
TypeDetail::Simple(ty) => match ty {
registry::Type::Scalar { description, .. } => description.map(|s| s.to_string()),
@ -92,7 +92,7 @@ impl<'a> __Type<'a> {
}
#[field]
fn fields(
async fn fields(
&self,
#[arg(default = "false")] include_deprecated: bool,
) -> Option<Vec<__Field<'a>>> {
@ -118,7 +118,7 @@ impl<'a> __Type<'a> {
}
#[field]
fn interfaces(&self) -> Option<Vec<__Type<'a>>> {
async fn interfaces(&self) -> Option<Vec<__Type<'a>>> {
if let TypeDetail::Simple(registry::Type::Object { name, .. }) = &self.detail {
Some(
self.registry
@ -135,7 +135,7 @@ impl<'a> __Type<'a> {
}
#[field]
fn possible_types(&self) -> Option<Vec<__Type<'a>>> {
async fn possible_types(&self) -> Option<Vec<__Type<'a>>> {
if let TypeDetail::Simple(registry::Type::Interface { possible_types, .. }) = &self.detail {
Some(
possible_types
@ -158,7 +158,7 @@ impl<'a> __Type<'a> {
}
#[field]
fn enum_values(
async fn enum_values(
&self,
#[arg(default = "false")] include_deprecated: bool,
) -> Option<Vec<__EnumValue<'a>>> {
@ -179,7 +179,7 @@ impl<'a> __Type<'a> {
}
#[field]
fn input_fields(&self) -> Option<Vec<__InputValue<'a>>> {
async fn input_fields(&self) -> Option<Vec<__InputValue<'a>>> {
if let TypeDetail::Simple(registry::Type::InputObject { input_fields, .. }) = &self.detail {
Some(
input_fields
@ -196,7 +196,7 @@ impl<'a> __Type<'a> {
}
#[field]
fn of_type(&self) -> Option<__Type<'a>> {
async fn of_type(&self) -> Option<__Type<'a>> {
if let TypeDetail::List(ty) = &self.detail {
Some(__Type::new(self.registry, &ty))
} else if let TypeDetail::NonNull(ty) = &self.detail {