From 9b0573a8bd958ffdfa1e6668948dd74cab525978 Mon Sep 17 00:00:00 2001 From: Sunli Date: Wed, 30 Mar 2022 20:54:49 +0800 Subject: [PATCH] Panics when the same Rust type has the same name. #880 --- derive/src/enum.rs | 2 +- derive/src/input_object.rs | 4 +- derive/src/interface.rs | 2 +- derive/src/merged_object.rs | 2 +- derive/src/newtype.rs | 2 +- derive/src/object.rs | 4 +- derive/src/oneof_object.rs | 4 +- derive/src/scalar.rs | 4 +- derive/src/simple_object.rs | 4 +- derive/src/union.rs | 2 +- examples | 2 +- src/registry/mod.rs | 99 ++++++++++++++++++---- src/resolver_utils/scalar.rs | 28 +++--- src/types/connection/connection_type.rs | 3 +- src/types/connection/edge.rs | 3 +- src/types/empty_mutation.rs | 3 +- src/types/external/json_object/btreemap.rs | 6 +- src/types/external/json_object/hashmap.rs | 6 +- src/types/json.rs | 34 ++++---- src/types/merged_object.rs | 4 +- src/types/upload.rs | 3 +- tests/input_object.rs | 25 ++++++ 22 files changed, 174 insertions(+), 72 deletions(-) diff --git a/derive/src/enum.rs b/derive/src/enum.rs index 9efab5d4..ea22520f 100644 --- a/derive/src/enum.rs +++ b/derive/src/enum.rs @@ -130,7 +130,7 @@ pub fn generate(enum_args: &args::Enum) -> GeneratorResult { } fn __create_type_info(registry: &mut #crate_name::registry::Registry) -> ::std::string::String { - registry.create_input_type::(|registry| { + registry.create_input_type::(#crate_name::registry::MetaTypeId::Enum, |registry| { #crate_name::registry::MetaType::Enum { name: ::std::borrow::ToOwned::to_owned(#gql_typename), description: #desc, diff --git a/derive/src/input_object.rs b/derive/src/input_object.rs index 6d545738..4d62853d 100644 --- a/derive/src/input_object.rs +++ b/derive/src/input_object.rs @@ -213,7 +213,7 @@ pub fn generate(object_args: &args::InputObject) -> GeneratorResult } fn create_type_info(registry: &mut #crate_name::registry::Registry) -> ::std::string::String { - registry.create_input_type::(|registry| #crate_name::registry::MetaType::InputObject { + registry.create_input_type::(#crate_name::registry::MetaTypeId::InputObject, |registry| #crate_name::registry::MetaType::InputObject { name: ::std::borrow::ToOwned::to_owned(#gql_typename), description: #desc, input_fields: { @@ -260,7 +260,7 @@ pub fn generate(object_args: &args::InputObject) -> GeneratorResult #[allow(clippy::all, clippy::pedantic)] impl #impl_generics #ident #ty_generics #where_clause { fn __internal_create_type_info(registry: &mut #crate_name::registry::Registry, name: &str) -> ::std::string::String where Self: #crate_name::InputType { - registry.create_input_type::(|registry| #crate_name::registry::MetaType::InputObject { + registry.create_input_type::(#crate_name::registry::MetaTypeId::InputObject, |registry| #crate_name::registry::MetaType::InputObject { name: ::std::borrow::ToOwned::to_owned(name), description: #desc, input_fields: { diff --git a/derive/src/interface.rs b/derive/src/interface.rs index a8b5d0f4..0bdda0e0 100644 --- a/derive/src/interface.rs +++ b/derive/src/interface.rs @@ -374,7 +374,7 @@ pub fn generate(interface_args: &args::Interface) -> GeneratorResult ::std::string::String { - registry.create_output_type::(|registry| { + registry.create_output_type::(#crate_name::registry::MetaTypeId::Interface, |registry| { #(#registry_types)* #crate_name::registry::MetaType::Interface { diff --git a/derive/src/merged_object.rs b/derive/src/merged_object.rs index b234e06a..362f2a71 100644 --- a/derive/src/merged_object.rs +++ b/derive/src/merged_object.rs @@ -82,7 +82,7 @@ pub fn generate(object_args: &args::MergedObject) -> GeneratorResult ::std::string::String { - registry.create_output_type::(|registry| { + registry.create_output_type::(#crate_name::registry::MetaTypeId::Object, |registry| { let mut fields = ::std::default::Default::default(); let mut cache_control = ::std::default::Default::default(); diff --git a/derive/src/newtype.rs b/derive/src/newtype.rs index 2405f89f..7113c1b9 100644 --- a/derive/src/newtype.rs +++ b/derive/src/newtype.rs @@ -44,7 +44,7 @@ pub fn generate(newtype_args: &args::NewType) -> GeneratorResult { }; quote! { - registry.create_input_type::<#ident, _>(|_| #crate_name::registry::MetaType::Scalar { + registry.create_input_type::<#ident, _>(#crate_name::registry::MetaTypeId::Scalar, |_| #crate_name::registry::MetaType::Scalar { name: ::std::borrow::ToOwned::to_owned(#name), description: #desc, is_valid: |value| <#ident as #crate_name::ScalarType>::is_valid(value), diff --git a/derive/src/object.rs b/derive/src/object.rs index 3716bc8a..d97c7632 100644 --- a/derive/src/object.rs +++ b/derive/src/object.rs @@ -653,7 +653,7 @@ pub fn generate( } fn create_type_info(registry: &mut #crate_name::registry::Registry) -> ::std::string::String { - let ty = registry.create_output_type::(|registry| #crate_name::registry::MetaType::Object { + let ty = registry.create_output_type::(#crate_name::registry::MetaTypeId::Object, |registry| #crate_name::registry::MetaType::Object { name: ::std::borrow::ToOwned::to_owned(#gql_typename), description: #desc, fields: { @@ -692,7 +692,7 @@ pub fn generate( impl #impl_generics #self_ty #where_clause { fn __internal_create_type_info(registry: &mut #crate_name::registry::Registry, name: &str) -> ::std::string::String where Self: #crate_name::OutputType { - let ty = registry.create_output_type::(|registry| #crate_name::registry::MetaType::Object { + let ty = registry.create_output_type::(#crate_name::registry::MetaTypeId::Object, |registry| #crate_name::registry::MetaType::Object { name: ::std::borrow::ToOwned::to_owned(name), description: #desc, fields: { diff --git a/derive/src/oneof_object.rs b/derive/src/oneof_object.rs index 588997f9..330b6e7d 100644 --- a/derive/src/oneof_object.rs +++ b/derive/src/oneof_object.rs @@ -131,7 +131,7 @@ pub fn generate(object_args: &args::OneofObject) -> GeneratorResult } fn create_type_info(registry: &mut #crate_name::registry::Registry) -> ::std::string::String { - registry.create_input_type::(|registry| #crate_name::registry::MetaType::InputObject { + registry.create_input_type::(#crate_name::registry::MetaTypeId::InputObject, |registry| #crate_name::registry::MetaType::InputObject { name: ::std::borrow::ToOwned::to_owned(#gql_typename), description: #desc, input_fields: { @@ -181,7 +181,7 @@ pub fn generate(object_args: &args::OneofObject) -> GeneratorResult #[allow(clippy::all, clippy::pedantic)] impl #impl_generics #ident #ty_generics #where_clause { fn __internal_create_type_info(registry: &mut #crate_name::registry::Registry, name: &str) -> ::std::string::String where Self: #crate_name::InputType { - registry.create_input_type::(|registry| #crate_name::registry::MetaType::InputObject { + registry.create_input_type::(#crate_name::registry::MetaTypeId::InputObject, |registry| #crate_name::registry::MetaType::InputObject { name: ::std::borrow::ToOwned::to_owned(name), description: #desc, input_fields: { diff --git a/derive/src/scalar.rs b/derive/src/scalar.rs index a7feebfd..a4838f98 100644 --- a/derive/src/scalar.rs +++ b/derive/src/scalar.rs @@ -47,7 +47,7 @@ pub fn generate( } fn create_type_info(registry: &mut #crate_name::registry::Registry) -> ::std::string::String { - registry.create_input_type::<#self_ty, _>(|_| #crate_name::registry::MetaType::Scalar { + registry.create_input_type::<#self_ty, _>(#crate_name::registry::MetaTypeId::Scalar, |_| #crate_name::registry::MetaType::Scalar { name: ::std::borrow::ToOwned::to_owned(#gql_typename), description: #desc, is_valid: |value| <#self_ty as #crate_name::ScalarType>::is_valid(value), @@ -77,7 +77,7 @@ pub fn generate( } fn create_type_info(registry: &mut #crate_name::registry::Registry) -> ::std::string::String { - registry.create_output_type::<#self_ty, _>(|_| #crate_name::registry::MetaType::Scalar { + registry.create_output_type::<#self_ty, _>(#crate_name::registry::MetaTypeId::Scalar, |_| #crate_name::registry::MetaType::Scalar { name: ::std::borrow::ToOwned::to_owned(#gql_typename), description: #desc, is_valid: |value| <#self_ty as #crate_name::ScalarType>::is_valid(value), diff --git a/derive/src/simple_object.rs b/derive/src/simple_object.rs index a84500f8..900c3a75 100644 --- a/derive/src/simple_object.rs +++ b/derive/src/simple_object.rs @@ -311,7 +311,7 @@ pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult ::std::string::String { - registry.create_output_type::(|registry| #crate_name::registry::MetaType::Object { + registry.create_output_type::(#crate_name::registry::MetaTypeId::Object, |registry| #crate_name::registry::MetaType::Object { name: ::std::borrow::ToOwned::to_owned(#gql_typename), description: #desc, fields: { @@ -375,7 +375,7 @@ pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult, ) -> ::std::string::String where Self: #crate_name::OutputType { - registry.create_output_type::(|registry| #crate_name::registry::MetaType::Object { + registry.create_output_type::(#crate_name::registry::MetaTypeId::Object, |registry| #crate_name::registry::MetaType::Object { name: ::std::borrow::ToOwned::to_owned(name), description: #desc, fields: { diff --git a/derive/src/union.rs b/derive/src/union.rs index c35bc4bf..d557995e 100644 --- a/derive/src/union.rs +++ b/derive/src/union.rs @@ -172,7 +172,7 @@ pub fn generate(union_args: &args::Union) -> GeneratorResult { } fn create_type_info(registry: &mut #crate_name::registry::Registry) -> ::std::string::String { - registry.create_output_type::(|registry| { + registry.create_output_type::(#crate_name::registry::MetaTypeId::Union, |registry| { #(#registry_types)* #crate_name::registry::MetaType::Union { diff --git a/examples b/examples index 6a638085..61384c8f 160000 --- a/examples +++ b/examples @@ -1 +1 @@ -Subproject commit 6a63808523f7e4995f9111a3497f06921cd3b11b +Subproject commit 61384c8fa50e1395e50015b2be77b4bc6f5de4d2 diff --git a/src/registry/mod.rs b/src/registry/mod.rs index e818e39e..b50811fc 100644 --- a/src/registry/mod.rs +++ b/src/registry/mod.rs @@ -3,6 +3,7 @@ mod export_sdl; mod stringify_exec_doc; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; +use std::fmt::{self, Display, Formatter}; use indexmap::map::IndexMap; use indexmap::set::IndexSet; @@ -179,6 +180,29 @@ pub struct MetaEnumValue { type MetaVisibleFn = fn(&Context<'_>) -> bool; +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub enum MetaTypeId { + Scalar, + Object, + Interface, + Union, + Enum, + InputObject, +} + +impl Display for MetaTypeId { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str(match self { + MetaTypeId::Scalar => "Scalar", + MetaTypeId::Object => "Object", + MetaTypeId::Interface => "Interface", + MetaTypeId::Union => "Union", + MetaTypeId::Enum => "Enum", + MetaTypeId::InputObject => "InputObject", + }) + } +} + #[derive(Clone)] pub enum MetaType { Scalar { @@ -234,6 +258,18 @@ pub enum MetaType { } impl MetaType { + #[inline] + pub fn type_id(&self) -> MetaTypeId { + match self { + MetaType::Scalar { .. } => MetaTypeId::Scalar, + MetaType::Object { .. } => MetaTypeId::Object, + MetaType::Interface { .. } => MetaTypeId::Interface, + MetaType::Union { .. } => MetaTypeId::Union, + MetaType::Enum { .. } => MetaTypeId::Enum, + MetaType::InputObject { .. } => MetaTypeId::InputObject, + } + } + #[inline] pub fn field_by_name(&self, name: &str) -> Option<&MetaField> { self.fields().and_then(|fields| fields.get(name)) @@ -371,30 +407,45 @@ pub struct Registry { } impl Registry { - pub fn create_input_type MetaType>( - &mut self, - mut f: F, - ) -> String { - self.create_type(&mut f, &*T::type_name(), std::any::type_name::()); + pub fn create_input_type(&mut self, type_id: MetaTypeId, mut f: F) -> String + where + T: InputType + ?Sized, + F: FnMut(&mut Registry) -> MetaType, + { + self.create_type( + &mut f, + &*T::type_name(), + std::any::type_name::(), + type_id, + ); T::qualified_type_name() } - pub fn create_output_type MetaType>( - &mut self, - mut f: F, - ) -> String { - self.create_type(&mut f, &*T::type_name(), std::any::type_name::()); + pub fn create_output_type(&mut self, type_id: MetaTypeId, mut f: F) -> String + where + T: OutputType + ?Sized, + F: FnMut(&mut Registry) -> MetaType, + { + self.create_type( + &mut f, + &*T::type_name(), + std::any::type_name::(), + type_id, + ); T::qualified_type_name() } - pub fn create_subscription_type< + pub fn create_subscription_type(&mut self, mut f: F) -> String + where T: SubscriptionType + ?Sized, F: FnMut(&mut Registry) -> MetaType, - >( - &mut self, - mut f: F, - ) -> String { - self.create_type(&mut f, &*T::type_name(), std::any::type_name::()); + { + self.create_type( + &mut f, + &*T::type_name(), + std::any::type_name::(), + MetaTypeId::Object, + ); T::qualified_type_name() } @@ -403,16 +454,30 @@ impl Registry { f: &mut F, name: &str, rust_typename: &str, + type_id: MetaTypeId, ) { match self.types.get(name) { Some(ty) => { if let Some(prev_typename) = ty.rust_typename() { - if prev_typename != "__fake_type__" && rust_typename != prev_typename { + if prev_typename == "__fake_type__" { + return; + } + + if rust_typename != prev_typename { panic!( "`{}` and `{}` have the same GraphQL name `{}`", prev_typename, rust_typename, name, ); } + + if ty.type_id() != type_id { + panic!( + "Register `{}` as `{}`, but it is already registered as `{}`", + name, + type_id, + ty.type_id() + ); + } } } None => { diff --git a/src/resolver_utils/scalar.rs b/src/resolver_utils/scalar.rs index f17b01c4..85dd9c27 100644 --- a/src/resolver_utils/scalar.rs +++ b/src/resolver_utils/scalar.rs @@ -154,12 +154,14 @@ macro_rules! scalar_internal { fn create_type_info( registry: &mut $crate::registry::Registry, ) -> ::std::string::String { - registry.create_input_type::<$ty, _>(|_| $crate::registry::MetaType::Scalar { - name: ::std::borrow::ToOwned::to_owned($name), - description: $desc, - is_valid: |value| <$ty as $crate::ScalarType>::is_valid(value), - visible: ::std::option::Option::None, - specified_by_url: $specified_by_url, + registry.create_input_type::<$ty, _>($crate::registry::MetaTypeId::Scalar, |_| { + $crate::registry::MetaType::Scalar { + name: ::std::borrow::ToOwned::to_owned($name), + description: $desc, + is_valid: |value| <$ty as $crate::ScalarType>::is_valid(value), + visible: ::std::option::Option::None, + specified_by_url: $specified_by_url, + } }) } @@ -187,12 +189,14 @@ macro_rules! scalar_internal { fn create_type_info( registry: &mut $crate::registry::Registry, ) -> ::std::string::String { - registry.create_output_type::<$ty, _>(|_| $crate::registry::MetaType::Scalar { - name: ::std::borrow::ToOwned::to_owned($name), - description: $desc, - is_valid: |value| <$ty as $crate::ScalarType>::is_valid(value), - visible: ::std::option::Option::None, - specified_by_url: $specified_by_url, + registry.create_output_type::<$ty, _>($crate::registry::MetaTypeId::Scalar, |_| { + $crate::registry::MetaType::Scalar { + name: ::std::borrow::ToOwned::to_owned($name), + description: $desc, + is_valid: |value| <$ty as $crate::ScalarType>::is_valid(value), + visible: ::std::option::Option::None, + specified_by_url: $specified_by_url, + } }) } diff --git a/src/types/connection/connection_type.rs b/src/types/connection/connection_type.rs index 52bd2fcf..e17c8340 100644 --- a/src/types/connection/connection_type.rs +++ b/src/types/connection/connection_type.rs @@ -6,6 +6,7 @@ use indexmap::map::IndexMap; use crate::connection::edge::Edge; use crate::connection::page_info::PageInfo; use crate::parser::types::Field; +use crate::registry::MetaTypeId; use crate::resolver_utils::{resolve_container, ContainerType}; use crate::types::connection::{CursorType, EmptyFields}; use crate::{ @@ -163,7 +164,7 @@ where } fn create_type_info(registry: &mut registry::Registry) -> String { - registry.create_output_type::(|registry| { + registry.create_output_type::(MetaTypeId::Object,|registry| { EC::create_type_info(registry); let additional_fields = if let Some(registry::MetaType::Object { fields, .. }) = registry.types.remove(EC::type_name().as_ref()) diff --git a/src/types/connection/edge.rs b/src/types/connection/edge.rs index b4704f05..54f4660a 100644 --- a/src/types/connection/edge.rs +++ b/src/types/connection/edge.rs @@ -4,6 +4,7 @@ use indexmap::map::IndexMap; use crate::connection::EmptyFields; use crate::parser::types::Field; +use crate::registry::MetaTypeId; use crate::resolver_utils::{resolve_container, ContainerType}; use crate::types::connection::CursorType; use crate::{ @@ -72,7 +73,7 @@ where } fn create_type_info(registry: &mut registry::Registry) -> String { - registry.create_output_type::(|registry| { + registry.create_output_type::(MetaTypeId::Object, |registry| { let additional_fields = if let registry::MetaType::Object { fields, .. } = registry.create_fake_output_type::() { diff --git a/src/types/empty_mutation.rs b/src/types/empty_mutation.rs index 7b5f2f3c..16a684ce 100644 --- a/src/types/empty_mutation.rs +++ b/src/types/empty_mutation.rs @@ -1,6 +1,7 @@ use std::borrow::Cow; use crate::parser::types::Field; +use crate::registry::MetaTypeId; use crate::resolver_utils::ContainerType; use crate::{ registry, Context, ContextSelectionSet, ObjectType, OutputType, Positioned, ServerError, @@ -49,7 +50,7 @@ impl OutputType for EmptyMutation { } fn create_type_info(registry: &mut registry::Registry) -> String { - registry.create_output_type::(|_| registry::MetaType::Object { + registry.create_output_type::(MetaTypeId::Object, |_| registry::MetaType::Object { name: "EmptyMutation".to_string(), description: None, fields: Default::default(), diff --git a/src/types/external/json_object/btreemap.rs b/src/types/external/json_object/btreemap.rs index 9df8a2c6..221e78d1 100644 --- a/src/types/external/json_object/btreemap.rs +++ b/src/types/external/json_object/btreemap.rs @@ -10,7 +10,7 @@ use indexmap::IndexMap; use serde::de::DeserializeOwned; use serde::Serialize; -use crate::registry::{MetaType, Registry}; +use crate::registry::{MetaType, MetaTypeId, Registry}; use crate::{ ContextSelectionSet, InputType, InputValueError, InputValueResult, Name, OutputType, ServerResult, Value, @@ -29,7 +29,7 @@ where } fn create_type_info(registry: &mut Registry) -> String { - registry.create_input_type::(|_| MetaType::Scalar { + registry.create_input_type::(MetaTypeId::Scalar, |_| MetaType::Scalar { name: ::type_name().to_string(), description: Some("A scalar that can represent any JSON Object value."), is_valid: |_| true, @@ -84,7 +84,7 @@ where } fn create_type_info(registry: &mut Registry) -> String { - registry.create_output_type::(|_| MetaType::Scalar { + registry.create_output_type::(MetaTypeId::Scalar, |_| MetaType::Scalar { name: ::type_name().to_string(), description: Some("A scalar that can represent any JSON Object value."), is_valid: |_| true, diff --git a/src/types/external/json_object/hashmap.rs b/src/types/external/json_object/hashmap.rs index 09f96450..1df5caf9 100644 --- a/src/types/external/json_object/hashmap.rs +++ b/src/types/external/json_object/hashmap.rs @@ -11,7 +11,7 @@ use indexmap::IndexMap; use serde::de::DeserializeOwned; use serde::Serialize; -use crate::registry::{MetaType, Registry}; +use crate::registry::{MetaType, MetaTypeId, Registry}; use crate::{ ContextSelectionSet, InputType, InputValueError, InputValueResult, Name, OutputType, ServerResult, Value, @@ -31,7 +31,7 @@ where } fn create_type_info(registry: &mut Registry) -> String { - registry.create_input_type::(|_| MetaType::Scalar { + registry.create_input_type::(MetaTypeId::Scalar, |_| MetaType::Scalar { name: ::type_name().to_string(), description: Some("A scalar that can represent any JSON Object value."), is_valid: |_| true, @@ -87,7 +87,7 @@ where } fn create_type_info(registry: &mut Registry) -> String { - registry.create_output_type::(|_| MetaType::Scalar { + registry.create_output_type::(MetaTypeId::Scalar, |_| MetaType::Scalar { name: ::type_name().to_string(), description: Some("A scalar that can represent any JSON Object value."), is_valid: |_| true, diff --git a/src/types/json.rs b/src/types/json.rs index e80fa089..89971ccd 100644 --- a/src/types/json.rs +++ b/src/types/json.rs @@ -5,7 +5,7 @@ use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use crate::parser::types::Field; -use crate::registry::{MetaType, Registry}; +use crate::registry::{MetaType, MetaTypeId, Registry}; use crate::{ from_value, to_value, ContextSelectionSet, InputType, InputValueResult, OutputType, Positioned, ServerResult, Value, @@ -46,7 +46,7 @@ impl InputType for Json { } fn create_type_info(registry: &mut Registry) -> String { - registry.create_input_type::, _>(|_| MetaType::Scalar { + registry.create_input_type::, _>(MetaTypeId::Scalar, |_| MetaType::Scalar { name: ::type_name().to_string(), description: Some("A scalar that can represent any JSON value."), is_valid: |_| true, @@ -75,7 +75,7 @@ impl OutputType for Json { } fn create_type_info(registry: &mut Registry) -> String { - registry.create_output_type::, _>(|_| MetaType::Scalar { + registry.create_output_type::, _>(MetaTypeId::Scalar, |_| MetaType::Scalar { name: ::type_name().to_string(), description: Some("A scalar that can represent any JSON value."), is_valid: |_| true, @@ -101,12 +101,14 @@ impl InputType for serde_json::Value { } fn create_type_info(registry: &mut Registry) -> String { - registry.create_input_type::(|_| MetaType::Scalar { - name: ::type_name().to_string(), - description: Some("A scalar that can represent any JSON value."), - is_valid: |_| true, - visible: None, - specified_by_url: None, + registry.create_input_type::(MetaTypeId::Scalar, |_| { + MetaType::Scalar { + name: ::type_name().to_string(), + description: Some("A scalar that can represent any JSON value."), + is_valid: |_| true, + visible: None, + specified_by_url: None, + } }) } @@ -130,12 +132,14 @@ impl OutputType for serde_json::Value { } fn create_type_info(registry: &mut Registry) -> String { - registry.create_output_type::(|_| MetaType::Scalar { - name: ::type_name().to_string(), - description: Some("A scalar that can represent any JSON value."), - is_valid: |_| true, - visible: None, - specified_by_url: None, + registry.create_output_type::(MetaTypeId::Scalar, |_| { + MetaType::Scalar { + name: ::type_name().to_string(), + description: Some("A scalar that can represent any JSON value."), + is_valid: |_| true, + visible: None, + specified_by_url: None, + } }) } diff --git a/src/types/merged_object.rs b/src/types/merged_object.rs index b6ff21fd..09fe1b46 100644 --- a/src/types/merged_object.rs +++ b/src/types/merged_object.rs @@ -5,7 +5,7 @@ use indexmap::IndexMap; use crate::futures_util::Stream; use crate::parser::types::Field; -use crate::registry::{MetaType, Registry}; +use crate::registry::{MetaType, MetaTypeId, Registry}; use crate::{ CacheControl, ContainerType, Context, ContextSelectionSet, OutputType, Positioned, Response, ServerResult, SimpleObject, SubscriptionType, Value, @@ -48,7 +48,7 @@ where } fn create_type_info(registry: &mut Registry) -> String { - registry.create_output_type::(|registry| { + registry.create_output_type::(MetaTypeId::Object, |registry| { let mut fields = IndexMap::new(); let mut cc = CacheControl::default(); diff --git a/src/types/upload.rs b/src/types/upload.rs index 23df60e3..06b9ed06 100644 --- a/src/types/upload.rs +++ b/src/types/upload.rs @@ -5,6 +5,7 @@ use std::io::Read; #[cfg(feature = "unblock")] use futures_util::io::AsyncRead; +use crate::registry::MetaTypeId; use crate::{registry, Context, InputType, InputValueError, InputValueResult, Value}; /// A file upload value. @@ -109,7 +110,7 @@ impl InputType for Upload { } fn create_type_info(registry: &mut registry::Registry) -> String { - registry.create_input_type::(|_| registry::MetaType::Scalar { + registry.create_input_type::(MetaTypeId::Scalar, |_| registry::MetaType::Scalar { name: Self::type_name().to_string(), description: None, is_valid: |value| matches!(value, Value::String(_)), diff --git a/tests/input_object.rs b/tests/input_object.rs index 92019b22..d9c86ee9 100644 --- a/tests/input_object.rs +++ b/tests/input_object.rs @@ -407,6 +407,31 @@ pub async fn test_both_input_output() { assert_eq!(::type_name(), "MyObject"); } +#[test] +#[should_panic] +pub fn test_both_input_output_with_same_name() { + #[derive(SimpleObject, InputObject)] + #[allow(dead_code)] + struct MyObject { + #[graphql(default = 10)] + a: i32, + b: bool, + #[graphql(skip)] + c: String, + } + + struct Query; + + #[Object] + impl Query { + async fn obj(&self, input: MyObject) -> MyObject { + input + } + } + + Schema::new(Query, EmptyMutation, EmptySubscription); +} + #[tokio::test] pub async fn test_skip_input() { #[derive(SimpleObject, InputObject)]