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 48c08453..a5b18839 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 17def841..3bf6a615 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()) { @@ -180,7 +180,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 f361692d..e8a18c8e 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::ServerResult> { #(#resolvers)* Ok(None) @@ -328,11 +328,11 @@ pub fn generate(interface_args: &args::Interface) -> GeneratorResult, _field: &#crate_name::Positioned<#crate_name::parser::types::Field>) -> #crate_name::ServerResult<#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 be037538..f174fd9c 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::ServerResult<::std::option::Option<#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::ServerResult<#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 ec7348df..56a51cb7 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::ServerResult<::std::option::Option<#crate_name::serde_json::Value>> { #(#resolvers)* Ok(None) @@ -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::ServerResult<#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 2c9879a3..91a23d4a 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 f906c2fb..ccae27d6 100644 --- a/derive/src/simple_object.rs +++ b/derive/src/simple_object.rs @@ -178,7 +178,8 @@ pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult) -> #crate_name::ServerResult<::std::option::Option<#crate_name::serde_json::Value>> { #(#resolvers)* Ok(None) @@ -188,12 +189,13 @@ pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult, _field: &#crate_name::Positioned<#crate_name::parser::types::Field>) -> #crate_name::ServerResult<#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 773e7311..05c1db1f 100644 --- a/derive/src/subscription.rs +++ b/derive/src/subscription.rs @@ -393,8 +393,6 @@ pub fn generate( None } } - - 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 2330844f..d3c560c7 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,8 @@ 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::ServerResult<::std::option::Option<#crate_name::serde_json::Value>> { Ok(None) } @@ -174,11 +175,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::ServerResult<#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 69efedc5..eb96e113 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, Result, Schema, SubscriptionType}; +use async_graphql::{Data, ObjectType, Result, 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 9b983481..fda7b1c8 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/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"] } 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 daa337a5..ce13c904 100644 --- a/integrations/warp/src/subscription.rs +++ b/integrations/warp/src/subscription.rs @@ -1,4 +1,4 @@ -use async_graphql::{resolver_utils::ObjectType, Data, Result, Schema, SubscriptionType}; +use async_graphql::{Data, ObjectType, Result, 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 120a3502..6aa799d3 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, InputValueResult, Positioned, Result, ServerResult, Value, + registry, ContainerType, ContextSelectionSet, InputValueResult, Positioned, Result, + ServerResult, Value, }; use std::borrow::Cow; @@ -97,3 +98,18 @@ impl OutputValueType for Result { } } } + +/// 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 5f96cf6c..a695844a 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, Error, Request, Response, Result, Schema, SubscriptionType}; +use crate::{Data, Error, ObjectType, Request, Response, Result, 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 c8c07cf8..e22cab83 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -134,8 +134,6 @@ pub mod validators; #[doc(hidden)] pub mod registry; -#[doc(hidden)] -pub mod type_mark; #[doc(hidden)] pub use async_stream; @@ -155,7 +153,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, }; @@ -174,7 +174,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::*; /// Define a GraphQL object with methods 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 08116c84..c6dc3bbf 100644 --- a/src/resolver_utils/object.rs +++ b/src/resolver_utils/container.rs @@ -7,12 +7,12 @@ use crate::{ 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 { @@ -24,7 +24,7 @@ pub trait ObjectType: OutputValueType { /// If the field was not found returns None. async fn resolve_field(&self, ctx: &Context<'_>) -> ServerResult>; - /// 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. @@ -52,7 +52,7 @@ pub trait ObjectType: OutputValueType { } #[async_trait::async_trait] -impl ObjectType for &T { +impl ContainerType for &T { async fn resolve_field(&self, ctx: &Context<'_>) -> ServerResult> { T::resolve_field(*self, ctx).await } @@ -60,8 +60,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, ) -> ServerResult { @@ -85,8 +85,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, ) -> ServerResult { @@ -119,7 +119,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 de1e9b20..77e68b75 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, QueryEnv, Request, Response, - ServerError, SubscriptionType, Type, ID, + BatchRequest, BatchResponse, CacheControl, ContextBase, ObjectType, QueryEnv, Request, + Response, ServerError, 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. @@ -432,8 +432,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 Response::from_errors(vec![ServerError::new( "Subscriptions are not supported on this transport.", diff --git a/src/subscription.rs b/src/subscription.rs index 4e81b751..f7b963b8 100644 --- a/src/subscription.rs +++ b/src/subscription.rs @@ -3,7 +3,7 @@ use crate::{Context, ContextSelectionSet, PathSegment, ServerError, ServerResult 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 4a14fa92..08fa5fe0 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, OutputValueType, Positioned, Result, ServerResult, Type, + registry, Context, ContextSelectionSet, ObjectType, OutputValueType, Positioned, Result, + ServerResult, 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, @@ -232,8 +232,15 @@ where ctx: &ContextSelectionSet<'_>, _field: &Positioned, ) -> ServerResult { - 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 afec9f7e..fbe90789 100644 --- a/src/types/connection/edge.rs +++ b/src/types/connection/edge.rs @@ -1,10 +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, ServerResult, Type, + registry, Context, ContextSelectionSet, ObjectType, OutputValueType, Positioned, ServerResult, + Type, }; use indexmap::map::IndexMap; use std::borrow::Cow; @@ -107,7 +107,7 @@ where } #[async_trait::async_trait] -impl ObjectType for Edge +impl ContainerType for Edge where C: CursorType + Send + Sync, T: OutputValueType + Send + Sync, @@ -139,8 +139,14 @@ where ctx: &ContextSelectionSet<'_>, _field: &Positioned, ) -> ServerResult { - 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 0a2f7785..4de47c67 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, OutputValueType, Positioned, ServerError, ServerResult, - Type, + registry, Context, ContextSelectionSet, ObjectType, OutputValueType, Positioned, ServerError, + ServerResult, 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 } @@ -65,4 +64,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 04c5cef1..368a3a2a 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, ServerError, ServerResult, SubscriptionType, Type}; use futures::{stream, Stream}; use std::borrow::Cow; @@ -44,5 +43,3 @@ impl SubscriptionType for EmptySubscription { }))) } } - -impl TypeMarkSubscription for EmptySubscription {} diff --git a/src/types/merged_object.rs b/src/types/merged_object.rs index f0579c46..ad42f82b 100644 --- a/src/types/merged_object.rs +++ b/src/types/merged_object.rs @@ -1,13 +1,14 @@ use crate::parser::types::Field; use crate::registry::{MetaType, Registry}; -use crate::resolver_utils::{resolve_object, ObjectType}; -use crate::type_mark::TypeMarkObject; +use crate::resolver_utils::resolve_container; use crate::{ - CacheControl, Context, ContextSelectionSet, OutputValueType, Positioned, ServerResult, - SimpleObject, Subscription, Type, + CacheControl, ContainerType, Context, ContextSelectionSet, ObjectType, OutputValueType, + Positioned, ServerResult, SimpleObject, Subscription, SubscriptionType, Type, }; +use futures::Stream; use indexmap::IndexMap; use std::borrow::Cow; +use std::pin::Pin; #[doc(hidden)] pub struct MergedObject(pub A, pub B); @@ -57,7 +58,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, @@ -82,11 +83,32 @@ where ctx: &ContextSelectionSet<'_>, _field: &Positioned, ) -> ServerResult { - 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 + A: SubscriptionType + Send + Sync, + B: SubscriptionType + Send + Sync, +{ + fn create_field_stream<'a>( + &'a self, + ctx: &'a Context<'a>, + ) -> Option> + Send + 'a>>> { + match self.0.create_field_stream(ctx) { + Some(stream) => Some(stream), + None => self.1.create_field_stream(ctx), + } + } +} #[doc(hidden)] #[derive(SimpleObject, Default)] diff --git a/src/types/query_root.rs b/src/types/query_root.rs index ac6ca0af..8d2cc1c9 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, OutputValueType, Positioned, ServerError, - ServerResult, SimpleObject, Type, + registry, Any, Context, ContextSelectionSet, ObjectType, OutputValueType, Positioned, + ServerError, ServerResult, 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<'_>) -> ServerResult> { if ctx.item.node.name.node == "__schema" { if self.disable_introspection { @@ -148,8 +147,8 @@ impl OutputValueType for QueryRoot { ctx: &ContextSelectionSet<'_>, _field: &Positioned, ) -> ServerResult { - resolve_object(ctx, self).await + resolve_container(ctx, self).await } } -impl TypeMarkObject for QueryRoot {} +impl ObjectType for QueryRoot {}