From 35f886a7f8d1bbd81062ea0ef674ae4e1a6426a6 Mon Sep 17 00:00:00 2001 From: Sunli Date: Wed, 30 Sep 2020 07:45:48 +0800 Subject: [PATCH 1/2] Improve trait for GraphQL types. --- benchmark/src/lib.rs | 2 +- derive/src/enum.rs | 2 -- derive/src/input_object.rs | 4 ++-- derive/src/interface.rs | 6 +++--- derive/src/merged_object.rs | 6 ++++-- derive/src/object.rs | 6 +++--- derive/src/scalar.rs | 2 -- derive/src/simple_object.rs | 6 +++--- derive/src/subscription.rs | 2 -- derive/src/union.rs | 10 +++++----- integrations/actix-web/src/subscription.rs | 2 +- integrations/rocket/src/lib.rs | 2 +- integrations/tide/src/lib.rs | 2 +- integrations/warp/src/subscription.rs | 2 +- src/base.rs | 18 ++++++++++++++++- src/http/websocket.rs | 3 +-- src/lib.rs | 8 ++++---- .../{object.rs => container.rs} | 18 ++++++++--------- src/resolver_utils/mod.rs | 4 ++-- src/schema.rs | 12 +++++------ src/subscription.rs | 2 +- src/type_mark.rs | 7 ------- src/types/connection/connection_type.rs | 19 ++++++++++++------ src/types/connection/edge.rs | 19 ++++++++++++------ src/types/empty_mutation.rs | 11 +++++----- src/types/empty_subscription.rs | 3 --- src/types/merged_object.rs | 20 ++++++++++--------- src/types/query_root.rs | 13 ++++++------ 28 files changed, 113 insertions(+), 98 deletions(-) rename src/resolver_utils/{object.rs => container.rs} (95%) delete mode 100644 src/type_mark.rs diff --git a/benchmark/src/lib.rs b/benchmark/src/lib.rs index 0822f7d1..a7ab4f9e 100644 --- a/benchmark/src/lib.rs +++ b/benchmark/src/lib.rs @@ -1,4 +1,4 @@ -use async_graphql::{resolver_utils::ObjectType, Response, Schema, SubscriptionType}; +use async_graphql::{ObjectType, Response, Schema, SubscriptionType}; use async_graphql_parser::{parse_query, types::ExecutableDocument}; use async_std::task; diff --git a/derive/src/enum.rs b/derive/src/enum.rs index 047ff449..3d7971c3 100644 --- a/derive/src/enum.rs +++ b/derive/src/enum.rs @@ -156,8 +156,6 @@ pub fn generate(enum_args: &args::Enum) -> GeneratorResult { } #remote_conversion - - impl #crate_name::type_mark::TypeMarkEnum for #ident {} }; Ok(expanded.into()) } diff --git a/derive/src/input_object.rs b/derive/src/input_object.rs index 3f718284..dcb466b2 100644 --- a/derive/src/input_object.rs +++ b/derive/src/input_object.rs @@ -64,7 +64,7 @@ pub fn generate(object_args: &args::InputObject) -> GeneratorResult flatten_fields.push((ident, ty)); schema_fields.push(quote! { - #crate_name::static_assertions::assert_impl_one!(#ty: #crate_name::type_mark::TypeMarkInputObject); + #crate_name::static_assertions::assert_impl_one!(#ty: #crate_name::InputObjectType); #ty::create_type_info(registry); if let Some(#crate_name::registry::MetaType::InputObject{ input_fields, .. }) = registry.types.remove(&*<#ty as #crate_name::Type>::type_name()) { @@ -176,7 +176,7 @@ pub fn generate(object_args: &args::InputObject) -> GeneratorResult } } - impl #crate_name::type_mark::TypeMarkInputObject for #ident {} + impl #crate_name::InputObjectType for #ident {} }; Ok(expanded.into()) } diff --git a/derive/src/interface.rs b/derive/src/interface.rs index dd8a4344..0e7206c7 100644 --- a/derive/src/interface.rs +++ b/derive/src/interface.rs @@ -311,7 +311,7 @@ pub fn generate(interface_args: &args::Interface) -> GeneratorResult) -> #crate_name::Result<#crate_name::serde_json::Value> { #(#resolvers)* Err(#crate_name::QueryError::FieldNotFound { @@ -331,11 +331,11 @@ pub fn generate(interface_args: &args::Interface) -> GeneratorResult, _field: &#crate_name::Positioned<#crate_name::parser::types::Field>) -> #crate_name::Result<#crate_name::serde_json::Value> { - #crate_name::resolver_utils::resolve_object(ctx, self).await + #crate_name::resolver_utils::resolve_container(ctx, self).await } } - impl #generics #crate_name::type_mark::TypeMarkInterface for #ident #generics {} + impl #generics #crate_name::InterfaceType for #ident #generics {} }; Ok(expanded.into()) } diff --git a/derive/src/merged_object.rs b/derive/src/merged_object.rs index de2a5917..24da6318 100644 --- a/derive/src/merged_object.rs +++ b/derive/src/merged_object.rs @@ -89,7 +89,7 @@ pub fn generate(object_args: &args::MergedObject) -> GeneratorResult) -> #crate_name::Result<#crate_name::serde_json::Value> { #create_merged_obj.resolve_field(ctx).await } @@ -99,9 +99,11 @@ pub fn generate(object_args: &args::MergedObject) -> GeneratorResult, _field: &#crate_name::Positioned<#crate_name::parser::types::Field>) -> #crate_name::Result<#crate_name::serde_json::Value> { - #crate_name::resolver_utils::resolve_object(ctx, self).await + #crate_name::resolver_utils::resolve_container(ctx, self).await } } + + impl #crate_name::ObjectType for #ident {} }; Ok(expanded.into()) } diff --git a/derive/src/object.rs b/derive/src/object.rs index 97535525..4d1f7009 100644 --- a/derive/src/object.rs +++ b/derive/src/object.rs @@ -502,7 +502,7 @@ pub fn generate( #[allow(clippy::all, clippy::pedantic, clippy::suspicious_else_formatting)] #[allow(unused_braces, unused_variables, unused_parens, unused_mut)] #[#crate_name::async_trait::async_trait] - impl#generics #crate_name::resolver_utils::ObjectType for #self_ty #where_clause { + impl#generics #crate_name::resolver_utils::ContainerType for #self_ty #where_clause { async fn resolve_field(&self, ctx: &#crate_name::Context<'_>) -> #crate_name::Result<#crate_name::serde_json::Value> { #(#resolvers)* Err(#crate_name::QueryError::FieldNotFound { @@ -530,11 +530,11 @@ pub fn generate( #[#crate_name::async_trait::async_trait] impl #generics #crate_name::OutputValueType for #self_ty #where_clause { async fn resolve(&self, ctx: &#crate_name::ContextSelectionSet<'_>, _field: &#crate_name::Positioned<#crate_name::parser::types::Field>) -> #crate_name::Result<#crate_name::serde_json::Value> { - #crate_name::resolver_utils::resolve_object(ctx, self).await + #crate_name::resolver_utils::resolve_container(ctx, self).await } } - impl #generics #crate_name::type_mark::TypeMarkObject for #self_ty #where_clause {} + impl #generics #crate_name::ObjectType for #self_ty #where_clause {} }; Ok(expanded.into()) } diff --git a/derive/src/scalar.rs b/derive/src/scalar.rs index 4f3b641a..7ac8fc36 100644 --- a/derive/src/scalar.rs +++ b/derive/src/scalar.rs @@ -68,8 +68,6 @@ pub fn generate( Ok(#crate_name::ScalarType::to_value(self).into_json().unwrap()) } } - - impl #generic #crate_name::type_mark::TypeMarkScalar for #self_ty #where_clause {} }; Ok(expanded.into()) } diff --git a/derive/src/simple_object.rs b/derive/src/simple_object.rs index 72896661..89d62493 100644 --- a/derive/src/simple_object.rs +++ b/derive/src/simple_object.rs @@ -178,7 +178,7 @@ pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult) -> #crate_name::Result<#crate_name::serde_json::Value> { #(#resolvers)* Err(#crate_name::QueryError::FieldNotFound { @@ -192,11 +192,11 @@ pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult, _field: &#crate_name::Positioned<#crate_name::parser::types::Field>) -> #crate_name::Result<#crate_name::serde_json::Value> { - #crate_name::resolver_utils::resolve_object(ctx, self).await + #crate_name::resolver_utils::resolve_container(ctx, self).await } } - impl #generics #crate_name::type_mark::TypeMarkObject for #ident #generics #where_clause {} + impl #generics #crate_name::ObjectType for #ident #generics #where_clause {} }; Ok(expanded.into()) } diff --git a/derive/src/subscription.rs b/derive/src/subscription.rs index de3145da..b2b8ea61 100644 --- a/derive/src/subscription.rs +++ b/derive/src/subscription.rs @@ -403,8 +403,6 @@ pub fn generate( ::std::boxed::Box::pin(#crate_name::futures::stream::once(async { Err(error) })) } } - - impl #crate_name::type_mark::TypeMarkSubscription for #self_ty #where_clause {} }; Ok(expanded.into()) } diff --git a/derive/src/union.rs b/derive/src/union.rs index c591e1f2..b177ec27 100644 --- a/derive/src/union.rs +++ b/derive/src/union.rs @@ -67,7 +67,7 @@ pub fn generate(union_args: &args::Union) -> GeneratorResult { if !variant.flatten { type_into_impls.push(quote! { - #crate_name::static_assertions::assert_impl_one!(#p: #crate_name::type_mark::TypeMarkObject); + #crate_name::static_assertions::assert_impl_one!(#p: #crate_name::ObjectType); #[allow(clippy::all, clippy::pedantic)] impl #generics ::std::convert::From<#p> for #ident #generics { @@ -78,7 +78,7 @@ pub fn generate(union_args: &args::Union) -> GeneratorResult { }); } else { type_into_impls.push(quote! { - #crate_name::static_assertions::assert_impl_one!(#p: #crate_name::type_mark::TypeMarkEnum); + #crate_name::static_assertions::assert_impl_one!(#p: #crate_name::UnionType); #[allow(clippy::all, clippy::pedantic)] impl #generics ::std::convert::From<#p> for #ident #generics { @@ -158,7 +158,7 @@ pub fn generate(union_args: &args::Union) -> GeneratorResult { #[allow(clippy::all, clippy::pedantic)] #[#crate_name::async_trait::async_trait] - impl #generics #crate_name::resolver_utils::ObjectType for #ident #generics { + impl #generics #crate_name::resolver_utils::ContainerType for #ident #generics { async fn resolve_field(&self, ctx: &#crate_name::Context<'_>) -> #crate_name::Result<#crate_name::serde_json::Value> { Err(#crate_name::QueryError::FieldNotFound { field_name: ctx.item.node.name.to_string(), @@ -177,11 +177,11 @@ pub fn generate(union_args: &args::Union) -> GeneratorResult { #[#crate_name::async_trait::async_trait] impl #generics #crate_name::OutputValueType for #ident #generics { async fn resolve(&self, ctx: &#crate_name::ContextSelectionSet<'_>, _field: &#crate_name::Positioned<#crate_name::parser::types::Field>) -> #crate_name::Result<#crate_name::serde_json::Value> { - #crate_name::resolver_utils::resolve_object(ctx, self).await + #crate_name::resolver_utils::resolve_container(ctx, self).await } } - impl #generics #crate_name::type_mark::TypeMarkEnum for #ident #generics {} + impl #generics #crate_name::UnionType for #ident #generics {} }; Ok(expanded.into()) } diff --git a/integrations/actix-web/src/subscription.rs b/integrations/actix-web/src/subscription.rs index 13f2261e..eb8bc6f3 100644 --- a/integrations/actix-web/src/subscription.rs +++ b/integrations/actix-web/src/subscription.rs @@ -5,7 +5,7 @@ use actix::{ use actix_http::ws; use actix_web_actors::ws::{Message, ProtocolError, WebsocketContext}; use async_graphql::http::WebSocket; -use async_graphql::{resolver_utils::ObjectType, Data, FieldResult, Schema, SubscriptionType}; +use async_graphql::{Data, FieldResult, ObjectType, Schema, SubscriptionType}; use futures::channel::mpsc; use futures::SinkExt; use std::time::{Duration, Instant}; diff --git a/integrations/rocket/src/lib.rs b/integrations/rocket/src/lib.rs index 5a9fd098..457bab74 100644 --- a/integrations/rocket/src/lib.rs +++ b/integrations/rocket/src/lib.rs @@ -4,7 +4,7 @@ #![forbid(unsafe_code)] use async_graphql::http::MultipartOptions; -use async_graphql::{resolver_utils::ObjectType, Schema, SubscriptionType, Variables}; +use async_graphql::{ObjectType, Schema, SubscriptionType, Variables}; use log::{error, info}; use rocket::{ data::{self, FromData}, diff --git a/integrations/tide/src/lib.rs b/integrations/tide/src/lib.rs index 7ffae03d..2c4314b8 100644 --- a/integrations/tide/src/lib.rs +++ b/integrations/tide/src/lib.rs @@ -9,7 +9,7 @@ #![forbid(unsafe_code)] use async_graphql::http::MultipartOptions; -use async_graphql::{resolver_utils::ObjectType, ParseRequestError, Schema, SubscriptionType}; +use async_graphql::{ObjectType, ParseRequestError, Schema, SubscriptionType}; use async_trait::async_trait; use tide::{ http::{ diff --git a/integrations/warp/src/subscription.rs b/integrations/warp/src/subscription.rs index 63b4ecb2..db1b5dc1 100644 --- a/integrations/warp/src/subscription.rs +++ b/integrations/warp/src/subscription.rs @@ -1,4 +1,4 @@ -use async_graphql::{resolver_utils::ObjectType, Data, FieldResult, Schema, SubscriptionType}; +use async_graphql::{Data, FieldResult, ObjectType, Schema, SubscriptionType}; use futures::{future, StreamExt}; use warp::filters::ws; use warp::{Filter, Rejection, Reply}; diff --git a/src/base.rs b/src/base.rs index 17bfa869..0ceb6ef3 100644 --- a/src/base.rs +++ b/src/base.rs @@ -1,7 +1,8 @@ use crate::parser::types::Field; use crate::registry::Registry; use crate::{ - registry, ContextSelectionSet, FieldResult, InputValueResult, Positioned, Result, Value, + registry, ContainerType, ContextSelectionSet, FieldResult, InputValueResult, Positioned, + Result, Value, }; use std::borrow::Cow; @@ -99,3 +100,18 @@ impl OutputValueType for FieldResult { } } } + +/// A GraphQL object. +pub trait ObjectType: ContainerType {} + +#[async_trait::async_trait] +impl ObjectType for &T {} + +/// A GraphQL interface. +pub trait InterfaceType: ContainerType {} + +/// A GraphQL interface. +pub trait UnionType: ContainerType {} + +/// A GraphQL input object. +pub trait InputObjectType: InputValueType {} diff --git a/src/http/websocket.rs b/src/http/websocket.rs index 7183f2df..2d6f473e 100644 --- a/src/http/websocket.rs +++ b/src/http/websocket.rs @@ -1,7 +1,6 @@ //! WebSocket transport for subscription -use crate::resolver_utils::ObjectType; -use crate::{Data, FieldResult, Request, Response, Schema, SubscriptionType}; +use crate::{Data, FieldResult, ObjectType, Request, Response, Schema, SubscriptionType}; use futures::Stream; use pin_project_lite::pin_project; use serde::{Deserialize, Serialize}; diff --git a/src/lib.rs b/src/lib.rs index cf31ae2f..22017f92 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -135,8 +135,6 @@ pub mod validators; #[doc(hidden)] pub mod registry; -#[doc(hidden)] -pub mod type_mark; #[doc(hidden)] pub use async_stream; @@ -156,7 +154,9 @@ pub use static_assertions; pub use subscription::SubscriptionType; pub use async_graphql_parser as parser; -pub use base::{InputValueType, OutputValueType, Type}; +pub use base::{ + InputObjectType, InputValueType, InterfaceType, ObjectType, OutputValueType, Type, UnionType, +}; pub use context::{ Context, ContextBase, Data, QueryEnv, QueryPathNode, QueryPathSegment, ResolveId, Variables, }; @@ -175,7 +175,7 @@ pub use validation::ValidationMode; #[doc(no_inline)] pub use parser::{Pos, Positioned}; #[doc(no_inline)] -pub use resolver_utils::{EnumType, ObjectType, ScalarType}; +pub use resolver_utils::{ContainerType, EnumType, ScalarType}; pub use types::*; /// Result type diff --git a/src/resolver_utils/object.rs b/src/resolver_utils/container.rs similarity index 95% rename from src/resolver_utils/object.rs rename to src/resolver_utils/container.rs index 57dc2e83..b9da8f07 100644 --- a/src/resolver_utils/object.rs +++ b/src/resolver_utils/container.rs @@ -6,12 +6,12 @@ use futures::TryFutureExt; use std::future::Future; use std::pin::Pin; -/// A GraphQL object. +/// A GraphQL container. /// /// This helper trait allows the type to call `resolve_object` on itself in its /// `OutputValueType::resolve` implementation. #[async_trait::async_trait] -pub trait ObjectType: OutputValueType { +pub trait ContainerType: OutputValueType { /// This function returns true of type `EmptyMutation` only. #[doc(hidden)] fn is_empty() -> bool { @@ -21,7 +21,7 @@ pub trait ObjectType: OutputValueType { /// Resolves a field value and outputs it as a json value `serde_json::Value`. async fn resolve_field(&self, ctx: &Context<'_>) -> Result; - /// Collect all the fields of the object that are queried in the selection set. + /// Collect all the fields of the container that are queried in the selection set. /// /// Objects do not have to override this, but interfaces and unions must call it on their /// internal type. @@ -45,7 +45,7 @@ pub trait ObjectType: OutputValueType { } #[async_trait::async_trait] -impl ObjectType for &T { +impl ContainerType for &T { async fn resolve_field(&self, ctx: &Context<'_>) -> Result { T::resolve_field(*self, ctx).await } @@ -53,8 +53,8 @@ impl ObjectType for &T { // TODO: reduce code duplication between the two below functions? -/// Resolve an object by executing each of the fields concurrently. -pub async fn resolve_object<'a, T: ObjectType + Send + Sync>( +/// Resolve an container by executing each of the fields concurrently. +pub async fn resolve_container<'a, T: ContainerType + Send + Sync>( ctx: &ContextSelectionSet<'a>, root: &'a T, ) -> Result { @@ -78,8 +78,8 @@ pub async fn resolve_object<'a, T: ObjectType + Send + Sync>( Ok(map.into()) } -/// Resolve an object by executing each of the fields serially. -pub async fn resolve_object_serial<'a, T: ObjectType + Send + Sync>( +/// Resolve an container by executing each of the fields serially. +pub async fn resolve_container_serial<'a, T: ContainerType + Send + Sync>( ctx: &ContextSelectionSet<'a>, root: &'a T, ) -> Result { @@ -112,7 +112,7 @@ pub struct Fields<'a>(Vec>); impl<'a> Fields<'a> { /// Add another set of fields to this set of fields using the given object. - pub fn add_set( + pub fn add_set( &mut self, ctx: &ContextSelectionSet<'a>, root: &'a T, diff --git a/src/resolver_utils/mod.rs b/src/resolver_utils/mod.rs index cc98ab55..4c2b5a27 100644 --- a/src/resolver_utils/mod.rs +++ b/src/resolver_utils/mod.rs @@ -1,12 +1,12 @@ //! Utilities for implementing //! [`OutputValueType::resolve`](trait.OutputValueType.html#tymethod.resolve). +mod container; mod r#enum; mod list; -mod object; mod scalar; +pub use container::*; pub use list::*; -pub use object::*; pub use r#enum::*; pub use scalar::*; diff --git a/src/schema.rs b/src/schema.rs index 83844663..e5b011ab 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -4,13 +4,13 @@ use crate::model::__DirectiveLocation; use crate::parser::parse_query; use crate::parser::types::{DocumentOperations, OperationType}; use crate::registry::{MetaDirective, MetaInputValue, Registry}; -use crate::resolver_utils::{resolve_object, resolve_object_serial, ObjectType}; +use crate::resolver_utils::{resolve_container, resolve_container_serial, ContainerType}; use crate::subscription::collect_subscription_streams; use crate::types::QueryRoot; use crate::validation::{check_rules, CheckResult, ValidationMode}; use crate::{ - BatchRequest, BatchResponse, CacheControl, ContextBase, Error, Pos, QueryEnv, QueryError, - Request, Response, Result, SubscriptionType, Type, ID, + BatchRequest, BatchResponse, CacheControl, ContextBase, Error, ObjectType, Pos, QueryEnv, + QueryError, Request, Response, Result, SubscriptionType, Type, ID, }; use futures::stream::{self, Stream, StreamExt}; use indexmap::map::IndexMap; @@ -34,7 +34,7 @@ pub struct SchemaBuilder { enable_federation: bool, } -impl +impl SchemaBuilder { /// Manually register a type in the schema. @@ -430,8 +430,8 @@ where env.extensions.lock().execution_start(&ctx_extension); let data = match &env.operation.node.ty { - OperationType::Query => resolve_object(&ctx, &self.query).await, - OperationType::Mutation => resolve_object_serial(&ctx, &self.mutation).await, + OperationType::Query => resolve_container(&ctx, &self.query).await, + OperationType::Mutation => resolve_container_serial(&ctx, &self.mutation).await, OperationType::Subscription => { return Error::Query { pos: Pos::default(), diff --git a/src/subscription.rs b/src/subscription.rs index 8e7813e2..68e01ee7 100644 --- a/src/subscription.rs +++ b/src/subscription.rs @@ -3,7 +3,7 @@ use crate::{Context, ContextSelectionSet, Result, Type}; use futures::{Stream, StreamExt}; use std::pin::Pin; -/// Represents a GraphQL subscription object +/// A GraphQL subscription object pub trait SubscriptionType: Type { /// This function returns true of type `EmptySubscription` only. #[doc(hidden)] diff --git a/src/type_mark.rs b/src/type_mark.rs deleted file mode 100644 index bd2eb510..00000000 --- a/src/type_mark.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub trait TypeMarkScalar {} -pub trait TypeMarkObject {} -pub trait TypeMarkInterface {} -pub trait TypeMarkUnion {} -pub trait TypeMarkEnum {} -pub trait TypeMarkInputObject {} -pub trait TypeMarkSubscription {} diff --git a/src/types/connection/connection_type.rs b/src/types/connection/connection_type.rs index 93f46fe1..9377e31f 100644 --- a/src/types/connection/connection_type.rs +++ b/src/types/connection/connection_type.rs @@ -1,11 +1,11 @@ use crate::connection::edge::Edge; use crate::connection::page_info::PageInfo; use crate::parser::types::Field; -use crate::resolver_utils::{resolve_object, ObjectType}; -use crate::type_mark::TypeMarkObject; +use crate::resolver_utils::{resolve_container, ContainerType}; use crate::types::connection::{CursorType, EmptyFields}; use crate::{ - registry, Context, ContextSelectionSet, FieldResult, OutputValueType, Positioned, Result, Type, + registry, Context, ContextSelectionSet, FieldResult, ObjectType, OutputValueType, Positioned, + Result, Type, }; use futures::{Stream, StreamExt, TryStreamExt}; use indexmap::map::IndexMap; @@ -189,7 +189,7 @@ where } #[async_trait::async_trait] -impl ObjectType for Connection +impl ContainerType for Connection where C: CursorType + Send + Sync, T: OutputValueType + Send + Sync, @@ -228,8 +228,15 @@ where ctx: &ContextSelectionSet<'_>, _field: &Positioned, ) -> Result { - resolve_object(ctx, self).await + resolve_container(ctx, self).await } } -impl TypeMarkObject for Connection {} +impl ObjectType for Connection +where + C: CursorType + Send + Sync, + T: OutputValueType + Send + Sync, + EC: ObjectType + Sync + Send, + EE: ObjectType + Sync + Send, +{ +} diff --git a/src/types/connection/edge.rs b/src/types/connection/edge.rs index 78d65d1a..1453aa6f 100644 --- a/src/types/connection/edge.rs +++ b/src/types/connection/edge.rs @@ -1,9 +1,10 @@ use crate::connection::EmptyFields; use crate::parser::types::Field; -use crate::resolver_utils::{resolve_object, ObjectType}; -use crate::type_mark::TypeMarkObject; +use crate::resolver_utils::{resolve_container, ContainerType}; use crate::types::connection::CursorType; -use crate::{registry, Context, ContextSelectionSet, OutputValueType, Positioned, Result, Type}; +use crate::{ + registry, Context, ContextSelectionSet, ObjectType, OutputValueType, Positioned, Result, Type, +}; use indexmap::map::IndexMap; use std::borrow::Cow; @@ -105,7 +106,7 @@ where } #[async_trait::async_trait] -impl ObjectType for Edge +impl ContainerType for Edge where C: CursorType + Send + Sync, T: OutputValueType + Send + Sync, @@ -135,8 +136,14 @@ where ctx: &ContextSelectionSet<'_>, _field: &Positioned, ) -> Result { - resolve_object(ctx, self).await + resolve_container(ctx, self).await } } -impl TypeMarkObject for Edge {} +impl ObjectType for Edge +where + C: CursorType + Send + Sync, + T: OutputValueType + Send + Sync, + E: ObjectType + Sync + Send, +{ +} diff --git a/src/types/empty_mutation.rs b/src/types/empty_mutation.rs index 071e9bd8..68311e73 100644 --- a/src/types/empty_mutation.rs +++ b/src/types/empty_mutation.rs @@ -1,9 +1,8 @@ use crate::parser::types::Field; -use crate::resolver_utils::ObjectType; -use crate::type_mark::TypeMarkObject; +use crate::resolver_utils::ContainerType; use crate::{ - registry, Context, ContextSelectionSet, Error, OutputValueType, Positioned, QueryError, Result, - Type, + registry, Context, ContextSelectionSet, Error, ObjectType, OutputValueType, Positioned, + QueryError, Result, Type, }; use std::borrow::Cow; @@ -44,7 +43,7 @@ impl Type for EmptyMutation { } #[async_trait::async_trait] -impl ObjectType for EmptyMutation { +impl ContainerType for EmptyMutation { fn is_empty() -> bool { true } @@ -69,4 +68,4 @@ impl OutputValueType for EmptyMutation { } } -impl TypeMarkObject for EmptyMutation {} +impl ObjectType for EmptyMutation {} diff --git a/src/types/empty_subscription.rs b/src/types/empty_subscription.rs index f0f3a041..9b65402e 100644 --- a/src/types/empty_subscription.rs +++ b/src/types/empty_subscription.rs @@ -1,4 +1,3 @@ -use crate::type_mark::TypeMarkSubscription; use crate::{registry, Context, Error, Pos, QueryError, Result, SubscriptionType, Type}; use futures::{stream, Stream}; use std::borrow::Cow; @@ -48,5 +47,3 @@ impl SubscriptionType for EmptySubscription { })) } } - -impl TypeMarkSubscription for EmptySubscription {} diff --git a/src/types/merged_object.rs b/src/types/merged_object.rs index 50dfdd33..e7ab987a 100644 --- a/src/types/merged_object.rs +++ b/src/types/merged_object.rs @@ -1,10 +1,9 @@ use crate::parser::types::Field; use crate::registry::{MetaType, Registry}; -use crate::resolver_utils::{resolve_object, ObjectType}; -use crate::type_mark::{TypeMarkObject, TypeMarkSubscription}; +use crate::resolver_utils::{resolve_container, ContainerType}; use crate::{ - CacheControl, Context, ContextSelectionSet, Error, OutputValueType, Positioned, QueryError, - Result, SimpleObject, Subscription, SubscriptionType, Type, + CacheControl, Context, ContextSelectionSet, Error, ObjectType, OutputValueType, Positioned, + QueryError, Result, SimpleObject, Subscription, SubscriptionType, Type, }; use futures::{future::Either, stream, Stream, StreamExt}; use indexmap::IndexMap; @@ -69,7 +68,7 @@ impl Type for MergedObject { } #[async_trait::async_trait] -impl ObjectType for MergedObject +impl ContainerType for MergedObject where A: ObjectType + Send + Sync, B: ObjectType + Send + Sync, @@ -97,11 +96,16 @@ where ctx: &ContextSelectionSet<'_>, _field: &Positioned, ) -> Result { - resolve_object(ctx, self).await + resolve_container(ctx, self).await } } -impl TypeMarkObject for MergedObject {} +impl ObjectType for MergedObject +where + A: ObjectType + Send + Sync, + B: ObjectType + Send + Sync, +{ +} impl SubscriptionType for MergedObject where @@ -124,8 +128,6 @@ where } } -impl TypeMarkSubscription for MergedObject {} - #[doc(hidden)] #[derive(SimpleObject, Default)] #[graphql(internal)] diff --git a/src/types/query_root.rs b/src/types/query_root.rs index de72a570..c09a450e 100644 --- a/src/types/query_root.rs +++ b/src/types/query_root.rs @@ -1,12 +1,11 @@ use crate::model::{__Schema, __Type}; use crate::parser::types::Field; -use crate::resolver_utils::{resolve_object, ObjectType}; +use crate::resolver_utils::{resolve_container, ContainerType}; use crate::{ - registry, Any, Context, ContextSelectionSet, Error, OutputValueType, Positioned, QueryError, - Result, SimpleObject, Type, + registry, Any, Context, ContextSelectionSet, Error, ObjectType, OutputValueType, Positioned, + QueryError, Result, SimpleObject, Type, }; -use crate::type_mark::TypeMarkObject; use indexmap::map::IndexMap; use std::borrow::Cow; @@ -81,7 +80,7 @@ impl Type for QueryRoot { } #[async_trait::async_trait] -impl ObjectType for QueryRoot { +impl ContainerType for QueryRoot { async fn resolve_field(&self, ctx: &Context<'_>) -> Result { if ctx.item.node.name.node == "__schema" { if self.disable_introspection { @@ -150,8 +149,8 @@ impl OutputValueType for QueryRoot { ctx: &ContextSelectionSet<'_>, _field: &Positioned, ) -> Result { - resolve_object(ctx, self).await + resolve_container(ctx, self).await } } -impl TypeMarkObject for QueryRoot {} +impl ObjectType for QueryRoot {} From 7ca82d9a9f20ce792f5adbcdf567944f1cca7f56 Mon Sep 17 00:00:00 2001 From: Sunli Date: Wed, 30 Sep 2020 08:00:48 +0800 Subject: [PATCH 2/2] Update Cargo.toml --- integrations/tide/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/tide/Cargo.toml b/integrations/tide/Cargo.toml index b94e51a8..4792c520 100644 --- a/integrations/tide/Cargo.toml +++ b/integrations/tide/Cargo.toml @@ -19,7 +19,7 @@ async-trait = "0.1.36" serde_json = "1.0.56" futures = "0.3.5" async-std = "1.6.2" -pin-project-lite = "=0.1.8" # https://github.com/http-rs/async-sse/issues/10 +pin-project-lite = "0.1.9" [dev-dependencies] smol = { version = "0.1.18", features = ["tokio02"] }