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! {
enum_items.insert(#gql_item_name, #crate_name::registry::EnumValue {
enum_items.insert(#gql_item_name, #crate_name::registry::MetaEnumValue {
name: #gql_item_name,
description: #item_desc,
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 {
registry.create_type::<Self, _>(|registry| {
#crate_name::registry::Type::Enum {
#crate_name::registry::MetaType::Enum {
name: #gql_typename.to_string(),
description: #desc,
enum_values: {

View File

@ -97,7 +97,7 @@ pub fn generate(object_args: &args::InputObject, input: &DeriveInput) -> Result<
fields.push(ident);
schema_fields.push(quote! {
fields.insert(#name.to_string(), #crate_name::registry::InputValue {
fields.insert(#name.to_string(), #crate_name::registry::MetaInputValue {
name: #name,
description: #desc,
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 {
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(),
description: #desc,
input_fields: {

View File

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

View File

@ -78,7 +78,7 @@ pub fn generate(object_args: &args::Object, input: &mut DeriveInput) -> Result<T
};
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(),
description: #field_desc,
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 {
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(),
description: #desc,
fields: {

View File

@ -162,7 +162,7 @@ pub fn generate(object_args: &args::Object, item_impl: &mut ItemImpl) -> Result<
.unwrap_or_else(|| quote! {None});
schema_args.push(quote! {
args.insert(#name, #crate_name::registry::InputValue {
args.insert(#name, #crate_name::registry::MetaInputValue {
name: #name,
description: #desc,
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! {
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(),
description: #field_desc,
args: {
@ -312,7 +312,7 @@ pub fn generate(object_args: &args::Object, item_impl: &mut ItemImpl) -> Result<
#[allow(bare_trait_objects)]
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(),
description: #desc,
fields: {

View File

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

View File

@ -67,7 +67,7 @@ pub enum __DirectiveLocation {
pub struct __Directive<'a> {
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.

View File

@ -3,7 +3,7 @@ use async_graphql_derive::Object;
pub struct __EnumValue<'a> {
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.

View File

@ -5,7 +5,7 @@ use itertools::Itertools;
pub struct __Field<'a> {
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.

View File

@ -4,7 +4,7 @@ use async_graphql_derive::Object;
pub struct __InputValue<'a> {
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.

View File

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

View File

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

View File

@ -3,7 +3,7 @@ use crate::extensions::{BoxExtension, Extension};
use crate::model::__DirectiveLocation;
use crate::parser::parse_query;
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::types::QueryRoot;
use crate::validation::{check_rules, ValidationMode};
@ -134,7 +134,7 @@ where
},
};
registry.add_directive(Directive {
registry.add_directive(MetaDirective {
name: "include",
description: Some("Directs the executor to include this field or fragment only when the `if` argument is true."),
locations: vec![
@ -144,7 +144,7 @@ where
],
args: {
let mut args = HashMap::new();
args.insert("if", InputValue {
args.insert("if", MetaInputValue {
name: "if",
description: Some("Included when true."),
ty: "Boolean!".to_string(),
@ -155,7 +155,7 @@ where
}
});
registry.add_directive(Directive {
registry.add_directive(MetaDirective {
name: "skip",
description: Some("Directs the executor to skip this field or fragment when the `if` argument is true."),
locations: vec![
@ -165,7 +165,7 @@ where
],
args: {
let mut args = HashMap::new();
args.insert("if", InputValue {
args.insert("if", MetaInputValue {
name: "if",
description: Some("Skipped when true."),
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 {
registry.create_type::<Self, _>(|registry| registry::Type::Object {
registry.create_type::<Self, _>(|registry| registry::MetaType::Object {
name: Self::type_name().to_string(),
description: None,
fields: {
@ -107,7 +107,7 @@ impl<T: OutputValueType + Send + Sync, E: ObjectType + Sync + Send> Type for Con
fields.insert(
"pageInfo".to_string(),
registry::Field {
registry::MetaField {
name: "pageInfo".to_string(),
description: Some("Information to aid in pagination."),
args: Default::default(),
@ -122,7 +122,7 @@ impl<T: OutputValueType + Send + Sync, E: ObjectType + Sync + Send> Type for Con
fields.insert(
"edges".to_string(),
registry::Field {
registry::MetaField {
name: "edges".to_string(),
description: Some("A list of edges."),
args: Default::default(),
@ -137,7 +137,7 @@ impl<T: OutputValueType + Send + Sync, E: ObjectType + Sync + Send> Type for Con
fields.insert(
"totalCount".to_string(),
registry::Field {
registry::MetaField {
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."#),
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();
fields.insert(elements_name.clone(),registry::Field{
fields.insert(elements_name.clone(),registry::MetaField {
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."#),
args: Default::default(),

View File

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

View File

@ -30,7 +30,7 @@ impl Type for EmptyMutation {
}
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(),
description: None,
fields: Default::default(),

View File

@ -19,7 +19,7 @@ impl Type for EmptySubscription {
}
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(),
description: None,
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 {
let schema_type = __Schema::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())
{
fields.insert(
"__schema".to_string(),
registry::Field {
registry::MetaField {
name: "__schema".to_string(),
description: Some("Access the current type schema of this server."),
args: Default::default(),
@ -47,14 +47,14 @@ impl<T: Type> Type for QueryRoot<T> {
fields.insert(
"__type".to_string(),
registry::Field {
registry::MetaField {
name: "__type".to_string(),
description: Some("Request the type information of a single type."),
args: {
let mut args = HashMap::new();
args.insert(
"name",
registry::InputValue {
registry::MetaInputValue {
name: "name",
description: None,
ty: "String!".to_string(),

View File

@ -67,7 +67,7 @@ impl<'a> Type for Upload {
}
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(),
description: None,
is_valid: |value| match value {

View File

@ -1,6 +1,6 @@
use crate::context::QueryPathNode;
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::visitor::{Visitor, VisitorContext};
use crate::{Positioned, QueryPathSegment, Value};
@ -8,7 +8,7 @@ use std::collections::HashMap;
#[derive(Default)]
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> {

View File

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

View File

@ -1,5 +1,5 @@
use crate::parser::ast::{Directive, Field};
use crate::registry::InputValue;
use crate::registry::MetaInputValue;
use crate::validation::suggestion::make_suggestion;
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::{Positioned, Value};
@ -15,7 +15,7 @@ enum ArgsType<'a> {
#[derive(Default)]
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> {

View File

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

View File

@ -1,5 +1,5 @@
use crate::parser::ast::{Directive, Field};
use crate::registry::TypeName;
use crate::registry::MetaTypeName;
use crate::validation::visitor::{Visitor, VisitorContext};
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) {
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()
&& directive
.arguments
@ -36,7 +36,7 @@ impl<'a> Visitor<'a> for ProvidedNonNullArguments {
if let Some(parent_type) = ctx.parent_type() {
if let Some(schema_field) = parent_type.field_by_name(&field.name) {
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()
&& field
.arguments

View File

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

View File

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

View File

@ -3,15 +3,15 @@ use crate::parser::ast::{
Definition, Directive, Document, Field, FragmentDefinition, FragmentSpread, InlineFragment,
OperationDefinition, Selection, SelectionSet, TypeCondition, VariableDefinition,
};
use crate::registry::{self, Type, TypeName};
use crate::registry::{self, MetaType, MetaTypeName};
use crate::{Pos, Positioned, Value};
use std::collections::HashMap;
pub struct VisitorContext<'a> {
pub registry: &'a registry::Registry,
pub errors: Vec<RuleError>,
type_stack: Vec<Option<&'a registry::Type>>,
input_type: Vec<Option<TypeName<'a>>>,
type_stack: Vec<Option<&'a registry::MetaType>>,
input_type: Vec<Option<MetaTypeName<'a>>>,
fragments: HashMap<&'a str, &'a Positioned<FragmentDefinition>>,
}
@ -46,7 +46,7 @@ impl<'a> VisitorContext<'a> {
pub fn with_type<F: FnMut(&mut VisitorContext<'a>)>(
&mut self,
ty: Option<&'a registry::Type>,
ty: Option<&'a registry::MetaType>,
mut f: F,
) {
self.type_stack.push(ty);
@ -56,7 +56,7 @@ impl<'a> VisitorContext<'a> {
pub fn with_input_type<F: FnMut(&mut VisitorContext<'a>)>(
&mut self,
ty: Option<TypeName<'a>>,
ty: Option<MetaTypeName<'a>>,
mut f: F,
) {
self.input_type.push(ty);
@ -64,7 +64,7 @@ impl<'a> VisitorContext<'a> {
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 {
self.type_stack
.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()
}
@ -218,7 +218,7 @@ pub trait Visitor<'a> {
&mut self,
_ctx: &mut VisitorContext<'a>,
_pos: Pos,
_expected_type: &Option<TypeName<'a>>,
_expected_type: &Option<MetaTypeName<'a>>,
_value: &'a Value,
) {
}
@ -226,7 +226,7 @@ pub trait Visitor<'a> {
&mut self,
_ctx: &mut VisitorContext<'a>,
_pos: Pos,
_expected_type: &Option<TypeName<'a>>,
_expected_type: &Option<MetaTypeName<'a>>,
_value: &Value,
) {
}
@ -581,7 +581,7 @@ fn visit_field<'a, V: Visitor<'a>>(
.parent_type()
.and_then(|ty| ty.field_by_name(&field.name))
.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| {
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,
ctx: &mut VisitorContext<'a>,
pos: Pos,
expected_ty: Option<TypeName<'a>>,
expected_ty: Option<MetaTypeName<'a>>,
value: &'a 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) => {
if let Some(expected_ty) = expected_ty {
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| {
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) => {
if let Some(expected_ty) = expected_ty {
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
.registry
.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 {
if let Some(input_value) = input_fields.get(item_key.as_ref()) {
visit_input_value(
v,
ctx,
pos,
Some(TypeName::create(&input_value.ty)),
Some(MetaTypeName::create(&input_value.ty)),
item_value,
);
}
@ -670,7 +676,7 @@ fn visit_directives<'a, V: Visitor<'a>>(
v.enter_argument(ctx, name, value);
let expected_ty = schema_directive
.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| {
visit_input_value(v, ctx, d.position(), expected_ty, value)
});

View File

@ -1,5 +1,5 @@
use crate::parser::ast::{Field, SelectionSet};
use crate::registry::Type;
use crate::registry::MetaType;
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::{CacheControl, Positioned};
@ -14,7 +14,7 @@ impl<'ctx, 'a> Visitor<'ctx> for CacheControlCalculate<'a> {
_selection_set: &Positioned<SelectionSet>,
) {
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);
}
}