Modify some type names (internal types)

This commit is contained in:
Sunli 2020-05-15 10:08:37 +08:00
parent b92f6a568e
commit f74652e61a
31 changed files with 215 additions and 196 deletions

View File

@ -115,7 +115,7 @@ pub fn generate(enum_args: &args::Enum, input: &DeriveInput) -> Result<TokenStre
} }
}); });
schema_enum_items.push(quote! { schema_enum_items.push(quote! {
enum_items.insert(#gql_item_name, #crate_name::registry::EnumValue { enum_items.insert(#gql_item_name, #crate_name::registry::MetaEnumValue {
name: #gql_item_name, name: #gql_item_name,
description: #item_desc, description: #item_desc,
deprecation: #item_deprecation, deprecation: #item_deprecation,
@ -142,7 +142,7 @@ pub fn generate(enum_args: &args::Enum, input: &DeriveInput) -> Result<TokenStre
fn create_type_info(registry: &mut #crate_name::registry::Registry) -> String { fn create_type_info(registry: &mut #crate_name::registry::Registry) -> String {
registry.create_type::<Self, _>(|registry| { registry.create_type::<Self, _>(|registry| {
#crate_name::registry::Type::Enum { #crate_name::registry::MetaType::Enum {
name: #gql_typename.to_string(), name: #gql_typename.to_string(),
description: #desc, description: #desc,
enum_values: { enum_values: {

View File

@ -97,7 +97,7 @@ pub fn generate(object_args: &args::InputObject, input: &DeriveInput) -> Result<
fields.push(ident); fields.push(ident);
schema_fields.push(quote! { schema_fields.push(quote! {
fields.insert(#name.to_string(), #crate_name::registry::InputValue { fields.insert(#name.to_string(), #crate_name::registry::MetaInputValue {
name: #name, name: #name,
description: #desc, description: #desc,
ty: <#ty as #crate_name::Type>::create_type_info(registry), ty: <#ty as #crate_name::Type>::create_type_info(registry),
@ -116,7 +116,7 @@ pub fn generate(object_args: &args::InputObject, input: &DeriveInput) -> Result<
} }
fn create_type_info(registry: &mut #crate_name::registry::Registry) -> String { fn create_type_info(registry: &mut #crate_name::registry::Registry) -> String {
registry.create_type::<Self, _>(|registry| #crate_name::registry::Type::InputObject { registry.create_type::<Self, _>(|registry| #crate_name::registry::MetaType::InputObject {
name: #gql_typename.to_string(), name: #gql_typename.to_string(),
description: #desc, description: #desc,
input_fields: { input_fields: {

View File

@ -177,7 +177,7 @@ pub fn generate(interface_args: &args::Interface, input: &DeriveInput) -> Result
}) })
.unwrap_or_else(|| quote! {None}); .unwrap_or_else(|| quote! {None});
schema_args.push(quote! { schema_args.push(quote! {
args.insert(#name, #crate_name::registry::InputValue { args.insert(#name, #crate_name::registry::MetaInputValue {
name: #name, name: #name,
description: #desc, description: #desc,
ty: <#ty as #crate_name::Type>::create_type_info(registry), ty: <#ty as #crate_name::Type>::create_type_info(registry),
@ -219,7 +219,7 @@ pub fn generate(interface_args: &args::Interface, input: &DeriveInput) -> Result
}); });
schema_fields.push(quote! { schema_fields.push(quote! {
fields.insert(#name.to_string(), #crate_name::registry::Field { fields.insert(#name.to_string(), #crate_name::registry::MetaField {
name: #name.to_string(), name: #name.to_string(),
description: #desc, description: #desc,
args: { args: {
@ -282,7 +282,7 @@ pub fn generate(interface_args: &args::Interface, input: &DeriveInput) -> Result
registry.create_type::<Self, _>(|registry| { registry.create_type::<Self, _>(|registry| {
#(#registry_types)* #(#registry_types)*
#crate_name::registry::Type::Interface { #crate_name::registry::MetaType::Interface {
name: #gql_typename.to_string(), name: #gql_typename.to_string(),
description: #desc, description: #desc,
fields: { fields: {

View File

@ -156,7 +156,7 @@ pub fn Scalar(args: TokenStream, input: TokenStream) -> TokenStream {
} }
fn create_type_info(registry: &mut #crate_name::registry::Registry) -> String { fn create_type_info(registry: &mut #crate_name::registry::Registry) -> String {
registry.create_type::<#self_ty, _>(|_| #crate_name::registry::Type::Scalar { registry.create_type::<#self_ty, _>(|_| #crate_name::registry::MetaType::Scalar {
name: <#self_ty as #crate_name::ScalarType>::type_name().to_string(), name: <#self_ty as #crate_name::ScalarType>::type_name().to_string(),
description: <#self_ty>::description(), description: <#self_ty>::description(),
is_valid: |value| <#self_ty as #crate_name::ScalarType>::is_valid(value), is_valid: |value| <#self_ty as #crate_name::ScalarType>::is_valid(value),

View File

@ -310,7 +310,7 @@ pub fn generate(object_args: &args::Object, item_impl: &mut ItemImpl) -> Result<
.unwrap_or_else(|| quote! {None}); .unwrap_or_else(|| quote! {None});
schema_args.push(quote! { schema_args.push(quote! {
args.insert(#name, #crate_name::registry::InputValue { args.insert(#name, #crate_name::registry::MetaInputValue {
name: #name, name: #name,
description: #desc, description: #desc,
ty: <#ty as #crate_name::Type>::create_type_info(registry), ty: <#ty as #crate_name::Type>::create_type_info(registry),
@ -339,7 +339,7 @@ pub fn generate(object_args: &args::Object, item_impl: &mut ItemImpl) -> Result<
let schema_ty = ty.value_type(); let schema_ty = ty.value_type();
schema_fields.push(quote! { schema_fields.push(quote! {
fields.insert(#field_name.to_string(), #crate_name::registry::Field { fields.insert(#field_name.to_string(), #crate_name::registry::MetaField {
name: #field_name.to_string(), name: #field_name.to_string(),
description: #field_desc, description: #field_desc,
args: { args: {
@ -437,7 +437,7 @@ pub fn generate(object_args: &args::Object, item_impl: &mut ItemImpl) -> Result<
} }
fn create_type_info(registry: &mut #crate_name::registry::Registry) -> String { fn create_type_info(registry: &mut #crate_name::registry::Registry) -> String {
let ty = registry.create_type::<Self, _>(|registry| #crate_name::registry::Type::Object { let ty = registry.create_type::<Self, _>(|registry| #crate_name::registry::MetaType::Object {
name: #gql_typename.to_string(), name: #gql_typename.to_string(),
description: #desc, description: #desc,
fields: { fields: {

View File

@ -78,7 +78,7 @@ pub fn generate(object_args: &args::Object, input: &mut DeriveInput) -> Result<T
}; };
schema_fields.push(quote! { schema_fields.push(quote! {
fields.insert(#field_name.to_string(), #crate_name::registry::Field { fields.insert(#field_name.to_string(), #crate_name::registry::MetaField {
name: #field_name.to_string(), name: #field_name.to_string(),
description: #field_desc, description: #field_desc,
args: Default::default(), args: Default::default(),
@ -157,7 +157,7 @@ pub fn generate(object_args: &args::Object, input: &mut DeriveInput) -> Result<T
} }
fn create_type_info(registry: &mut #crate_name::registry::Registry) -> String { fn create_type_info(registry: &mut #crate_name::registry::Registry) -> String {
registry.create_type::<Self, _>(|registry| #crate_name::registry::Type::Object { registry.create_type::<Self, _>(|registry| #crate_name::registry::MetaType::Object {
name: #gql_typename.to_string(), name: #gql_typename.to_string(),
description: #desc, description: #desc,
fields: { fields: {

View File

@ -162,7 +162,7 @@ pub fn generate(object_args: &args::Object, item_impl: &mut ItemImpl) -> Result<
.unwrap_or_else(|| quote! {None}); .unwrap_or_else(|| quote! {None});
schema_args.push(quote! { schema_args.push(quote! {
args.insert(#name, #crate_name::registry::InputValue { args.insert(#name, #crate_name::registry::MetaInputValue {
name: #name, name: #name,
description: #desc, description: #desc,
ty: <#ty as #crate_name::Type>::create_type_info(registry), ty: <#ty as #crate_name::Type>::create_type_info(registry),
@ -209,7 +209,7 @@ pub fn generate(object_args: &args::Object, item_impl: &mut ItemImpl) -> Result<
} }
schema_fields.push(quote! { schema_fields.push(quote! {
fields.insert(#field_name.to_string(), #crate_name::registry::Field { fields.insert(#field_name.to_string(), #crate_name::registry::MetaField {
name: #field_name.to_string(), name: #field_name.to_string(),
description: #field_desc, description: #field_desc,
args: { args: {
@ -312,7 +312,7 @@ pub fn generate(object_args: &args::Object, item_impl: &mut ItemImpl) -> Result<
#[allow(bare_trait_objects)] #[allow(bare_trait_objects)]
fn create_type_info(registry: &mut #crate_name::registry::Registry) -> String { fn create_type_info(registry: &mut #crate_name::registry::Registry) -> String {
registry.create_type::<Self, _>(|registry| #crate_name::registry::Type::Object { registry.create_type::<Self, _>(|registry| #crate_name::registry::MetaType::Object {
name: #gql_typename.to_string(), name: #gql_typename.to_string(),
description: #desc, description: #desc,
fields: { fields: {

View File

@ -115,7 +115,7 @@ pub fn generate(union_args: &args::Interface, input: &DeriveInput) -> Result<Tok
registry.create_type::<Self, _>(|registry| { registry.create_type::<Self, _>(|registry| {
#(#registry_types)* #(#registry_types)*
#crate_name::registry::Type::Union { #crate_name::registry::MetaType::Union {
name: #gql_typename.to_string(), name: #gql_typename.to_string(),
description: #desc, description: #desc,
possible_types: { possible_types: {

View File

@ -67,7 +67,7 @@ pub enum __DirectiveLocation {
pub struct __Directive<'a> { pub struct __Directive<'a> {
pub registry: &'a registry::Registry, pub registry: &'a registry::Registry,
pub directive: &'a registry::Directive, pub directive: &'a registry::MetaDirective,
} }
/// A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document. /// A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.

View File

@ -3,7 +3,7 @@ use async_graphql_derive::Object;
pub struct __EnumValue<'a> { pub struct __EnumValue<'a> {
pub registry: &'a registry::Registry, pub registry: &'a registry::Registry,
pub value: &'a registry::EnumValue, pub value: &'a registry::MetaEnumValue,
} }
/// One possible value for a given Enum. Enum values are unique values, not a placeholder for a string or numeric value. However an Enum value is returned in a JSON response as a string. /// One possible value for a given Enum. Enum values are unique values, not a placeholder for a string or numeric value. However an Enum value is returned in a JSON response as a string.

View File

@ -5,7 +5,7 @@ use itertools::Itertools;
pub struct __Field<'a> { pub struct __Field<'a> {
pub registry: &'a registry::Registry, pub registry: &'a registry::Registry,
pub field: &'a registry::Field, pub field: &'a registry::MetaField,
} }
/// Object and Interface types are described by a list of Fields, each of which has a name, potentially a list of arguments, and a return type. /// Object and Interface types are described by a list of Fields, each of which has a name, potentially a list of arguments, and a return type.

View File

@ -4,7 +4,7 @@ use async_graphql_derive::Object;
pub struct __InputValue<'a> { pub struct __InputValue<'a> {
pub registry: &'a registry::Registry, pub registry: &'a registry::Registry,
pub input_value: &'a registry::InputValue, pub input_value: &'a registry::MetaInputValue,
} }
/// Arguments provided to Fields or Directives and the input fields of an InputObject are represented as Input Values which describe their type and optionally a default value. /// Arguments provided to Fields or Directives and the input fields of an InputObject are represented as Input Values which describe their type and optionally a default value.

View File

@ -4,7 +4,7 @@ use async_graphql_derive::Object;
use itertools::Itertools; use itertools::Itertools;
enum TypeDetail<'a> { enum TypeDetail<'a> {
Named(&'a registry::Type), Named(&'a registry::MetaType),
NonNull(String), NonNull(String),
List(String), List(String),
} }
@ -15,7 +15,7 @@ pub struct __Type<'a> {
} }
impl<'a> __Type<'a> { impl<'a> __Type<'a> {
pub fn new_simple(registry: &'a registry::Registry, ty: &'a registry::Type) -> __Type<'a> { pub fn new_simple(registry: &'a registry::Registry, ty: &'a registry::MetaType) -> __Type<'a> {
__Type { __Type {
registry, registry,
detail: TypeDetail::Named(ty), detail: TypeDetail::Named(ty),
@ -23,16 +23,16 @@ impl<'a> __Type<'a> {
} }
pub fn new(registry: &'a registry::Registry, type_name: &str) -> __Type<'a> { pub fn new(registry: &'a registry::Registry, type_name: &str) -> __Type<'a> {
match registry::TypeName::create(type_name) { match registry::MetaTypeName::create(type_name) {
registry::TypeName::NonNull(ty) => __Type { registry::MetaTypeName::NonNull(ty) => __Type {
registry, registry,
detail: TypeDetail::NonNull(ty.to_string()), detail: TypeDetail::NonNull(ty.to_string()),
}, },
registry::TypeName::List(ty) => __Type { registry::MetaTypeName::List(ty) => __Type {
registry, registry,
detail: TypeDetail::List(ty.to_string()), detail: TypeDetail::List(ty.to_string()),
}, },
registry::TypeName::Named(ty) => __Type { registry::MetaTypeName::Named(ty) => __Type {
registry, registry,
detail: TypeDetail::Named(&registry.types[ty]), detail: TypeDetail::Named(&registry.types[ty]),
}, },
@ -48,12 +48,12 @@ impl<'a> __Type<'a> {
async fn kind(&self) -> __TypeKind { async fn kind(&self) -> __TypeKind {
match &self.detail { match &self.detail {
TypeDetail::Named(ty) => match ty { TypeDetail::Named(ty) => match ty {
registry::Type::Scalar { .. } => __TypeKind::Scalar, registry::MetaType::Scalar { .. } => __TypeKind::Scalar,
registry::Type::Object { .. } => __TypeKind::Object, registry::MetaType::Object { .. } => __TypeKind::Object,
registry::Type::Interface { .. } => __TypeKind::Interface, registry::MetaType::Interface { .. } => __TypeKind::Interface,
registry::Type::Union { .. } => __TypeKind::Union, registry::MetaType::Union { .. } => __TypeKind::Union,
registry::Type::Enum { .. } => __TypeKind::Enum, registry::MetaType::Enum { .. } => __TypeKind::Enum,
registry::Type::InputObject { .. } => __TypeKind::InputObject, registry::MetaType::InputObject { .. } => __TypeKind::InputObject,
}, },
TypeDetail::NonNull(_) => __TypeKind::NonNull, TypeDetail::NonNull(_) => __TypeKind::NonNull,
TypeDetail::List(_) => __TypeKind::List, TypeDetail::List(_) => __TypeKind::List,
@ -71,12 +71,18 @@ impl<'a> __Type<'a> {
async fn description(&self) -> Option<String> { async fn description(&self) -> Option<String> {
match &self.detail { match &self.detail {
TypeDetail::Named(ty) => match ty { TypeDetail::Named(ty) => match ty {
registry::Type::Scalar { description, .. } => description.map(|s| s.to_string()), registry::MetaType::Scalar { description, .. } => {
registry::Type::Object { description, .. } => description.map(|s| s.to_string()), description.map(|s| s.to_string())
registry::Type::Interface { description, .. } => description.map(|s| s.to_string()), }
registry::Type::Union { description, .. } => description.map(|s| s.to_string()), registry::MetaType::Object { description, .. } => {
registry::Type::Enum { description, .. } => description.map(|s| s.to_string()), description.map(|s| s.to_string())
registry::Type::InputObject { description, .. } => { }
registry::MetaType::Interface { description, .. } => {
description.map(|s| s.to_string())
}
registry::MetaType::Union { description, .. } => description.map(|s| s.to_string()),
registry::MetaType::Enum { description, .. } => description.map(|s| s.to_string()),
registry::MetaType::InputObject { description, .. } => {
description.map(|s| s.to_string()) description.map(|s| s.to_string())
} }
}, },
@ -111,7 +117,7 @@ impl<'a> __Type<'a> {
} }
async fn interfaces(&self) -> Option<Vec<__Type<'a>>> { async fn interfaces(&self) -> Option<Vec<__Type<'a>>> {
if let TypeDetail::Named(registry::Type::Object { name, .. }) = &self.detail { if let TypeDetail::Named(registry::MetaType::Object { name, .. }) = &self.detail {
Some( Some(
self.registry self.registry
.implements .implements
@ -127,14 +133,17 @@ impl<'a> __Type<'a> {
} }
async fn possible_types(&self) -> Option<Vec<__Type<'a>>> { async fn possible_types(&self) -> Option<Vec<__Type<'a>>> {
if let TypeDetail::Named(registry::Type::Interface { possible_types, .. }) = &self.detail { if let TypeDetail::Named(registry::MetaType::Interface { possible_types, .. }) =
&self.detail
{
Some( Some(
possible_types possible_types
.iter() .iter()
.map(|ty| __Type::new(self.registry, ty)) .map(|ty| __Type::new(self.registry, ty))
.collect(), .collect(),
) )
} else if let TypeDetail::Named(registry::Type::Union { possible_types, .. }) = &self.detail } else if let TypeDetail::Named(registry::MetaType::Union { possible_types, .. }) =
&self.detail
{ {
Some( Some(
possible_types possible_types
@ -151,7 +160,7 @@ impl<'a> __Type<'a> {
&self, &self,
#[arg(default = "false")] include_deprecated: bool, #[arg(default = "false")] include_deprecated: bool,
) -> Option<Vec<__EnumValue<'a>>> { ) -> Option<Vec<__EnumValue<'a>>> {
if let TypeDetail::Named(registry::Type::Enum { enum_values, .. }) = &self.detail { if let TypeDetail::Named(registry::MetaType::Enum { enum_values, .. }) = &self.detail {
Some( Some(
enum_values enum_values
.values() .values()
@ -168,7 +177,9 @@ impl<'a> __Type<'a> {
} }
async fn input_fields(&self) -> Option<Vec<__InputValue<'a>>> { async fn input_fields(&self) -> Option<Vec<__InputValue<'a>>> {
if let TypeDetail::Named(registry::Type::InputObject { input_fields, .. }) = &self.detail { if let TypeDetail::Named(registry::MetaType::InputObject { input_fields, .. }) =
&self.detail
{
Some( Some(
input_fields input_fields
.values() .values()

View File

@ -22,43 +22,43 @@ fn parse_list(type_name: &str) -> Option<&str> {
} }
#[derive(Clone, Copy, PartialEq, Debug)] #[derive(Clone, Copy, PartialEq, Debug)]
pub enum TypeName<'a> { pub enum MetaTypeName<'a> {
List(&'a str), List(&'a str),
NonNull(&'a str), NonNull(&'a str),
Named(&'a str), Named(&'a str),
} }
impl<'a> std::fmt::Display for TypeName<'a> { impl<'a> std::fmt::Display for MetaTypeName<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
TypeName::Named(name) => write!(f, "{}", name), MetaTypeName::Named(name) => write!(f, "{}", name),
TypeName::NonNull(name) => write!(f, "{}!", name), MetaTypeName::NonNull(name) => write!(f, "{}!", name),
TypeName::List(name) => write!(f, "[{}]", name), MetaTypeName::List(name) => write!(f, "[{}]", name),
} }
} }
} }
impl<'a> TypeName<'a> { impl<'a> MetaTypeName<'a> {
pub fn create(type_name: &str) -> TypeName { pub fn create(type_name: &str) -> MetaTypeName {
if let Some(type_name) = parse_non_null(type_name) { if let Some(type_name) = parse_non_null(type_name) {
TypeName::NonNull(type_name) MetaTypeName::NonNull(type_name)
} else if let Some(type_name) = parse_list(type_name) { } else if let Some(type_name) = parse_list(type_name) {
TypeName::List(type_name) MetaTypeName::List(type_name)
} else { } else {
TypeName::Named(type_name) MetaTypeName::Named(type_name)
} }
} }
pub fn concrete_typename(type_name: &str) -> &str { pub fn concrete_typename(type_name: &str) -> &str {
match TypeName::create(type_name) { match MetaTypeName::create(type_name) {
TypeName::List(type_name) => Self::concrete_typename(type_name), MetaTypeName::List(type_name) => Self::concrete_typename(type_name),
TypeName::NonNull(type_name) => Self::concrete_typename(type_name), MetaTypeName::NonNull(type_name) => Self::concrete_typename(type_name),
TypeName::Named(type_name) => type_name, MetaTypeName::Named(type_name) => type_name,
} }
} }
pub fn is_non_null(&self) -> bool { pub fn is_non_null(&self) -> bool {
if let TypeName::NonNull(_) = self { if let MetaTypeName::NonNull(_) = self {
true true
} else { } else {
false false
@ -67,20 +67,22 @@ impl<'a> TypeName<'a> {
pub fn unwrap_non_null(&self) -> Self { pub fn unwrap_non_null(&self) -> Self {
match self { match self {
TypeName::NonNull(ty) => TypeName::create(ty), MetaTypeName::NonNull(ty) => MetaTypeName::create(ty),
_ => *self, _ => *self,
} }
} }
pub fn is_subtype(&self, sub: &TypeName<'_>) -> bool { pub fn is_subtype(&self, sub: &MetaTypeName<'_>) -> bool {
match (self, sub) { match (self, sub) {
(TypeName::NonNull(super_type), TypeName::NonNull(sub_type)) (MetaTypeName::NonNull(super_type), MetaTypeName::NonNull(sub_type))
| (TypeName::Named(super_type), TypeName::NonNull(sub_type)) => { | (MetaTypeName::Named(super_type), MetaTypeName::NonNull(sub_type)) => {
TypeName::create(super_type).is_subtype(&TypeName::create(sub_type)) MetaTypeName::create(super_type).is_subtype(&MetaTypeName::create(sub_type))
} }
(TypeName::Named(super_type), TypeName::Named(sub_type)) => super_type == sub_type, (MetaTypeName::Named(super_type), MetaTypeName::Named(sub_type)) => {
(TypeName::List(super_type), TypeName::List(sub_type)) => { super_type == sub_type
TypeName::create(super_type).is_subtype(&TypeName::create(sub_type)) }
(MetaTypeName::List(super_type), MetaTypeName::List(sub_type)) => {
MetaTypeName::create(super_type).is_subtype(&MetaTypeName::create(sub_type))
} }
_ => false, _ => false,
} }
@ -88,7 +90,7 @@ impl<'a> TypeName<'a> {
} }
#[derive(Clone)] #[derive(Clone)]
pub struct InputValue { pub struct MetaInputValue {
pub name: &'static str, pub name: &'static str,
pub description: Option<&'static str>, pub description: Option<&'static str>,
pub ty: String, pub ty: String,
@ -97,10 +99,10 @@ pub struct InputValue {
} }
#[derive(Clone)] #[derive(Clone)]
pub struct Field { pub struct MetaField {
pub name: String, pub name: String,
pub description: Option<&'static str>, pub description: Option<&'static str>,
pub args: HashMap<&'static str, InputValue>, pub args: HashMap<&'static str, MetaInputValue>,
pub ty: String, pub ty: String,
pub deprecation: Option<&'static str>, pub deprecation: Option<&'static str>,
pub cache_control: CacheControl, pub cache_control: CacheControl,
@ -110,7 +112,7 @@ pub struct Field {
} }
#[derive(Clone)] #[derive(Clone)]
pub struct EnumValue { pub struct MetaEnumValue {
pub name: &'static str, pub name: &'static str,
pub description: Option<&'static str>, pub description: Option<&'static str>,
pub deprecation: Option<&'static str>, pub deprecation: Option<&'static str>,
@ -192,7 +194,7 @@ impl CacheControl {
} }
} }
pub enum Type { pub enum MetaType {
Scalar { Scalar {
name: String, name: String,
description: Option<&'static str>, description: Option<&'static str>,
@ -201,7 +203,7 @@ pub enum Type {
Object { Object {
name: String, name: String,
description: Option<&'static str>, description: Option<&'static str>,
fields: HashMap<String, Field>, fields: HashMap<String, MetaField>,
cache_control: CacheControl, cache_control: CacheControl,
extends: bool, extends: bool,
keys: Option<Vec<String>>, keys: Option<Vec<String>>,
@ -209,7 +211,7 @@ pub enum Type {
Interface { Interface {
name: String, name: String,
description: Option<&'static str>, description: Option<&'static str>,
fields: HashMap<String, Field>, fields: HashMap<String, MetaField>,
possible_types: HashSet<String>, possible_types: HashSet<String>,
extends: bool, extends: bool,
keys: Option<Vec<String>>, keys: Option<Vec<String>>,
@ -222,92 +224,92 @@ pub enum Type {
Enum { Enum {
name: String, name: String,
description: Option<&'static str>, description: Option<&'static str>,
enum_values: HashMap<&'static str, EnumValue>, enum_values: HashMap<&'static str, MetaEnumValue>,
}, },
InputObject { InputObject {
name: String, name: String,
description: Option<&'static str>, description: Option<&'static str>,
input_fields: HashMap<String, InputValue>, input_fields: HashMap<String, MetaInputValue>,
}, },
} }
impl Type { impl MetaType {
pub fn field_by_name(&self, name: &str) -> Option<&Field> { pub fn field_by_name(&self, name: &str) -> Option<&MetaField> {
self.fields().and_then(|fields| fields.get(name)) self.fields().and_then(|fields| fields.get(name))
} }
pub fn fields(&self) -> Option<&HashMap<String, Field>> { pub fn fields(&self) -> Option<&HashMap<String, MetaField>> {
match self { match self {
Type::Object { fields, .. } => Some(&fields), MetaType::Object { fields, .. } => Some(&fields),
Type::Interface { fields, .. } => Some(&fields), MetaType::Interface { fields, .. } => Some(&fields),
_ => None, _ => None,
} }
} }
pub fn name(&self) -> &str { pub fn name(&self) -> &str {
match self { match self {
Type::Scalar { name, .. } => &name, MetaType::Scalar { name, .. } => &name,
Type::Object { name, .. } => name, MetaType::Object { name, .. } => name,
Type::Interface { name, .. } => name, MetaType::Interface { name, .. } => name,
Type::Union { name, .. } => name, MetaType::Union { name, .. } => name,
Type::Enum { name, .. } => name, MetaType::Enum { name, .. } => name,
Type::InputObject { name, .. } => name, MetaType::InputObject { name, .. } => name,
} }
} }
pub fn is_composite(&self) -> bool { pub fn is_composite(&self) -> bool {
match self { match self {
Type::Object { .. } => true, MetaType::Object { .. } => true,
Type::Interface { .. } => true, MetaType::Interface { .. } => true,
Type::Union { .. } => true, MetaType::Union { .. } => true,
_ => false, _ => false,
} }
} }
pub fn is_abstract(&self) -> bool { pub fn is_abstract(&self) -> bool {
match self { match self {
Type::Interface { .. } => true, MetaType::Interface { .. } => true,
Type::Union { .. } => true, MetaType::Union { .. } => true,
_ => false, _ => false,
} }
} }
pub fn is_leaf(&self) -> bool { pub fn is_leaf(&self) -> bool {
match self { match self {
Type::Enum { .. } => true, MetaType::Enum { .. } => true,
Type::Scalar { .. } => true, MetaType::Scalar { .. } => true,
_ => false, _ => false,
} }
} }
pub fn is_input(&self) -> bool { pub fn is_input(&self) -> bool {
match self { match self {
Type::Enum { .. } => true, MetaType::Enum { .. } => true,
Type::Scalar { .. } => true, MetaType::Scalar { .. } => true,
Type::InputObject { .. } => true, MetaType::InputObject { .. } => true,
_ => false, _ => false,
} }
} }
pub fn is_possible_type(&self, type_name: &str) -> bool { pub fn is_possible_type(&self, type_name: &str) -> bool {
match self { match self {
Type::Interface { possible_types, .. } => possible_types.contains(type_name), MetaType::Interface { possible_types, .. } => possible_types.contains(type_name),
Type::Union { possible_types, .. } => possible_types.contains(type_name), MetaType::Union { possible_types, .. } => possible_types.contains(type_name),
Type::Object { name, .. } => name == type_name, MetaType::Object { name, .. } => name == type_name,
_ => false, _ => false,
} }
} }
pub fn possible_types(&self) -> Option<&HashSet<String>> { pub fn possible_types(&self) -> Option<&HashSet<String>> {
match self { match self {
Type::Interface { possible_types, .. } => Some(possible_types), MetaType::Interface { possible_types, .. } => Some(possible_types),
Type::Union { possible_types, .. } => Some(possible_types), MetaType::Union { possible_types, .. } => Some(possible_types),
_ => None, _ => None,
} }
} }
pub fn type_overlap(&self, ty: &Type) -> bool { pub fn type_overlap(&self, ty: &MetaType) -> bool {
if self as *const Type == ty as *const Type { if self as *const MetaType == ty as *const MetaType {
return true; return true;
} }
@ -325,16 +327,16 @@ impl Type {
} }
} }
pub struct Directive { pub struct MetaDirective {
pub name: &'static str, pub name: &'static str,
pub description: Option<&'static str>, pub description: Option<&'static str>,
pub locations: Vec<model::__DirectiveLocation>, pub locations: Vec<model::__DirectiveLocation>,
pub args: HashMap<&'static str, InputValue>, pub args: HashMap<&'static str, MetaInputValue>,
} }
pub struct Registry { pub struct Registry {
pub types: HashMap<String, Type>, pub types: HashMap<String, MetaType>,
pub directives: HashMap<String, Directive>, pub directives: HashMap<String, MetaDirective>,
pub implements: HashMap<String, HashSet<String>>, pub implements: HashMap<String, HashSet<String>>,
pub query_type: String, pub query_type: String,
pub mutation_type: Option<String>, pub mutation_type: Option<String>,
@ -342,7 +344,7 @@ pub struct Registry {
} }
impl Registry { impl Registry {
pub fn create_type<T: crate::Type, F: FnMut(&mut Registry) -> Type>( pub fn create_type<T: crate::Type, F: FnMut(&mut Registry) -> MetaType>(
&mut self, &mut self,
mut f: F, mut f: F,
) -> String { ) -> String {
@ -350,7 +352,7 @@ impl Registry {
if !self.types.contains_key(name.as_ref()) { if !self.types.contains_key(name.as_ref()) {
self.types.insert( self.types.insert(
name.to_string(), name.to_string(),
Type::Object { MetaType::Object {
name: "".to_string(), name: "".to_string(),
description: None, description: None,
fields: Default::default(), fields: Default::default(),
@ -365,7 +367,7 @@ impl Registry {
T::qualified_type_name() T::qualified_type_name()
} }
pub fn add_directive(&mut self, directive: Directive) { pub fn add_directive(&mut self, directive: MetaDirective) {
self.directives self.directives
.insert(directive.name.to_string(), directive); .insert(directive.name.to_string(), directive);
} }
@ -385,8 +387,8 @@ impl Registry {
pub fn add_keys(&mut self, ty: &str, keys: &str) { pub fn add_keys(&mut self, ty: &str, keys: &str) {
let all_keys = match self.types.get_mut(ty) { let all_keys = match self.types.get_mut(ty) {
Some(Type::Object { keys: all_keys, .. }) => all_keys, Some(MetaType::Object { keys: all_keys, .. }) => all_keys,
Some(Type::Interface { keys: all_keys, .. }) => all_keys, Some(MetaType::Interface { keys: all_keys, .. }) => all_keys,
_ => return, _ => return,
}; };
if let Some(all_keys) = all_keys { if let Some(all_keys) = all_keys {
@ -396,11 +398,11 @@ impl Registry {
} }
} }
pub fn concrete_type_by_name(&self, type_name: &str) -> Option<&Type> { pub fn concrete_type_by_name(&self, type_name: &str) -> Option<&MetaType> {
self.types.get(TypeName::concrete_typename(type_name)) self.types.get(MetaTypeName::concrete_typename(type_name))
} }
pub fn concrete_type_by_parsed_type(&self, query_type: &ParsedType) -> Option<&Type> { pub fn concrete_type_by_parsed_type(&self, query_type: &ParsedType) -> Option<&MetaType> {
match query_type { match query_type {
ParsedType::NonNull(ty) => self.concrete_type_by_parsed_type(ty), ParsedType::NonNull(ty) => self.concrete_type_by_parsed_type(ty),
ParsedType::List(ty) => self.concrete_type_by_parsed_type(ty), ParsedType::List(ty) => self.concrete_type_by_parsed_type(ty),
@ -408,7 +410,7 @@ impl Registry {
} }
} }
fn create_federation_fields<'a, I: Iterator<Item = &'a Field>>(sdl: &mut String, it: I) { fn create_federation_fields<'a, I: Iterator<Item = &'a MetaField>>(sdl: &mut String, it: I) {
for field in it { for field in it {
if field.name.starts_with("__") { if field.name.starts_with("__") {
continue; continue;
@ -431,9 +433,9 @@ impl Registry {
} }
} }
fn create_federation_type(&self, ty: &Type, sdl: &mut String) { fn create_federation_type(&self, ty: &MetaType, sdl: &mut String) {
match ty { match ty {
Type::Object { MetaType::Object {
name, name,
fields, fields,
extends, extends,
@ -464,7 +466,7 @@ impl Registry {
Self::create_federation_fields(sdl, fields.values()); Self::create_federation_fields(sdl, fields.values());
writeln!(sdl, "}}").ok(); writeln!(sdl, "}}").ok();
} }
Type::Interface { MetaType::Interface {
name, name,
fields, fields,
extends, extends,
@ -498,10 +500,10 @@ impl Registry {
fn has_entities(&self) -> bool { fn has_entities(&self) -> bool {
self.types.values().any(|ty| match ty { self.types.values().any(|ty| match ty {
Type::Object { MetaType::Object {
keys: Some(keys), .. keys: Some(keys), ..
} => !keys.is_empty(), } => !keys.is_empty(),
Type::Interface { MetaType::Interface {
keys: Some(keys), .. keys: Some(keys), ..
} => !keys.is_empty(), } => !keys.is_empty(),
_ => false, _ => false,
@ -513,12 +515,12 @@ impl Registry {
.types .types
.values() .values()
.filter_map(|ty| match ty { .filter_map(|ty| match ty {
Type::Object { MetaType::Object {
name, name,
keys: Some(keys), keys: Some(keys),
.. ..
} if !keys.is_empty() => Some(name.clone()), } if !keys.is_empty() => Some(name.clone()),
Type::Interface { MetaType::Interface {
name, name,
keys: Some(keys), keys: Some(keys),
.. ..
@ -529,7 +531,7 @@ impl Registry {
self.types.insert( self.types.insert(
"_Entity".to_string(), "_Entity".to_string(),
Type::Union { MetaType::Union {
name: "_Entity".to_string(), name: "_Entity".to_string(),
description: None, description: None,
possible_types, possible_types,
@ -546,14 +548,14 @@ impl Registry {
self.types.insert( self.types.insert(
"_Service".to_string(), "_Service".to_string(),
Type::Object { MetaType::Object {
name: "_Service".to_string(), name: "_Service".to_string(),
description: None, description: None,
fields: { fields: {
let mut fields = HashMap::new(); let mut fields = HashMap::new();
fields.insert( fields.insert(
"sdl".to_string(), "sdl".to_string(),
Field { MetaField {
name: "sdl".to_string(), name: "sdl".to_string(),
description: None, description: None,
args: Default::default(), args: Default::default(),
@ -576,10 +578,10 @@ impl Registry {
self.create_entity_type(); self.create_entity_type();
let query_root = self.types.get_mut(&self.query_type).unwrap(); let query_root = self.types.get_mut(&self.query_type).unwrap();
if let Type::Object { fields, .. } = query_root { if let MetaType::Object { fields, .. } = query_root {
fields.insert( fields.insert(
"_service".to_string(), "_service".to_string(),
Field { MetaField {
name: "_service".to_string(), name: "_service".to_string(),
description: None, description: None,
args: Default::default(), args: Default::default(),
@ -594,14 +596,14 @@ impl Registry {
fields.insert( fields.insert(
"_entities".to_string(), "_entities".to_string(),
Field { MetaField {
name: "_entities".to_string(), name: "_entities".to_string(),
description: None, description: None,
args: { args: {
let mut args = HashMap::new(); let mut args = HashMap::new();
args.insert( args.insert(
"representations", "representations",
InputValue { MetaInputValue {
name: "representations", name: "representations",
description: None, description: None,
ty: "[_Any!]!".to_string(), ty: "[_Any!]!".to_string(),

View File

@ -43,7 +43,7 @@ impl<'a> Type for &'a str {
} }
fn create_type_info(registry: &mut registry::Registry) -> String { fn create_type_info(registry: &mut registry::Registry) -> String {
registry.create_type::<Self, _>(|_| registry::Type::Scalar { registry.create_type::<Self, _>(|_| registry::MetaType::Scalar {
name: Self::type_name().to_string(), name: Self::type_name().to_string(),
description: Some(STRING_DESC), description: Some(STRING_DESC),
is_valid: |value| match value { is_valid: |value| match value {

View File

@ -3,7 +3,7 @@ use crate::extensions::{BoxExtension, Extension};
use crate::model::__DirectiveLocation; use crate::model::__DirectiveLocation;
use crate::parser::parse_query; use crate::parser::parse_query;
use crate::query::QueryBuilder; use crate::query::QueryBuilder;
use crate::registry::{Directive, InputValue, Registry}; use crate::registry::{MetaDirective, MetaInputValue, Registry};
use crate::subscription::{create_connection, create_subscription_stream, SubscriptionTransport}; use crate::subscription::{create_connection, create_subscription_stream, SubscriptionTransport};
use crate::types::QueryRoot; use crate::types::QueryRoot;
use crate::validation::{check_rules, ValidationMode}; use crate::validation::{check_rules, ValidationMode};
@ -134,7 +134,7 @@ where
}, },
}; };
registry.add_directive(Directive { registry.add_directive(MetaDirective {
name: "include", name: "include",
description: Some("Directs the executor to include this field or fragment only when the `if` argument is true."), description: Some("Directs the executor to include this field or fragment only when the `if` argument is true."),
locations: vec![ locations: vec![
@ -144,7 +144,7 @@ where
], ],
args: { args: {
let mut args = HashMap::new(); let mut args = HashMap::new();
args.insert("if", InputValue { args.insert("if", MetaInputValue {
name: "if", name: "if",
description: Some("Included when true."), description: Some("Included when true."),
ty: "Boolean!".to_string(), ty: "Boolean!".to_string(),
@ -155,7 +155,7 @@ where
} }
}); });
registry.add_directive(Directive { registry.add_directive(MetaDirective {
name: "skip", name: "skip",
description: Some("Directs the executor to skip this field or fragment when the `if` argument is true."), description: Some("Directs the executor to skip this field or fragment when the `if` argument is true."),
locations: vec![ locations: vec![
@ -165,7 +165,7 @@ where
], ],
args: { args: {
let mut args = HashMap::new(); let mut args = HashMap::new();
args.insert("if", InputValue { args.insert("if", MetaInputValue {
name: "if", name: "if",
description: Some("Skipped when true."), description: Some("Skipped when true."),
ty: "Boolean!".to_string(), ty: "Boolean!".to_string(),

View File

@ -99,7 +99,7 @@ impl<T: OutputValueType + Send + Sync, E: ObjectType + Sync + Send> Type for Con
} }
fn create_type_info(registry: &mut registry::Registry) -> String { fn create_type_info(registry: &mut registry::Registry) -> String {
registry.create_type::<Self, _>(|registry| registry::Type::Object { registry.create_type::<Self, _>(|registry| registry::MetaType::Object {
name: Self::type_name().to_string(), name: Self::type_name().to_string(),
description: None, description: None,
fields: { fields: {
@ -107,7 +107,7 @@ impl<T: OutputValueType + Send + Sync, E: ObjectType + Sync + Send> Type for Con
fields.insert( fields.insert(
"pageInfo".to_string(), "pageInfo".to_string(),
registry::Field { registry::MetaField {
name: "pageInfo".to_string(), name: "pageInfo".to_string(),
description: Some("Information to aid in pagination."), description: Some("Information to aid in pagination."),
args: Default::default(), args: Default::default(),
@ -122,7 +122,7 @@ impl<T: OutputValueType + Send + Sync, E: ObjectType + Sync + Send> Type for Con
fields.insert( fields.insert(
"edges".to_string(), "edges".to_string(),
registry::Field { registry::MetaField {
name: "edges".to_string(), name: "edges".to_string(),
description: Some("A list of edges."), description: Some("A list of edges."),
args: Default::default(), args: Default::default(),
@ -137,7 +137,7 @@ impl<T: OutputValueType + Send + Sync, E: ObjectType + Sync + Send> Type for Con
fields.insert( fields.insert(
"totalCount".to_string(), "totalCount".to_string(),
registry::Field { registry::MetaField {
name: "totalCount".to_string(), name: "totalCount".to_string(),
description: Some(r#"A count of the total number of objects in this connection, ignoring pagination. This allows a client to fetch the first five objects by passing "5" as the argument to "first", then fetch the total count so it could display "5 of 83", for example."#), description: Some(r#"A count of the total number of objects in this connection, ignoring pagination. This allows a client to fetch the first five objects by passing "5" as the argument to "first", then fetch the total count so it could display "5 of 83", for example."#),
args: Default::default(), args: Default::default(),
@ -151,7 +151,7 @@ impl<T: OutputValueType + Send + Sync, E: ObjectType + Sync + Send> Type for Con
); );
let elements_name = T::type_name().to_plural().to_camel_case(); let elements_name = T::type_name().to_plural().to_camel_case();
fields.insert(elements_name.clone(),registry::Field{ fields.insert(elements_name.clone(),registry::MetaField {
name: elements_name, name: elements_name,
description: Some(r#"A list of all of the objects returned in the connection. This is a convenience field provided for quickly exploring the API; rather than querying for "{ edges { node } }" when no edge data is needed, this field can be be used instead. Note that when clients like Relay need to fetch the "cursor" field on the edge to enable efficient pagination, this shortcut cannot be used, and the full "{ edges { node } }" version should be used instead."#), description: Some(r#"A list of all of the objects returned in the connection. This is a convenience field provided for quickly exploring the API; rather than querying for "{ edges { node } }" when no edge data is needed, this field can be be used instead. Note that when clients like Relay need to fetch the "cursor" field on the edge to enable efficient pagination, this shortcut cannot be used, and the full "{ edges { node } }" version should be used instead."#),
args: Default::default(), args: Default::default(),

View File

@ -41,7 +41,7 @@ where
fn create_type_info(registry: &mut registry::Registry) -> String { fn create_type_info(registry: &mut registry::Registry) -> String {
registry.create_type::<Self, _>(|registry| { registry.create_type::<Self, _>(|registry| {
E::create_type_info(registry); E::create_type_info(registry);
let extra_fields = if let Some(registry::Type::Object { fields, .. }) = let extra_fields = if let Some(registry::MetaType::Object { fields, .. }) =
registry.types.remove(E::type_name().as_ref()) registry.types.remove(E::type_name().as_ref())
{ {
fields fields
@ -49,7 +49,7 @@ where
unreachable!() unreachable!()
}; };
registry::Type::Object { registry::MetaType::Object {
name: Self::type_name().to_string(), name: Self::type_name().to_string(),
description: Some("An edge in a connection."), description: Some("An edge in a connection."),
fields: { fields: {
@ -57,7 +57,7 @@ where
fields.insert( fields.insert(
"node".to_string(), "node".to_string(),
registry::Field { registry::MetaField {
name: "node".to_string(), name: "node".to_string(),
description: Some("The item at the end of the edge"), description: Some("The item at the end of the edge"),
args: Default::default(), args: Default::default(),
@ -72,7 +72,7 @@ where
fields.insert( fields.insert(
"cursor".to_string(), "cursor".to_string(),
registry::Field { registry::MetaField {
name: "cursor".to_string(), name: "cursor".to_string(),
description: Some("A cursor for use in pagination"), description: Some("A cursor for use in pagination"),
args: Default::default(), args: Default::default(),

View File

@ -30,7 +30,7 @@ impl Type for EmptyMutation {
} }
fn create_type_info(registry: &mut registry::Registry) -> String { fn create_type_info(registry: &mut registry::Registry) -> String {
registry.create_type::<Self, _>(|_| registry::Type::Object { registry.create_type::<Self, _>(|_| registry::MetaType::Object {
name: "EmptyMutation".to_string(), name: "EmptyMutation".to_string(),
description: None, description: None,
fields: Default::default(), fields: Default::default(),

View File

@ -19,7 +19,7 @@ impl Type for EmptySubscription {
} }
fn create_type_info(registry: &mut registry::Registry) -> String { fn create_type_info(registry: &mut registry::Registry) -> String {
registry.create_type::<Self, _>(|_| registry::Type::Object { registry.create_type::<Self, _>(|_| registry::MetaType::Object {
name: "EmptySubscription".to_string(), name: "EmptySubscription".to_string(),
description: None, description: None,
fields: Default::default(), fields: Default::default(),

View File

@ -27,12 +27,12 @@ impl<T: Type> Type for QueryRoot<T> {
fn create_type_info(registry: &mut registry::Registry) -> String { fn create_type_info(registry: &mut registry::Registry) -> String {
let schema_type = __Schema::create_type_info(registry); let schema_type = __Schema::create_type_info(registry);
let root = T::create_type_info(registry); let root = T::create_type_info(registry);
if let Some(registry::Type::Object { fields, .. }) = if let Some(registry::MetaType::Object { fields, .. }) =
registry.types.get_mut(T::type_name().as_ref()) registry.types.get_mut(T::type_name().as_ref())
{ {
fields.insert( fields.insert(
"__schema".to_string(), "__schema".to_string(),
registry::Field { registry::MetaField {
name: "__schema".to_string(), name: "__schema".to_string(),
description: Some("Access the current type schema of this server."), description: Some("Access the current type schema of this server."),
args: Default::default(), args: Default::default(),
@ -47,14 +47,14 @@ impl<T: Type> Type for QueryRoot<T> {
fields.insert( fields.insert(
"__type".to_string(), "__type".to_string(),
registry::Field { registry::MetaField {
name: "__type".to_string(), name: "__type".to_string(),
description: Some("Request the type information of a single type."), description: Some("Request the type information of a single type."),
args: { args: {
let mut args = HashMap::new(); let mut args = HashMap::new();
args.insert( args.insert(
"name", "name",
registry::InputValue { registry::MetaInputValue {
name: "name", name: "name",
description: None, description: None,
ty: "String!".to_string(), ty: "String!".to_string(),

View File

@ -67,7 +67,7 @@ impl<'a> Type for Upload {
} }
fn create_type_info(registry: &mut registry::Registry) -> String { fn create_type_info(registry: &mut registry::Registry) -> String {
registry.create_type::<Self, _>(|_| registry::Type::Scalar { registry.create_type::<Self, _>(|_| registry::MetaType::Scalar {
name: Self::type_name().to_string(), name: Self::type_name().to_string(),
description: None, description: None,
is_valid: |value| match value { is_valid: |value| match value {

View File

@ -1,6 +1,6 @@
use crate::context::QueryPathNode; use crate::context::QueryPathNode;
use crate::parser::ast::{Directive, Field}; use crate::parser::ast::{Directive, Field};
use crate::registry::InputValue; use crate::registry::MetaInputValue;
use crate::validation::utils::is_valid_input_value; use crate::validation::utils::is_valid_input_value;
use crate::validation::visitor::{Visitor, VisitorContext}; use crate::validation::visitor::{Visitor, VisitorContext};
use crate::{Positioned, QueryPathSegment, Value}; use crate::{Positioned, QueryPathSegment, Value};
@ -8,7 +8,7 @@ use std::collections::HashMap;
#[derive(Default)] #[derive(Default)]
pub struct ArgumentsOfCorrectType<'a> { pub struct ArgumentsOfCorrectType<'a> {
current_args: Option<&'a HashMap<&'static str, InputValue>>, current_args: Option<&'a HashMap<&'static str, MetaInputValue>>,
} }
impl<'a> Visitor<'a> for ArgumentsOfCorrectType<'a> { impl<'a> Visitor<'a> for ArgumentsOfCorrectType<'a> {

View File

@ -9,8 +9,8 @@ pub struct FieldsOnCorrectType;
impl<'a> Visitor<'a> for FieldsOnCorrectType { impl<'a> Visitor<'a> for FieldsOnCorrectType {
fn enter_field(&mut self, ctx: &mut VisitorContext<'a>, field: &'a Positioned<Field>) { fn enter_field(&mut self, ctx: &mut VisitorContext<'a>, field: &'a Positioned<Field>) {
if let Some(parent_type) = ctx.parent_type() { if let Some(parent_type) = ctx.parent_type() {
if let Some(registry::Type::Union { .. }) | Some(registry::Type::Interface { .. }) = if let Some(registry::MetaType::Union { .. })
ctx.parent_type() | Some(registry::MetaType::Interface { .. }) = ctx.parent_type()
{ {
if field.name.node == "__typename" { if field.name.node == "__typename" {
return; return;

View File

@ -1,5 +1,5 @@
use crate::parser::ast::{Directive, Field}; use crate::parser::ast::{Directive, Field};
use crate::registry::InputValue; use crate::registry::MetaInputValue;
use crate::validation::suggestion::make_suggestion; use crate::validation::suggestion::make_suggestion;
use crate::validation::visitor::{Visitor, VisitorContext}; use crate::validation::visitor::{Visitor, VisitorContext};
use crate::{Positioned, Value}; use crate::{Positioned, Value};
@ -15,7 +15,7 @@ enum ArgsType<'a> {
#[derive(Default)] #[derive(Default)]
pub struct KnownArgumentNames<'a> { pub struct KnownArgumentNames<'a> {
current_args: Option<(&'a HashMap<&'static str, InputValue>, ArgsType<'a>)>, current_args: Option<(&'a HashMap<&'static str, MetaInputValue>, ArgsType<'a>)>,
} }
impl<'a> KnownArgumentNames<'a> { impl<'a> KnownArgumentNames<'a> {

View File

@ -1,5 +1,5 @@
use crate::parser::ast::{FragmentDefinition, InlineFragment, TypeCondition, VariableDefinition}; use crate::parser::ast::{FragmentDefinition, InlineFragment, TypeCondition, VariableDefinition};
use crate::registry::TypeName; use crate::registry::MetaTypeName;
use crate::validation::visitor::{Visitor, VisitorContext}; use crate::validation::visitor::{Visitor, VisitorContext};
use crate::{Pos, Positioned}; use crate::{Pos, Positioned};
@ -23,7 +23,7 @@ impl<'a> Visitor<'a> for KnownTypeNames {
) { ) {
validate_type( validate_type(
ctx, ctx,
TypeName::concrete_typename(&variable_definition.var_type.to_string()), MetaTypeName::concrete_typename(&variable_definition.var_type.to_string()),
variable_definition.position(), variable_definition.position(),
); );
} }

View File

@ -1,5 +1,5 @@
use crate::parser::ast::{Directive, Field}; use crate::parser::ast::{Directive, Field};
use crate::registry::TypeName; use crate::registry::MetaTypeName;
use crate::validation::visitor::{Visitor, VisitorContext}; use crate::validation::visitor::{Visitor, VisitorContext};
use crate::Positioned; use crate::Positioned;
@ -14,7 +14,7 @@ impl<'a> Visitor<'a> for ProvidedNonNullArguments {
) { ) {
if let Some(schema_directive) = ctx.registry.directives.get(directive.name.node) { if let Some(schema_directive) = ctx.registry.directives.get(directive.name.node) {
for arg in schema_directive.args.values() { for arg in schema_directive.args.values() {
if TypeName::create(&arg.ty).is_non_null() if MetaTypeName::create(&arg.ty).is_non_null()
&& arg.default_value.is_none() && arg.default_value.is_none()
&& directive && directive
.arguments .arguments
@ -36,7 +36,7 @@ impl<'a> Visitor<'a> for ProvidedNonNullArguments {
if let Some(parent_type) = ctx.parent_type() { if let Some(parent_type) = ctx.parent_type() {
if let Some(schema_field) = parent_type.field_by_name(&field.name) { if let Some(schema_field) = parent_type.field_by_name(&field.name) {
for arg in schema_field.args.values() { for arg in schema_field.args.values() {
if TypeName::create(&arg.ty).is_non_null() if MetaTypeName::create(&arg.ty).is_non_null()
&& arg.default_value.is_none() && arg.default_value.is_none()
&& field && field
.arguments .arguments

View File

@ -1,7 +1,7 @@
use crate::parser::ast::{ use crate::parser::ast::{
Document, FragmentDefinition, FragmentSpread, OperationDefinition, Type, VariableDefinition, Document, FragmentDefinition, FragmentSpread, OperationDefinition, Type, VariableDefinition,
}; };
use crate::registry::TypeName; use crate::registry::MetaTypeName;
use crate::validation::utils::{operation_name, Scope}; use crate::validation::utils::{operation_name, Scope};
use crate::validation::visitor::{Visitor, VisitorContext}; use crate::validation::visitor::{Visitor, VisitorContext};
use crate::{Pos, Positioned, Value}; use crate::{Pos, Positioned, Value};
@ -10,7 +10,7 @@ use std::collections::{HashMap, HashSet};
#[derive(Default)] #[derive(Default)]
pub struct VariableInAllowedPosition<'a> { pub struct VariableInAllowedPosition<'a> {
spreads: HashMap<Scope<'a>, HashSet<&'a str>>, spreads: HashMap<Scope<'a>, HashSet<&'a str>>,
variable_usages: HashMap<Scope<'a>, Vec<(&'a str, Pos, TypeName<'a>)>>, variable_usages: HashMap<Scope<'a>, Vec<(&'a str, Pos, MetaTypeName<'a>)>>,
variable_defs: HashMap<Scope<'a>, Vec<&'a Positioned<VariableDefinition>>>, variable_defs: HashMap<Scope<'a>, Vec<&'a Positioned<VariableDefinition>>>,
current_scope: Option<Scope<'a>>, current_scope: Option<Scope<'a>>,
} }
@ -38,7 +38,7 @@ impl<'a> VariableInAllowedPosition<'a> {
(_, _) => def.var_type.to_string(), (_, _) => def.var_type.to_string(),
}; };
if !var_type.is_subtype(&TypeName::create(&expected_type)) { if !var_type.is_subtype(&MetaTypeName::create(&expected_type)) {
ctx.report_error( ctx.report_error(
vec![def.position(), *usage_pos], vec![def.position(), *usage_pos],
format!( format!(
@ -113,7 +113,7 @@ impl<'a> Visitor<'a> for VariableInAllowedPosition<'a> {
&mut self, &mut self,
_ctx: &mut VisitorContext<'a>, _ctx: &mut VisitorContext<'a>,
pos: Pos, pos: Pos,
expected_type: &Option<TypeName<'a>>, expected_type: &Option<MetaTypeName<'a>>,
value: &'a Value, value: &'a Value,
) { ) {
if let Value::Variable(name) = value { if let Value::Variable(name) = value {

View File

@ -60,15 +60,15 @@ pub fn is_valid_input_value(
return None; return None;
} }
match registry::TypeName::create(type_name) { match registry::MetaTypeName::create(type_name) {
registry::TypeName::NonNull(type_name) => match value { registry::MetaTypeName::NonNull(type_name) => match value {
Value::Null => Some(valid_error( Value::Null => Some(valid_error(
&path_node, &path_node,
format!("expected type \"{}\"", type_name), format!("expected type \"{}\"", type_name),
)), )),
_ => is_valid_input_value(registry, type_name, value, path_node), _ => is_valid_input_value(registry, type_name, value, path_node),
}, },
registry::TypeName::List(type_name) => match value { registry::MetaTypeName::List(type_name) => match value {
Value::List(elems) => { Value::List(elems) => {
for (idx, elem) in elems.iter().enumerate() { for (idx, elem) in elems.iter().enumerate() {
if let Some(reason) = is_valid_input_value( if let Some(reason) = is_valid_input_value(
@ -87,14 +87,14 @@ pub fn is_valid_input_value(
} }
_ => is_valid_input_value(registry, type_name, value, path_node), _ => is_valid_input_value(registry, type_name, value, path_node),
}, },
registry::TypeName::Named(type_name) => { registry::MetaTypeName::Named(type_name) => {
if let Value::Null = value { if let Value::Null = value {
return None; return None;
} }
if let Some(ty) = registry.types.get(type_name) { if let Some(ty) = registry.types.get(type_name) {
match ty { match ty {
registry::Type::Scalar { is_valid, .. } => { registry::MetaType::Scalar { is_valid, .. } => {
if !is_valid(value) { if !is_valid(value) {
Some(valid_error( Some(valid_error(
&path_node, &path_node,
@ -104,7 +104,7 @@ pub fn is_valid_input_value(
None None
} }
} }
registry::Type::Enum { enum_values, .. } => match value { registry::MetaType::Enum { enum_values, .. } => match value {
Value::Enum(name) => { Value::Enum(name) => {
if !enum_values.contains_key(name) { if !enum_values.contains_key(name) {
Some(valid_error( Some(valid_error(
@ -124,7 +124,7 @@ pub fn is_valid_input_value(
format!("expected type \"{}\"", type_name), format!("expected type \"{}\"", type_name),
)), )),
}, },
registry::Type::InputObject { input_fields, .. } => match value { registry::MetaType::InputObject { input_fields, .. } => match value {
Value::Object(values) => { Value::Object(values) => {
let mut input_names = values let mut input_names = values
.keys() .keys()
@ -157,7 +157,7 @@ pub fn is_valid_input_value(
) { ) {
return Some(reason); return Some(reason);
} }
} else if registry::TypeName::create(&field.ty).is_non_null() } else if registry::MetaTypeName::create(&field.ty).is_non_null()
&& field.default_value.is_none() && field.default_value.is_none()
{ {
return Some(valid_error( return Some(valid_error(

View File

@ -3,15 +3,15 @@ use crate::parser::ast::{
Definition, Directive, Document, Field, FragmentDefinition, FragmentSpread, InlineFragment, Definition, Directive, Document, Field, FragmentDefinition, FragmentSpread, InlineFragment,
OperationDefinition, Selection, SelectionSet, TypeCondition, VariableDefinition, OperationDefinition, Selection, SelectionSet, TypeCondition, VariableDefinition,
}; };
use crate::registry::{self, Type, TypeName}; use crate::registry::{self, MetaType, MetaTypeName};
use crate::{Pos, Positioned, Value}; use crate::{Pos, Positioned, Value};
use std::collections::HashMap; use std::collections::HashMap;
pub struct VisitorContext<'a> { pub struct VisitorContext<'a> {
pub registry: &'a registry::Registry, pub registry: &'a registry::Registry,
pub errors: Vec<RuleError>, pub errors: Vec<RuleError>,
type_stack: Vec<Option<&'a registry::Type>>, type_stack: Vec<Option<&'a registry::MetaType>>,
input_type: Vec<Option<TypeName<'a>>>, input_type: Vec<Option<MetaTypeName<'a>>>,
fragments: HashMap<&'a str, &'a Positioned<FragmentDefinition>>, fragments: HashMap<&'a str, &'a Positioned<FragmentDefinition>>,
} }
@ -46,7 +46,7 @@ impl<'a> VisitorContext<'a> {
pub fn with_type<F: FnMut(&mut VisitorContext<'a>)>( pub fn with_type<F: FnMut(&mut VisitorContext<'a>)>(
&mut self, &mut self,
ty: Option<&'a registry::Type>, ty: Option<&'a registry::MetaType>,
mut f: F, mut f: F,
) { ) {
self.type_stack.push(ty); self.type_stack.push(ty);
@ -56,7 +56,7 @@ impl<'a> VisitorContext<'a> {
pub fn with_input_type<F: FnMut(&mut VisitorContext<'a>)>( pub fn with_input_type<F: FnMut(&mut VisitorContext<'a>)>(
&mut self, &mut self,
ty: Option<TypeName<'a>>, ty: Option<MetaTypeName<'a>>,
mut f: F, mut f: F,
) { ) {
self.input_type.push(ty); self.input_type.push(ty);
@ -64,7 +64,7 @@ impl<'a> VisitorContext<'a> {
self.input_type.pop(); self.input_type.pop();
} }
pub fn parent_type(&self) -> Option<&'a registry::Type> { pub fn parent_type(&self) -> Option<&'a registry::MetaType> {
if self.type_stack.len() >= 2 { if self.type_stack.len() >= 2 {
self.type_stack self.type_stack
.get(self.type_stack.len() - 2) .get(self.type_stack.len() - 2)
@ -75,7 +75,7 @@ impl<'a> VisitorContext<'a> {
} }
} }
pub fn current_type(&self) -> Option<&'a registry::Type> { pub fn current_type(&self) -> Option<&'a registry::MetaType> {
self.type_stack.last().copied().flatten() self.type_stack.last().copied().flatten()
} }
@ -218,7 +218,7 @@ pub trait Visitor<'a> {
&mut self, &mut self,
_ctx: &mut VisitorContext<'a>, _ctx: &mut VisitorContext<'a>,
_pos: Pos, _pos: Pos,
_expected_type: &Option<TypeName<'a>>, _expected_type: &Option<MetaTypeName<'a>>,
_value: &'a Value, _value: &'a Value,
) { ) {
} }
@ -226,7 +226,7 @@ pub trait Visitor<'a> {
&mut self, &mut self,
_ctx: &mut VisitorContext<'a>, _ctx: &mut VisitorContext<'a>,
_pos: Pos, _pos: Pos,
_expected_type: &Option<TypeName<'a>>, _expected_type: &Option<MetaTypeName<'a>>,
_value: &Value, _value: &Value,
) { ) {
} }
@ -581,7 +581,7 @@ fn visit_field<'a, V: Visitor<'a>>(
.parent_type() .parent_type()
.and_then(|ty| ty.field_by_name(&field.name)) .and_then(|ty| ty.field_by_name(&field.name))
.and_then(|schema_field| schema_field.args.get(name.node)) .and_then(|schema_field| schema_field.args.get(name.node))
.map(|input_ty| TypeName::create(&input_ty.ty)); .map(|input_ty| MetaTypeName::create(&input_ty.ty));
ctx.with_input_type(expected_ty, |ctx| { ctx.with_input_type(expected_ty, |ctx| {
visit_input_value(v, ctx, field.position(), expected_ty, value) visit_input_value(v, ctx, field.position(), expected_ty, value)
}); });
@ -597,7 +597,7 @@ fn visit_input_value<'a, V: Visitor<'a>>(
v: &mut V, v: &mut V,
ctx: &mut VisitorContext<'a>, ctx: &mut VisitorContext<'a>,
pos: Pos, pos: Pos,
expected_ty: Option<TypeName<'a>>, expected_ty: Option<MetaTypeName<'a>>,
value: &'a Value, value: &'a Value,
) { ) {
v.enter_input_value(ctx, pos, &expected_ty, value); v.enter_input_value(ctx, pos, &expected_ty, value);
@ -606,9 +606,15 @@ fn visit_input_value<'a, V: Visitor<'a>>(
Value::List(values) => { Value::List(values) => {
if let Some(expected_ty) = expected_ty { if let Some(expected_ty) = expected_ty {
let elem_ty = expected_ty.unwrap_non_null(); let elem_ty = expected_ty.unwrap_non_null();
if let TypeName::List(expected_ty) = elem_ty { if let MetaTypeName::List(expected_ty) = elem_ty {
values.iter().for_each(|value| { values.iter().for_each(|value| {
visit_input_value(v, ctx, pos, Some(TypeName::create(expected_ty)), value) visit_input_value(
v,
ctx,
pos,
Some(MetaTypeName::create(expected_ty)),
value,
)
}); });
} }
} }
@ -616,20 +622,20 @@ fn visit_input_value<'a, V: Visitor<'a>>(
Value::Object(values) => { Value::Object(values) => {
if let Some(expected_ty) = expected_ty { if let Some(expected_ty) = expected_ty {
let expected_ty = expected_ty.unwrap_non_null(); let expected_ty = expected_ty.unwrap_non_null();
if let TypeName::Named(expected_ty) = expected_ty { if let MetaTypeName::Named(expected_ty) = expected_ty {
if let Some(ty) = ctx if let Some(ty) = ctx
.registry .registry
.types .types
.get(TypeName::concrete_typename(expected_ty)) .get(MetaTypeName::concrete_typename(expected_ty))
{ {
if let Type::InputObject { input_fields, .. } = ty { if let MetaType::InputObject { input_fields, .. } = ty {
for (item_key, item_value) in values { for (item_key, item_value) in values {
if let Some(input_value) = input_fields.get(item_key.as_ref()) { if let Some(input_value) = input_fields.get(item_key.as_ref()) {
visit_input_value( visit_input_value(
v, v,
ctx, ctx,
pos, pos,
Some(TypeName::create(&input_value.ty)), Some(MetaTypeName::create(&input_value.ty)),
item_value, item_value,
); );
} }
@ -670,7 +676,7 @@ fn visit_directives<'a, V: Visitor<'a>>(
v.enter_argument(ctx, name, value); v.enter_argument(ctx, name, value);
let expected_ty = schema_directive let expected_ty = schema_directive
.and_then(|schema_directive| schema_directive.args.get(name.node)) .and_then(|schema_directive| schema_directive.args.get(name.node))
.map(|input_ty| TypeName::create(&input_ty.ty)); .map(|input_ty| MetaTypeName::create(&input_ty.ty));
ctx.with_input_type(expected_ty, |ctx| { ctx.with_input_type(expected_ty, |ctx| {
visit_input_value(v, ctx, d.position(), expected_ty, value) visit_input_value(v, ctx, d.position(), expected_ty, value)
}); });

View File

@ -1,5 +1,5 @@
use crate::parser::ast::{Field, SelectionSet}; use crate::parser::ast::{Field, SelectionSet};
use crate::registry::Type; use crate::registry::MetaType;
use crate::validation::visitor::{Visitor, VisitorContext}; use crate::validation::visitor::{Visitor, VisitorContext};
use crate::{CacheControl, Positioned}; use crate::{CacheControl, Positioned};
@ -14,7 +14,7 @@ impl<'ctx, 'a> Visitor<'ctx> for CacheControlCalculate<'a> {
_selection_set: &Positioned<SelectionSet>, _selection_set: &Positioned<SelectionSet>,
) { ) {
if let Some(current_type) = ctx.current_type() { if let Some(current_type) = ctx.current_type() {
if let Type::Object { cache_control, .. } = current_type { if let MetaType::Object { cache_control, .. } = current_type {
self.cache_control.merge(cache_control); self.cache_control.merge(cache_control);
} }
} }