Allow the `deprecation` attribute to have no reason.

This commit is contained in:
Sunli 2021-02-27 11:59:58 +08:00
parent 144ddb752c
commit 4ebe0dd4cd
20 changed files with 208 additions and 60 deletions

View File

@ -4,6 +4,27 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2.5.8] - 2021-02-27
- Allow the `deprecation` attribute to have no reason.
```rust
#[derive(SimpleObject)]
struct MyObject {
#[graphql(deprecation)]
a: i32,
#[graphql(deprecation = true)]
b: i32,
#[graphql(deprecation = false)]
c: i32,
#[graphql(deprecation = "reason")]
d: i32,
}
```
## [2.5.7] - 2021-02-23
- Fix the problem that the borrowing lifetime returned by the `Context::data` function is too small.

View File

@ -86,6 +86,35 @@ pub struct ConcreteType {
pub params: PathList,
}
#[derive(Debug)]
pub enum Deprecation {
NoDeprecated,
Deprecated { reason: Option<String> },
}
impl Default for Deprecation {
fn default() -> Self {
Deprecation::NoDeprecated
}
}
impl FromMeta for Deprecation {
fn from_word() -> darling::Result<Self> {
Ok(Deprecation::Deprecated { reason: None })
}
fn from_value(value: &Lit) -> darling::Result<Self> {
match value {
Lit::Bool(LitBool { value: true, .. }) => Ok(Deprecation::Deprecated { reason: None }),
Lit::Bool(LitBool { value: false, .. }) => Ok(Deprecation::NoDeprecated),
Lit::Str(str) => Ok(Deprecation::Deprecated {
reason: Some(str.value()),
}),
_ => Err(darling::Error::unexpected_lit_type(value)),
}
}
}
#[derive(FromField)]
#[darling(attributes(graphql), forward_attrs(doc))]
pub struct SimpleObjectField {
@ -99,7 +128,7 @@ pub struct SimpleObjectField {
#[darling(default)]
pub name: Option<String>,
#[darling(default)]
pub deprecation: Option<String>,
pub deprecation: Deprecation,
#[darling(default)]
pub owned: bool,
#[darling(default)]
@ -198,7 +227,7 @@ pub struct ObjectField {
pub skip: bool,
pub entity: bool,
pub name: Option<String>,
pub deprecation: Option<String>,
pub deprecation: Deprecation,
pub cache_control: CacheControl,
pub external: bool,
pub provides: Option<String>,
@ -238,7 +267,7 @@ pub struct EnumItem {
#[darling(default)]
pub name: Option<String>,
#[darling(default)]
pub deprecation: Option<String>,
pub deprecation: Deprecation,
#[darling(default)]
pub visible: Option<Visible>,
}
@ -340,7 +369,7 @@ pub struct InterfaceField {
#[darling(default, multiple, rename = "arg")]
pub args: Vec<InterfaceFieldArgument>,
#[darling(default)]
pub deprecation: Option<String>,
pub deprecation: Deprecation,
#[darling(default)]
pub external: bool,
#[darling(default)]
@ -416,7 +445,7 @@ pub struct SubscriptionFieldArgument {
pub struct SubscriptionField {
pub skip: bool,
pub name: Option<String>,
pub deprecation: Option<String>,
pub deprecation: Deprecation,
pub guard: Option<Meta>,
pub visible: Option<Visible>,
pub complexity: Option<ComplexityType>,

View File

@ -5,7 +5,7 @@ use syn::ext::IdentExt;
use syn::Error;
use crate::args::{self, RenameRuleExt, RenameTarget};
use crate::utils::{get_crate_name, get_rustdoc, visible_fn, GeneratorResult};
use crate::utils::{gen_deprecation, get_crate_name, get_rustdoc, visible_fn, GeneratorResult};
pub fn generate(enum_args: &args::Enum) -> GeneratorResult<TokenStream> {
let crate_name = get_crate_name(enum_args.internal);
@ -46,11 +46,7 @@ pub fn generate(enum_args: &args::Enum) -> GeneratorResult<TokenStream> {
.rename_items
.rename(variant.ident.unraw().to_string(), RenameTarget::EnumItem)
});
let item_deprecation = variant
.deprecation
.as_ref()
.map(|s| quote! { ::std::option::Option::Some(#s) })
.unwrap_or_else(|| quote! {::std::option::Option::None});
let item_deprecation = gen_deprecation(&variant.deprecation, &crate_name);
let item_desc = get_rustdoc(&variant.attrs)?
.map(|s| quote! { ::std::option::Option::Some(#s) })
.unwrap_or_else(|| quote! {::std::option::Option::None});

View File

@ -9,7 +9,9 @@ use syn::{visit_mut, Error, Lifetime, Type};
use crate::args::{self, InterfaceField, InterfaceFieldArgument, RenameRuleExt, RenameTarget};
use crate::output_type::OutputType;
use crate::utils::{generate_default, get_crate_name, get_rustdoc, visible_fn, GeneratorResult};
use crate::utils::{
gen_deprecation, generate_default, get_crate_name, get_rustdoc, visible_fn, GeneratorResult,
};
pub fn generate(interface_args: &args::Interface) -> GeneratorResult<TokenStream> {
let crate_name = get_crate_name(interface_args.internal);
@ -241,10 +243,7 @@ pub fn generate(interface_args: &args::Interface) -> GeneratorResult<TokenStream
.as_ref()
.map(|s| quote! {::std::option::Option::Some(#s)})
.unwrap_or_else(|| quote! {::std::option::Option::None});
let deprecation = deprecation
.as_ref()
.map(|s| quote! {::std::option::Option::Some(#s)})
.unwrap_or_else(|| quote! {::std::option::Option::None});
let deprecation = gen_deprecation(deprecation, &crate_name);
let oty = OutputType::parse(&ty)?;
let ty = match oty {

View File

@ -7,9 +7,9 @@ use syn::{Block, Error, FnArg, Ident, ImplItem, ItemImpl, Pat, ReturnType, Type,
use crate::args::{self, ComplexityType, RenameRuleExt, RenameTarget};
use crate::output_type::OutputType;
use crate::utils::{
generate_default, generate_guards, generate_validator, get_cfg_attrs, get_crate_name,
get_param_getter_ident, get_rustdoc, get_type_path_and_name, parse_complexity_expr,
parse_graphql_attrs, remove_graphql_attrs, visible_fn, GeneratorResult,
gen_deprecation, generate_default, generate_guards, generate_validator, get_cfg_attrs,
get_crate_name, get_param_getter_ident, get_rustdoc, get_type_path_and_name,
parse_complexity_expr, parse_graphql_attrs, remove_graphql_attrs, visible_fn, GeneratorResult,
};
pub fn generate(
@ -233,11 +233,7 @@ pub fn generate(
let field_desc = get_rustdoc(&method.attrs)?
.map(|s| quote! { ::std::option::Option::Some(#s) })
.unwrap_or_else(|| quote! {::std::option::Option::None});
let field_deprecation = method_args
.deprecation
.as_ref()
.map(|s| quote! { ::std::option::Option::Some(#s) })
.unwrap_or_else(|| quote! {::std::option::Option::None});
let field_deprecation = gen_deprecation(&method_args.deprecation, &crate_name);
let external = method_args.external;
let requires = match &method_args.requires {
Some(requires) => quote! { ::std::option::Option::Some(#requires) },

View File

@ -5,7 +5,9 @@ use syn::ext::IdentExt;
use syn::Error;
use crate::args::{self, RenameRuleExt, RenameTarget};
use crate::utils::{generate_guards, get_crate_name, get_rustdoc, visible_fn, GeneratorResult};
use crate::utils::{
gen_deprecation, generate_guards, get_crate_name, get_rustdoc, visible_fn, GeneratorResult,
};
pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult<TokenStream> {
let crate_name = get_crate_name(object_args.internal);
@ -52,11 +54,7 @@ pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult<TokenStream
let field_desc = get_rustdoc(&field.attrs)?
.map(|s| quote! {::std::option::Option::Some(#s)})
.unwrap_or_else(|| quote! {::std::option::Option::None});
let field_deprecation = field
.deprecation
.as_ref()
.map(|s| quote! {::std::option::Option::Some(#s)})
.unwrap_or_else(|| quote! {::std::option::Option::None});
let field_deprecation = gen_deprecation(&field.deprecation, &crate_name);
let external = field.external;
let requires = match &field.requires {
Some(requires) => quote! { ::std::option::Option::Some(#requires) },

View File

@ -9,9 +9,9 @@ use syn::{
use crate::args::{self, ComplexityType, RenameRuleExt, RenameTarget, SubscriptionField};
use crate::output_type::OutputType;
use crate::utils::{
generate_default, generate_guards, generate_validator, get_cfg_attrs, get_crate_name,
get_param_getter_ident, get_rustdoc, get_type_path_and_name, parse_complexity_expr,
parse_graphql_attrs, remove_graphql_attrs, visible_fn, GeneratorResult,
gen_deprecation, generate_default, generate_guards, generate_validator, get_cfg_attrs,
get_crate_name, get_param_getter_ident, get_rustdoc, get_type_path_and_name,
parse_complexity_expr, parse_graphql_attrs, remove_graphql_attrs, visible_fn, GeneratorResult,
};
pub fn generate(
@ -54,11 +54,7 @@ pub fn generate(
let field_desc = get_rustdoc(&method.attrs)?
.map(|s| quote! {::std::option::Option::Some(#s)})
.unwrap_or_else(|| quote! {::std::option::Option::None});
let field_deprecation = field
.deprecation
.as_ref()
.map(|s| quote! {::std::option::Option::Some(#s)})
.unwrap_or_else(|| quote! {::std::option::Option::None});
let field_deprecation = gen_deprecation(&field.deprecation, &crate_name);
let cfg_attrs = get_cfg_attrs(&method.attrs);
if method.sig.asyncness.is_none() {

View File

@ -12,7 +12,7 @@ use syn::{
use thiserror::Error;
use crate::args;
use crate::args::Visible;
use crate::args::{Deprecation, Visible};
#[derive(Error, Debug)]
pub enum GeneratorError {
@ -440,3 +440,19 @@ pub fn parse_complexity_expr(s: &str) -> GeneratorResult<(HashSet<String>, Expr)
visit.visit_expr(&expr);
Ok((visit.variables, expr))
}
pub fn gen_deprecation(deprecation: &Deprecation, crate_name: &TokenStream) -> TokenStream {
match deprecation {
Deprecation::NoDeprecated => {
quote! { #crate_name::registry::Deprecation::NoDeprecated }
}
Deprecation::Deprecated {
reason: Some(reason),
} => {
quote! { #crate_name::registry::Deprecation::Deprecated { reason: ::std::option::Option::Some(#reason) } }
}
Deprecation::Deprecated { reason: None } => {
quote! { #crate_name::registry::Deprecation::Deprecated { reason: ::std::option::Option::None } }
}
}
}

View File

@ -265,6 +265,7 @@ pub type FieldResult<T> = Result<T>;
/// | skip | Skip this field | bool | Y |
/// | name | Field name | string | Y |
/// | desc | Field description | string | Y |
/// | deprecation | Field deprecated | bool | Y |
/// | deprecation | Field deprecation reason | string | Y |
/// | cache_control | Field cache control | [`CacheControl`](struct.CacheControl.html) | Y |
/// | external | Mark a field as owned by another service. This allows service A to use fields from service B while also knowing at runtime the types of that field. | bool | Y |
@ -441,6 +442,7 @@ pub use async_graphql_derive::Object;
/// |---------------|---------------------------|----------|----------|
/// | skip | Skip this field | bool | Y |
/// | name | Field name | string | Y |
/// | deprecation | Field deprecated | bool | Y |
/// | deprecation | Field deprecation reason | string | Y |
/// | owned | Field resolver return a ownedship value | bool | Y |
/// | cache_control | Field cache control | [`CacheControl`](struct.CacheControl.html) | Y |
@ -490,6 +492,7 @@ pub use async_graphql_derive::SimpleObject;
/// | Attribute | description | Type | Optional |
/// |-------------|---------------------------|----------|----------|
/// | name | Item name | string | Y |
/// | deprecation | Item deprecated | bool | Y |
/// | deprecation | Item deprecation reason | string | Y |
/// | visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |
/// | visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
@ -616,6 +619,7 @@ pub use async_graphql_derive::InputObject;
/// | type | Field type | string | N |
/// | method | Rust resolver method name. If specified, `name` will not be camelCased in schema definition | string | Y |
/// | desc | Field description | string | Y |
/// | deprecation | Field deprecated | bool | Y |
/// | deprecation | Field deprecation reason | string | Y |
/// | arg | Field arguments | [InterfaceFieldArgument] | Y |
/// | external | Mark a field as owned by another service. This allows service A to use fields from service B while also knowing at runtime the types of that field. | bool | Y |
@ -828,6 +832,7 @@ pub use async_graphql_derive::Union;
/// | Attribute | description | Type | Optional |
/// |-------------|---------------------------|----------|----------|
/// | name | Field name | string | Y |
/// | deprecation | Field deprecated | bool | Y |
/// | deprecation | Field deprecation reason | string | Y |
/// | guard | Field of guard | [`Guard`](guard/trait.Guard.html) | Y |
/// | visible | If `false`, it will not be displayed in introspection. *[See also the Book](https://async-graphql.github.io/async-graphql/en/visibility.html).* | bool | Y |

View File

@ -74,14 +74,17 @@ pub struct __Directive<'a> {
/// In some cases, you need to provide options to alter GraphQL's execution behavior in ways field arguments will not suffice, such as conditionally including or skipping a field. Directives provide this by describing additional information to the executor.
#[Object(internal, name = "__Directive")]
impl<'a> __Directive<'a> {
#[inline]
async fn name(&self) -> &str {
self.directive.name
}
#[inline]
async fn description(&self) -> Option<&str> {
self.directive.description
}
#[inline]
async fn locations(&self) -> &Vec<__DirectiveLocation> {
&self.directive.locations
}

View File

@ -8,19 +8,23 @@ pub struct __EnumValue<'a> {
/// 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.
#[Object(internal, name = "__EnumValue")]
impl<'a> __EnumValue<'a> {
#[inline]
async fn name(&self) -> &str {
self.value.name
}
#[inline]
async fn description(&self) -> Option<&str> {
self.value.description
}
#[inline]
async fn is_deprecated(&self) -> bool {
self.value.deprecation.is_some()
self.value.deprecation.is_deprecated()
}
#[inline]
async fn deprecation_reason(&self) -> Option<&str> {
self.value.deprecation
self.value.deprecation.reason()
}
}

View File

@ -9,10 +9,12 @@ pub struct __Field<'a> {
/// 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(internal, name = "__Field")]
impl<'a> __Field<'a> {
#[inline]
async fn name(&self) -> &str {
&self.field.name
}
#[inline]
async fn description(&self) -> Option<&str> {
self.field.description
}
@ -37,11 +39,13 @@ impl<'a> __Field<'a> {
__Type::new(self.registry, &self.field.ty)
}
#[inline]
async fn is_deprecated(&self) -> bool {
self.field.deprecation.is_some()
self.field.deprecation.is_deprecated()
}
#[inline]
async fn deprecation_reason(&self) -> Option<&str> {
self.field.deprecation
self.field.deprecation.reason()
}
}

View File

@ -9,19 +9,23 @@ pub struct __InputValue<'a> {
/// 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.
#[Object(internal, name = "__InputValue")]
impl<'a> __InputValue<'a> {
#[inline]
async fn name(&self) -> &str {
self.input_value.name
}
#[inline]
async fn description(&self) -> Option<&str> {
self.input_value.description
}
#[graphql(name = "type")]
#[inline]
async fn ty(&self) -> __Type<'a> {
__Type::new(self.registry, &self.input_value.ty)
}
#[inline]
async fn default_value(&self) -> Option<&str> {
self.input_value.default_value.as_deref()
}

View File

@ -27,6 +27,7 @@ impl<'a> __Schema<'a> {
}
/// The type that query operations will be rooted at.
#[inline]
async fn query_type(&self) -> __Type<'a> {
__Type::new_simple(
self.registry,
@ -35,6 +36,7 @@ impl<'a> __Schema<'a> {
}
/// If this server supports mutation, the type that mutation operations will be rooted at.
#[inline]
async fn mutation_type(&self) -> Option<__Type<'a>> {
if let Some(ty) = &self.registry.mutation_type {
Some(__Type::new_simple(self.registry, &self.registry.types[ty]))
@ -44,6 +46,7 @@ impl<'a> __Schema<'a> {
}
/// If this server support subscription, the type that subscription operations will be rooted at.
#[inline]
async fn subscription_type(&self) -> Option<__Type<'a>> {
if let Some(ty) = &self.registry.subscription_type {
Some(__Type::new_simple(self.registry, &self.registry.types[ty]))

View File

@ -13,6 +13,7 @@ pub struct __Type<'a> {
}
impl<'a> __Type<'a> {
#[inline]
pub fn new_simple(registry: &'a registry::Registry, ty: &'a registry::MetaType) -> __Type<'a> {
__Type {
registry,
@ -20,6 +21,7 @@ impl<'a> __Type<'a> {
}
}
#[inline]
pub fn new(registry: &'a registry::Registry, type_name: &str) -> __Type<'a> {
match registry::MetaTypeName::create(type_name) {
registry::MetaTypeName::NonNull(ty) => __Type {
@ -43,6 +45,7 @@ impl<'a> __Type<'a> {
/// Depending on the kind of a type, certain fields describe information about that type. Scalar types provide no information beyond a name and description, while Enum types provide their values. Object and Interface types provide the fields they describe. Abstract types, Union and Interface, provide the Object types possible at runtime. List and NonNull types compose other types.
#[Object(internal, name = "__Type")]
impl<'a> __Type<'a> {
#[inline]
async fn kind(&self) -> __TypeKind {
match &self.detail {
TypeDetail::Named(ty) => match ty {
@ -58,6 +61,7 @@ impl<'a> __Type<'a> {
}
}
#[inline]
async fn name(&self) -> Option<&str> {
match &self.detail {
TypeDetail::Named(ty) => Some(ty.name()),
@ -66,6 +70,7 @@ impl<'a> __Type<'a> {
}
}
#[inline]
async fn description(&self) -> Option<&str> {
match &self.detail {
TypeDetail::Named(ty) => match ty {
@ -95,7 +100,7 @@ impl<'a> __Type<'a> {
None => true,
})
.filter(|field| {
(include_deprecated || field.deprecation.is_none())
(include_deprecated || !field.deprecation.is_deprecated())
&& !field.name.starts_with("__")
})
.map(|field| __Field {
@ -162,7 +167,7 @@ impl<'a> __Type<'a> {
Some(f) => f(ctx),
None => true,
})
.filter(|value| include_deprecated || value.deprecation.is_none())
.filter(|value| include_deprecated || !value.deprecation.is_deprecated())
.map(|value| __EnumValue {
registry: self.registry,
value,
@ -196,6 +201,7 @@ impl<'a> __Type<'a> {
}
}
#[inline]
async fn of_type(&self) -> Option<__Type<'a>> {
if let TypeDetail::List(ty) = &self.detail {
Some(__Type::new(self.registry, &ty))

View File

@ -41,6 +41,7 @@ impl<'a> std::fmt::Display for MetaTypeName<'a> {
}
impl<'a> MetaTypeName<'a> {
#[inline]
pub fn create(type_name: &str) -> MetaTypeName {
if let Some(type_name) = type_name.strip_suffix('!') {
MetaTypeName::NonNull(type_name)
@ -51,6 +52,7 @@ impl<'a> MetaTypeName<'a> {
}
}
#[inline]
pub fn concrete_typename(type_name: &str) -> &str {
match MetaTypeName::create(type_name) {
MetaTypeName::List(type_name) => Self::concrete_typename(type_name),
@ -59,10 +61,12 @@ impl<'a> MetaTypeName<'a> {
}
}
#[inline]
pub fn is_non_null(&self) -> bool {
matches!(self, MetaTypeName::NonNull(_))
}
#[inline]
pub fn unwrap_non_null(&self) -> Self {
match self {
MetaTypeName::NonNull(ty) => MetaTypeName::create(ty),
@ -70,6 +74,7 @@ impl<'a> MetaTypeName<'a> {
}
}
#[inline]
pub fn is_subtype(&self, sub: &MetaTypeName<'_>) -> bool {
match (self, sub) {
(MetaTypeName::NonNull(super_type), MetaTypeName::NonNull(sub_type))
@ -86,6 +91,7 @@ impl<'a> MetaTypeName<'a> {
}
}
#[inline]
pub fn is_list(&self) -> bool {
match self {
MetaTypeName::List(_) => true,
@ -95,7 +101,6 @@ impl<'a> MetaTypeName<'a> {
}
}
#[derive(Clone)]
pub struct MetaInputValue {
pub name: &'static str,
pub description: Option<&'static str>,
@ -112,19 +117,44 @@ type ComputeComplexityFn = fn(
usize,
) -> ServerResult<usize>;
#[derive(Clone)]
pub enum ComplexityType {
Const(usize),
Fn(ComputeComplexityFn),
}
#[derive(Clone)]
#[derive(Debug)]
pub enum Deprecation {
NoDeprecated,
Deprecated { reason: Option<&'static str> },
}
impl Default for Deprecation {
fn default() -> Self {
Deprecation::NoDeprecated
}
}
impl Deprecation {
#[inline]
pub fn is_deprecated(&self) -> bool {
matches!(self, Deprecation::Deprecated { .. })
}
#[inline]
pub fn reason(&self) -> Option<&str> {
match self {
Deprecation::NoDeprecated => None,
Deprecation::Deprecated { reason } => reason.as_deref(),
}
}
}
pub struct MetaField {
pub name: String,
pub description: Option<&'static str>,
pub args: IndexMap<&'static str, MetaInputValue>,
pub ty: String,
pub deprecation: Option<&'static str>,
pub deprecation: Deprecation,
pub cache_control: CacheControl,
pub external: bool,
pub requires: Option<&'static str>,
@ -133,11 +163,10 @@ pub struct MetaField {
pub compute_complexity: Option<ComplexityType>,
}
#[derive(Clone)]
pub struct MetaEnumValue {
pub name: &'static str,
pub description: Option<&'static str>,
pub deprecation: Option<&'static str>,
pub deprecation: Deprecation,
pub visible: Option<MetaVisibleFn>,
}
@ -189,10 +218,12 @@ pub enum MetaType {
}
impl MetaType {
#[inline]
pub fn field_by_name(&self, name: &str) -> Option<&MetaField> {
self.fields().and_then(|fields| fields.get(name))
}
#[inline]
pub fn fields(&self) -> Option<&IndexMap<String, MetaField>> {
match self {
MetaType::Object { fields, .. } => Some(&fields),
@ -201,6 +232,7 @@ impl MetaType {
}
}
#[inline]
pub fn is_visible(&self, ctx: &Context<'_>) -> bool {
let visible = match self {
MetaType::Scalar { visible, .. } => visible,
@ -216,6 +248,7 @@ impl MetaType {
}
}
#[inline]
pub fn name(&self) -> &str {
match self {
MetaType::Scalar { name, .. } => &name,
@ -227,6 +260,7 @@ impl MetaType {
}
}
#[inline]
pub fn is_composite(&self) -> bool {
matches!(
self,
@ -234,14 +268,17 @@ impl MetaType {
)
}
#[inline]
pub fn is_abstract(&self) -> bool {
matches!(self, MetaType::Interface { .. } | MetaType::Union { .. })
}
#[inline]
pub fn is_leaf(&self) -> bool {
matches!(self, MetaType::Enum { .. } | MetaType::Scalar { .. })
}
#[inline]
pub fn is_input(&self) -> bool {
matches!(
self,
@ -249,6 +286,7 @@ impl MetaType {
)
}
#[inline]
pub fn is_possible_type(&self, type_name: &str) -> bool {
match self {
MetaType::Interface { possible_types, .. } => possible_types.contains(type_name),
@ -258,6 +296,7 @@ impl MetaType {
}
}
#[inline]
pub fn possible_types(&self) -> Option<&IndexSet<String>> {
match self {
MetaType::Interface { possible_types, .. } => Some(possible_types),
@ -457,7 +496,7 @@ impl Registry {
description: None,
args: Default::default(),
ty: "String".to_string(),
deprecation: None,
deprecation: Default::default(),
cache_control: Default::default(),
external: false,
requires: None,
@ -486,7 +525,7 @@ impl Registry {
description: None,
args: Default::default(),
ty: "_Service!".to_string(),
deprecation: None,
deprecation: Default::default(),
cache_control: Default::default(),
external: false,
requires: None,
@ -517,7 +556,7 @@ impl Registry {
args
},
ty: "[_Entity]!".to_string(),
deprecation: None,
deprecation: Default::default(),
cache_control: Default::default(),
external: false,
requires: None,

View File

@ -154,7 +154,7 @@ where
description: Some("Information to aid in pagination."),
args: Default::default(),
ty: PageInfo::create_type_info(registry),
deprecation: None,
deprecation: Default::default(),
cache_control: Default::default(),
external: false,
requires: None,
@ -173,7 +173,7 @@ where
ty: <Option<Vec<Option<Edge<C, T, EE>>>> as Type>::create_type_info(
registry,
),
deprecation: None,
deprecation: Default::default(),
cache_control: Default::default(),
external: false,
requires: None,

View File

@ -73,7 +73,7 @@ where
description: Some("The item at the end of the edge"),
args: Default::default(),
ty: T::create_type_info(registry),
deprecation: None,
deprecation: Default::default(),
cache_control: Default::default(),
external: false,
requires: None,
@ -90,7 +90,7 @@ where
description: Some("A cursor for use in pagination"),
args: Default::default(),
ty: String::create_type_info(registry),
deprecation: None,
deprecation: Default::default(),
cache_control: Default::default(),
external: false,
requires: None,

View File

@ -41,7 +41,7 @@ impl<T: Type> Type for QueryRoot<T> {
description: Some("Access the current type schema of this server."),
args: Default::default(),
ty: schema_type,
deprecation: None,
deprecation: Default::default(),
cache_control: Default::default(),
external: false,
requires: None,
@ -72,7 +72,7 @@ impl<T: Type> Type for QueryRoot<T> {
args
},
ty: "__Type".to_string(),
deprecation: None,
deprecation: Default::default(),
cache_control: Default::default(),
external: false,
requires: None,

View File

@ -109,6 +109,15 @@ struct SimpleObject {
#[graphql(deprecation = "Field e is deprecated")]
e: bool,
#[graphql(deprecation)]
e2: bool,
#[graphql(deprecation = true)]
e3: bool,
#[graphql(deprecation = false)]
e4: bool,
f: TestEnum,
g: TestInterface,
@ -329,6 +338,21 @@ pub async fn test_introspection_deprecation() {
"isDeprecated": true,
"deprecationReason": "Field e is deprecated"
},
{
"name": "e2",
"isDeprecated": true,
"deprecationReason": null
},
{
"name": "e3",
"isDeprecated": true,
"deprecationReason": null
},
{
"name": "e4",
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "f",
"isDeprecated": false,
@ -388,6 +412,11 @@ pub async fn test_introspection_deprecation() {
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "e4",
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "f",
"isDeprecated": false,