Add visible
attributes on types, fields, and parameters, allowing some content to be hidden based on conditions.
This commit is contained in:
parent
03f6ed4ba2
commit
e29b7a3627
|
@ -2,7 +2,7 @@ use darling::ast::{Data, Fields};
|
||||||
use darling::util::Ignored;
|
use darling::util::Ignored;
|
||||||
use darling::{FromDeriveInput, FromField, FromMeta, FromVariant};
|
use darling::{FromDeriveInput, FromField, FromMeta, FromVariant};
|
||||||
use inflector::Inflector;
|
use inflector::Inflector;
|
||||||
use syn::{Attribute, Generics, Ident, Lit, LitStr, Meta, Type, Visibility};
|
use syn::{Attribute, Generics, Ident, Lit, LitBool, LitStr, Meta, Type, Visibility};
|
||||||
|
|
||||||
#[derive(FromMeta)]
|
#[derive(FromMeta)]
|
||||||
#[darling(default)]
|
#[darling(default)]
|
||||||
|
@ -44,6 +44,24 @@ impl FromMeta for DefaultValue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Visible {
|
||||||
|
None,
|
||||||
|
HiddenAlways,
|
||||||
|
FnName(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromMeta for Visible {
|
||||||
|
fn from_value(value: &Lit) -> darling::Result<Self> {
|
||||||
|
match value {
|
||||||
|
Lit::Bool(LitBool { value: true, .. }) => Ok(Visible::None),
|
||||||
|
Lit::Bool(LitBool { value: false, .. }) => Ok(Visible::HiddenAlways),
|
||||||
|
Lit::Str(str) => Ok(Visible::FnName(str.value())),
|
||||||
|
_ => Err(darling::Error::unexpected_lit_type(value)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(FromField)]
|
#[derive(FromField)]
|
||||||
#[darling(attributes(graphql), forward_attrs(doc))]
|
#[darling(attributes(graphql), forward_attrs(doc))]
|
||||||
pub struct SimpleObjectField {
|
pub struct SimpleObjectField {
|
||||||
|
@ -70,6 +88,8 @@ pub struct SimpleObjectField {
|
||||||
pub requires: Option<String>,
|
pub requires: Option<String>,
|
||||||
#[darling(default)]
|
#[darling(default)]
|
||||||
pub guard: Option<Meta>,
|
pub guard: Option<Meta>,
|
||||||
|
#[darling(default)]
|
||||||
|
pub visible: Option<Visible>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromDeriveInput)]
|
#[derive(FromDeriveInput)]
|
||||||
|
@ -94,6 +114,8 @@ pub struct SimpleObject {
|
||||||
pub cache_control: CacheControl,
|
pub cache_control: CacheControl,
|
||||||
#[darling(default)]
|
#[darling(default)]
|
||||||
pub extends: bool,
|
pub extends: bool,
|
||||||
|
#[darling(default)]
|
||||||
|
pub visible: Option<Visible>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromMeta, Default)]
|
#[derive(FromMeta, Default)]
|
||||||
|
@ -105,6 +127,7 @@ pub struct Argument {
|
||||||
pub default_with: Option<LitStr>,
|
pub default_with: Option<LitStr>,
|
||||||
pub validator: Option<Meta>,
|
pub validator: Option<Meta>,
|
||||||
pub key: bool, // for entity
|
pub key: bool, // for entity
|
||||||
|
pub visible: Option<Visible>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromMeta, Default)]
|
#[derive(FromMeta, Default)]
|
||||||
|
@ -117,6 +140,7 @@ pub struct Object {
|
||||||
pub cache_control: CacheControl,
|
pub cache_control: CacheControl,
|
||||||
pub extends: bool,
|
pub extends: bool,
|
||||||
pub use_type_description: bool,
|
pub use_type_description: bool,
|
||||||
|
pub visible: Option<Visible>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromMeta, Default)]
|
#[derive(FromMeta, Default)]
|
||||||
|
@ -131,6 +155,7 @@ pub struct ObjectField {
|
||||||
pub provides: Option<String>,
|
pub provides: Option<String>,
|
||||||
pub requires: Option<String>,
|
pub requires: Option<String>,
|
||||||
pub guard: Option<Meta>,
|
pub guard: Option<Meta>,
|
||||||
|
pub visible: Option<Visible>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromDeriveInput)]
|
#[derive(FromDeriveInput)]
|
||||||
|
@ -149,6 +174,8 @@ pub struct Enum {
|
||||||
pub rename_items: Option<RenameRule>,
|
pub rename_items: Option<RenameRule>,
|
||||||
#[darling(default)]
|
#[darling(default)]
|
||||||
pub remote: Option<String>,
|
pub remote: Option<String>,
|
||||||
|
#[darling(default)]
|
||||||
|
pub visible: Option<Visible>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromVariant)]
|
#[derive(FromVariant)]
|
||||||
|
@ -162,6 +189,8 @@ pub struct EnumItem {
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
#[darling(default)]
|
#[darling(default)]
|
||||||
pub deprecation: Option<String>,
|
pub deprecation: Option<String>,
|
||||||
|
#[darling(default)]
|
||||||
|
pub visible: Option<Visible>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromDeriveInput)]
|
#[derive(FromDeriveInput)]
|
||||||
|
@ -176,6 +205,8 @@ pub struct Union {
|
||||||
pub internal: bool,
|
pub internal: bool,
|
||||||
#[darling(default)]
|
#[darling(default)]
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
|
#[darling(default)]
|
||||||
|
pub visible: Option<Visible>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromVariant)]
|
#[derive(FromVariant)]
|
||||||
|
@ -206,6 +237,8 @@ pub struct InputObjectField {
|
||||||
pub validator: Option<Meta>,
|
pub validator: Option<Meta>,
|
||||||
#[darling(default)]
|
#[darling(default)]
|
||||||
pub flatten: bool,
|
pub flatten: bool,
|
||||||
|
#[darling(default)]
|
||||||
|
pub visible: Option<Visible>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromDeriveInput)]
|
#[derive(FromDeriveInput)]
|
||||||
|
@ -222,6 +255,8 @@ pub struct InputObject {
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
#[darling(default)]
|
#[darling(default)]
|
||||||
pub rename_fields: Option<RenameRule>,
|
pub rename_fields: Option<RenameRule>,
|
||||||
|
#[darling(default)]
|
||||||
|
pub visible: Option<Visible>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromMeta)]
|
#[derive(FromMeta)]
|
||||||
|
@ -235,6 +270,8 @@ pub struct InterfaceFieldArgument {
|
||||||
pub default: Option<DefaultValue>,
|
pub default: Option<DefaultValue>,
|
||||||
#[darling(default)]
|
#[darling(default)]
|
||||||
pub default_with: Option<LitStr>,
|
pub default_with: Option<LitStr>,
|
||||||
|
#[darling(default)]
|
||||||
|
pub visible: Option<Visible>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromMeta)]
|
#[derive(FromMeta)]
|
||||||
|
@ -256,6 +293,8 @@ pub struct InterfaceField {
|
||||||
pub provides: Option<String>,
|
pub provides: Option<String>,
|
||||||
#[darling(default)]
|
#[darling(default)]
|
||||||
pub requires: Option<String>,
|
pub requires: Option<String>,
|
||||||
|
#[darling(default)]
|
||||||
|
pub visible: Option<Visible>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromVariant)]
|
#[derive(FromVariant)]
|
||||||
|
@ -284,6 +323,8 @@ pub struct Interface {
|
||||||
pub fields: Vec<InterfaceField>,
|
pub fields: Vec<InterfaceField>,
|
||||||
#[darling(default)]
|
#[darling(default)]
|
||||||
pub extends: bool,
|
pub extends: bool,
|
||||||
|
#[darling(default)]
|
||||||
|
pub visible: Option<Visible>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromMeta, Default)]
|
#[derive(FromMeta, Default)]
|
||||||
|
@ -292,6 +333,7 @@ pub struct Scalar {
|
||||||
pub internal: bool,
|
pub internal: bool,
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
pub use_type_description: bool,
|
pub use_type_description: bool,
|
||||||
|
pub visible: Option<Visible>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromMeta, Default)]
|
#[derive(FromMeta, Default)]
|
||||||
|
@ -312,6 +354,7 @@ pub struct SubscriptionFieldArgument {
|
||||||
pub default: Option<DefaultValue>,
|
pub default: Option<DefaultValue>,
|
||||||
pub default_with: Option<LitStr>,
|
pub default_with: Option<LitStr>,
|
||||||
pub validator: Option<Meta>,
|
pub validator: Option<Meta>,
|
||||||
|
pub visible: Option<Visible>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromMeta, Default)]
|
#[derive(FromMeta, Default)]
|
||||||
|
@ -321,6 +364,7 @@ pub struct SubscriptionField {
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
pub deprecation: Option<String>,
|
pub deprecation: Option<String>,
|
||||||
pub guard: Option<Meta>,
|
pub guard: Option<Meta>,
|
||||||
|
pub visible: Option<Visible>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromField)]
|
#[derive(FromField)]
|
||||||
|
@ -345,6 +389,8 @@ pub struct MergedObject {
|
||||||
pub cache_control: CacheControl,
|
pub cache_control: CacheControl,
|
||||||
#[darling(default)]
|
#[darling(default)]
|
||||||
pub extends: bool,
|
pub extends: bool,
|
||||||
|
#[darling(default)]
|
||||||
|
pub visible: Option<Visible>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromField)]
|
#[derive(FromField)]
|
||||||
|
@ -365,6 +411,8 @@ pub struct MergedSubscription {
|
||||||
pub internal: bool,
|
pub internal: bool,
|
||||||
#[darling(default)]
|
#[darling(default)]
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
|
#[darling(default)]
|
||||||
|
pub visible: Option<Visible>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, FromMeta)]
|
#[derive(Debug, Copy, Clone, FromMeta)]
|
||||||
|
|
|
@ -5,7 +5,7 @@ use syn::ext::IdentExt;
|
||||||
use syn::Error;
|
use syn::Error;
|
||||||
|
|
||||||
use crate::args::{self, RenameRuleExt, RenameTarget};
|
use crate::args::{self, RenameRuleExt, RenameTarget};
|
||||||
use crate::utils::{get_crate_name, get_rustdoc, GeneratorResult};
|
use crate::utils::{get_crate_name, get_rustdoc, visible_fn, GeneratorResult};
|
||||||
|
|
||||||
pub fn generate(enum_args: &args::Enum) -> GeneratorResult<TokenStream> {
|
pub fn generate(enum_args: &args::Enum) -> GeneratorResult<TokenStream> {
|
||||||
let crate_name = get_crate_name(enum_args.internal);
|
let crate_name = get_crate_name(enum_args.internal);
|
||||||
|
@ -62,11 +62,14 @@ pub fn generate(enum_args: &args::Enum) -> GeneratorResult<TokenStream> {
|
||||||
value: #ident::#item_ident,
|
value: #ident::#item_ident,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let visible = visible_fn(&variant.visible);
|
||||||
schema_enum_items.push(quote! {
|
schema_enum_items.push(quote! {
|
||||||
enum_items.insert(#gql_item_name, #crate_name::registry::MetaEnumValue {
|
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,
|
||||||
|
visible: #visible,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -119,6 +122,7 @@ pub fn generate(enum_args: &args::Enum) -> GeneratorResult<TokenStream> {
|
||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let visible = visible_fn(&enum_args.visible);
|
||||||
let expanded = quote! {
|
let expanded = quote! {
|
||||||
#[allow(clippy::all, clippy::pedantic)]
|
#[allow(clippy::all, clippy::pedantic)]
|
||||||
impl #crate_name::resolver_utils::EnumType for #ident {
|
impl #crate_name::resolver_utils::EnumType for #ident {
|
||||||
|
@ -143,6 +147,7 @@ pub fn generate(enum_args: &args::Enum) -> GeneratorResult<TokenStream> {
|
||||||
#(#schema_enum_items)*
|
#(#schema_enum_items)*
|
||||||
enum_items
|
enum_items
|
||||||
},
|
},
|
||||||
|
visible: #visible,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use syn::Error;
|
||||||
|
|
||||||
use crate::args::{self, RenameRuleExt, RenameTarget};
|
use crate::args::{self, RenameRuleExt, RenameTarget};
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
generate_default, generate_validator, get_crate_name, get_rustdoc, GeneratorResult,
|
generate_default, generate_validator, get_crate_name, get_rustdoc, visible_fn, GeneratorResult,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn generate(object_args: &args::InputObject) -> GeneratorResult<TokenStream> {
|
pub fn generate(object_args: &args::InputObject) -> GeneratorResult<TokenStream> {
|
||||||
|
@ -140,6 +140,7 @@ pub fn generate(object_args: &args::InputObject) -> GeneratorResult<TokenStream>
|
||||||
});
|
});
|
||||||
|
|
||||||
fields.push(ident);
|
fields.push(ident);
|
||||||
|
let visible = visible_fn(&field.visible);
|
||||||
schema_fields.push(quote! {
|
schema_fields.push(quote! {
|
||||||
fields.insert(::std::borrow::ToOwned::to_owned(#name), #crate_name::registry::MetaInputValue {
|
fields.insert(::std::borrow::ToOwned::to_owned(#name), #crate_name::registry::MetaInputValue {
|
||||||
name: #name,
|
name: #name,
|
||||||
|
@ -147,6 +148,7 @@ pub fn generate(object_args: &args::InputObject) -> GeneratorResult<TokenStream>
|
||||||
ty: <#ty as #crate_name::Type>::create_type_info(registry),
|
ty: <#ty as #crate_name::Type>::create_type_info(registry),
|
||||||
default_value: #schema_default,
|
default_value: #schema_default,
|
||||||
validator: #validator,
|
validator: #validator,
|
||||||
|
visible: #visible,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -159,6 +161,7 @@ pub fn generate(object_args: &args::InputObject) -> GeneratorResult<TokenStream>
|
||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let visible = visible_fn(&object_args.visible);
|
||||||
let expanded = quote! {
|
let expanded = quote! {
|
||||||
#[allow(clippy::all, clippy::pedantic)]
|
#[allow(clippy::all, clippy::pedantic)]
|
||||||
impl #crate_name::Type for #ident {
|
impl #crate_name::Type for #ident {
|
||||||
|
@ -174,7 +177,8 @@ pub fn generate(object_args: &args::InputObject) -> GeneratorResult<TokenStream>
|
||||||
let mut fields = #crate_name::indexmap::IndexMap::new();
|
let mut fields = #crate_name::indexmap::IndexMap::new();
|
||||||
#(#schema_fields)*
|
#(#schema_fields)*
|
||||||
fields
|
fields
|
||||||
}
|
},
|
||||||
|
visible: #visible,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use syn::{visit_mut, Error, Lifetime, Type};
|
||||||
|
|
||||||
use crate::args::{self, InterfaceField, InterfaceFieldArgument, RenameRuleExt, RenameTarget};
|
use crate::args::{self, InterfaceField, InterfaceFieldArgument, RenameRuleExt, RenameTarget};
|
||||||
use crate::output_type::OutputType;
|
use crate::output_type::OutputType;
|
||||||
use crate::utils::{generate_default, get_crate_name, get_rustdoc, GeneratorResult};
|
use crate::utils::{generate_default, get_crate_name, get_rustdoc, visible_fn, GeneratorResult};
|
||||||
|
|
||||||
pub fn generate(interface_args: &args::Interface) -> GeneratorResult<TokenStream> {
|
pub fn generate(interface_args: &args::Interface) -> GeneratorResult<TokenStream> {
|
||||||
let crate_name = get_crate_name(interface_args.internal);
|
let crate_name = get_crate_name(interface_args.internal);
|
||||||
|
@ -139,6 +139,7 @@ pub fn generate(interface_args: &args::Interface) -> GeneratorResult<TokenStream
|
||||||
external,
|
external,
|
||||||
provides,
|
provides,
|
||||||
requires,
|
requires,
|
||||||
|
visible,
|
||||||
} in &interface_args.fields
|
} in &interface_args.fields
|
||||||
{
|
{
|
||||||
let (name, method_name) = if let Some(method) = method {
|
let (name, method_name) = if let Some(method) = method {
|
||||||
|
@ -179,6 +180,7 @@ pub fn generate(interface_args: &args::Interface) -> GeneratorResult<TokenStream
|
||||||
ty,
|
ty,
|
||||||
default,
|
default,
|
||||||
default_with,
|
default_with,
|
||||||
|
visible,
|
||||||
} in args
|
} in args
|
||||||
{
|
{
|
||||||
let ident = Ident::new(name, Span::call_site());
|
let ident = Ident::new(name, Span::call_site());
|
||||||
|
@ -215,6 +217,7 @@ pub fn generate(interface_args: &args::Interface) -> GeneratorResult<TokenStream
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| quote! {::std::option::Option::None});
|
.unwrap_or_else(|| quote! {::std::option::Option::None});
|
||||||
|
let visible = visible_fn(&visible);
|
||||||
schema_args.push(quote! {
|
schema_args.push(quote! {
|
||||||
args.insert(#name, #crate_name::registry::MetaInputValue {
|
args.insert(#name, #crate_name::registry::MetaInputValue {
|
||||||
name: #name,
|
name: #name,
|
||||||
|
@ -222,6 +225,7 @@ pub fn generate(interface_args: &args::Interface) -> GeneratorResult<TokenStream
|
||||||
ty: <#ty as #crate_name::Type>::create_type_info(registry),
|
ty: <#ty as #crate_name::Type>::create_type_info(registry),
|
||||||
default_value: #schema_default,
|
default_value: #schema_default,
|
||||||
validator: ::std::option::Option::None,
|
validator: ::std::option::Option::None,
|
||||||
|
visible: #visible,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -257,6 +261,7 @@ pub fn generate(interface_args: &args::Interface) -> GeneratorResult<TokenStream
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let visible = visible_fn(&visible);
|
||||||
schema_fields.push(quote! {
|
schema_fields.push(quote! {
|
||||||
fields.insert(::std::string::ToString::to_string(#name), #crate_name::registry::MetaField {
|
fields.insert(::std::string::ToString::to_string(#name), #crate_name::registry::MetaField {
|
||||||
name: ::std::string::ToString::to_string(#name),
|
name: ::std::string::ToString::to_string(#name),
|
||||||
|
@ -272,6 +277,7 @@ pub fn generate(interface_args: &args::Interface) -> GeneratorResult<TokenStream
|
||||||
external: #external,
|
external: #external,
|
||||||
provides: #provides,
|
provides: #provides,
|
||||||
requires: #requires,
|
requires: #requires,
|
||||||
|
visible: #visible,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -300,6 +306,7 @@ pub fn generate(interface_args: &args::Interface) -> GeneratorResult<TokenStream
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let visible = visible_fn(&interface_args.visible);
|
||||||
let expanded = quote! {
|
let expanded = quote! {
|
||||||
#(#type_into_impls)*
|
#(#type_into_impls)*
|
||||||
|
|
||||||
|
@ -337,6 +344,7 @@ pub fn generate(interface_args: &args::Interface) -> GeneratorResult<TokenStream
|
||||||
},
|
},
|
||||||
extends: #extends,
|
extends: #extends,
|
||||||
keys: ::std::option::Option::None,
|
keys: ::std::option::Option::None,
|
||||||
|
visible: #visible,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use quote::quote;
|
||||||
use syn::{Error, LitInt};
|
use syn::{Error, LitInt};
|
||||||
|
|
||||||
use crate::args::{self, RenameTarget};
|
use crate::args::{self, RenameTarget};
|
||||||
use crate::utils::{get_crate_name, get_rustdoc, GeneratorResult};
|
use crate::utils::{get_crate_name, get_rustdoc, visible_fn, GeneratorResult};
|
||||||
|
|
||||||
pub fn generate(object_args: &args::MergedObject) -> GeneratorResult<TokenStream> {
|
pub fn generate(object_args: &args::MergedObject) -> GeneratorResult<TokenStream> {
|
||||||
let crate_name = get_crate_name(object_args.internal);
|
let crate_name = get_crate_name(object_args.internal);
|
||||||
|
@ -55,6 +55,7 @@ pub fn generate(object_args: &args::MergedObject) -> GeneratorResult<TokenStream
|
||||||
obj
|
obj
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let visible = visible_fn(&object_args.visible);
|
||||||
let expanded = quote! {
|
let expanded = quote! {
|
||||||
#[allow(clippy::all, clippy::pedantic)]
|
#[allow(clippy::all, clippy::pedantic)]
|
||||||
impl #generics #crate_name::Type for #ident #generics #where_clause {
|
impl #generics #crate_name::Type for #ident #generics #where_clause {
|
||||||
|
@ -83,6 +84,7 @@ pub fn generate(object_args: &args::MergedObject) -> GeneratorResult<TokenStream
|
||||||
cache_control,
|
cache_control,
|
||||||
extends: #extends,
|
extends: #extends,
|
||||||
keys: ::std::option::Option::None,
|
keys: ::std::option::Option::None,
|
||||||
|
visible: #visible,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use quote::quote;
|
||||||
use syn::{Error, LitInt};
|
use syn::{Error, LitInt};
|
||||||
|
|
||||||
use crate::args::{self, RenameTarget};
|
use crate::args::{self, RenameTarget};
|
||||||
use crate::utils::{get_crate_name, get_rustdoc, GeneratorResult};
|
use crate::utils::{get_crate_name, get_rustdoc, visible_fn, GeneratorResult};
|
||||||
|
|
||||||
pub fn generate(object_args: &args::MergedSubscription) -> GeneratorResult<TokenStream> {
|
pub fn generate(object_args: &args::MergedSubscription) -> GeneratorResult<TokenStream> {
|
||||||
let crate_name = get_crate_name(object_args.internal);
|
let crate_name = get_crate_name(object_args.internal);
|
||||||
|
@ -44,6 +44,7 @@ pub fn generate(object_args: &args::MergedSubscription) -> GeneratorResult<Token
|
||||||
|obj, ty| quote!(#crate_name::MergedObject::<#ty, #obj>),
|
|obj, ty| quote!(#crate_name::MergedObject::<#ty, #obj>),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let visible = visible_fn(&object_args.visible);
|
||||||
let expanded = quote! {
|
let expanded = quote! {
|
||||||
#[allow(clippy::all, clippy::pedantic)]
|
#[allow(clippy::all, clippy::pedantic)]
|
||||||
impl #crate_name::Type for #ident {
|
impl #crate_name::Type for #ident {
|
||||||
|
@ -69,6 +70,7 @@ pub fn generate(object_args: &args::MergedSubscription) -> GeneratorResult<Token
|
||||||
cache_control: ::std::default::Default::default(),
|
cache_control: ::std::default::Default::default(),
|
||||||
extends: false,
|
extends: false,
|
||||||
keys: ::std::option::Option::None,
|
keys: ::std::option::Option::None,
|
||||||
|
visible: #visible,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use crate::output_type::OutputType;
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
generate_default, generate_guards, generate_validator, get_cfg_attrs, get_crate_name,
|
generate_default, generate_guards, generate_validator, get_cfg_attrs, get_crate_name,
|
||||||
get_param_getter_ident, get_rustdoc, get_type_path_and_name, parse_graphql_attrs,
|
get_param_getter_ident, get_rustdoc, get_type_path_and_name, parse_graphql_attrs,
|
||||||
remove_graphql_attrs, GeneratorResult,
|
remove_graphql_attrs, visible_fn, GeneratorResult,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn generate(
|
pub fn generate(
|
||||||
|
@ -319,6 +319,7 @@ pub fn generate(
|
||||||
default,
|
default,
|
||||||
default_with,
|
default_with,
|
||||||
validator,
|
validator,
|
||||||
|
visible,
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
) in args
|
) in args
|
||||||
|
@ -352,6 +353,7 @@ pub fn generate(
|
||||||
None => quote!(::std::option::Option::None),
|
None => quote!(::std::option::Option::None),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let visible = visible_fn(&visible);
|
||||||
schema_args.push(quote! {
|
schema_args.push(quote! {
|
||||||
args.insert(#name, #crate_name::registry::MetaInputValue {
|
args.insert(#name, #crate_name::registry::MetaInputValue {
|
||||||
name: #name,
|
name: #name,
|
||||||
|
@ -359,6 +361,7 @@ pub fn generate(
|
||||||
ty: <#ty as #crate_name::Type>::create_type_info(registry),
|
ty: <#ty as #crate_name::Type>::create_type_info(registry),
|
||||||
default_value: #schema_default,
|
default_value: #schema_default,
|
||||||
validator: #validator,
|
validator: #validator,
|
||||||
|
visible: #visible,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -381,6 +384,7 @@ pub fn generate(
|
||||||
}
|
}
|
||||||
|
|
||||||
let schema_ty = ty.value_type();
|
let schema_ty = ty.value_type();
|
||||||
|
let visible = visible_fn(&method_args.visible);
|
||||||
|
|
||||||
schema_fields.push(quote! {
|
schema_fields.push(quote! {
|
||||||
#(#cfg_attrs)*
|
#(#cfg_attrs)*
|
||||||
|
@ -398,6 +402,7 @@ pub fn generate(
|
||||||
external: #external,
|
external: #external,
|
||||||
provides: #provides,
|
provides: #provides,
|
||||||
requires: #requires,
|
requires: #requires,
|
||||||
|
visible: #visible,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -473,6 +478,7 @@ pub fn generate(
|
||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let visible = visible_fn(&object_args.visible);
|
||||||
let expanded = quote! {
|
let expanded = quote! {
|
||||||
#item_impl
|
#item_impl
|
||||||
|
|
||||||
|
@ -494,6 +500,7 @@ pub fn generate(
|
||||||
cache_control: #cache_control,
|
cache_control: #cache_control,
|
||||||
extends: #extends,
|
extends: #extends,
|
||||||
keys: ::std::option::Option::None,
|
keys: ::std::option::Option::None,
|
||||||
|
visible: #visible,
|
||||||
});
|
});
|
||||||
#(#create_entity_types)*
|
#(#create_entity_types)*
|
||||||
#(#add_keys)*
|
#(#add_keys)*
|
||||||
|
|
|
@ -3,7 +3,9 @@ use quote::quote;
|
||||||
use syn::ItemImpl;
|
use syn::ItemImpl;
|
||||||
|
|
||||||
use crate::args::{self, RenameTarget};
|
use crate::args::{self, RenameTarget};
|
||||||
use crate::utils::{get_crate_name, get_rustdoc, get_type_path_and_name, GeneratorResult};
|
use crate::utils::{
|
||||||
|
get_crate_name, get_rustdoc, get_type_path_and_name, visible_fn, GeneratorResult,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn generate(
|
pub fn generate(
|
||||||
scalar_args: &args::Scalar,
|
scalar_args: &args::Scalar,
|
||||||
|
@ -27,6 +29,7 @@ pub fn generate(
|
||||||
let self_ty = &item_impl.self_ty;
|
let self_ty = &item_impl.self_ty;
|
||||||
let generic = &item_impl.generics;
|
let generic = &item_impl.generics;
|
||||||
let where_clause = &item_impl.generics.where_clause;
|
let where_clause = &item_impl.generics.where_clause;
|
||||||
|
let visible = visible_fn(&scalar_args.visible);
|
||||||
let expanded = quote! {
|
let expanded = quote! {
|
||||||
#item_impl
|
#item_impl
|
||||||
|
|
||||||
|
@ -41,6 +44,7 @@ pub fn generate(
|
||||||
name: ::std::borrow::ToOwned::to_owned(#gql_typename),
|
name: ::std::borrow::ToOwned::to_owned(#gql_typename),
|
||||||
description: #desc,
|
description: #desc,
|
||||||
is_valid: |value| <#self_ty as #crate_name::ScalarType>::is_valid(value),
|
is_valid: |value| <#self_ty as #crate_name::ScalarType>::is_valid(value),
|
||||||
|
visible: #visible,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use syn::ext::IdentExt;
|
||||||
use syn::Error;
|
use syn::Error;
|
||||||
|
|
||||||
use crate::args::{self, RenameRuleExt, RenameTarget};
|
use crate::args::{self, RenameRuleExt, RenameTarget};
|
||||||
use crate::utils::{generate_guards, get_crate_name, get_rustdoc, GeneratorResult};
|
use crate::utils::{generate_guards, get_crate_name, get_rustdoc, visible_fn, GeneratorResult};
|
||||||
|
|
||||||
pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult<TokenStream> {
|
pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult<TokenStream> {
|
||||||
let crate_name = get_crate_name(object_args.internal);
|
let crate_name = get_crate_name(object_args.internal);
|
||||||
|
@ -81,6 +81,8 @@ pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult<TokenStream
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let visible = visible_fn(&field.visible);
|
||||||
|
|
||||||
schema_fields.push(quote! {
|
schema_fields.push(quote! {
|
||||||
fields.insert(::std::borrow::ToOwned::to_owned(#field_name), #crate_name::registry::MetaField {
|
fields.insert(::std::borrow::ToOwned::to_owned(#field_name), #crate_name::registry::MetaField {
|
||||||
name: ::std::borrow::ToOwned::to_owned(#field_name),
|
name: ::std::borrow::ToOwned::to_owned(#field_name),
|
||||||
|
@ -92,6 +94,7 @@ pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult<TokenStream
|
||||||
external: #external,
|
external: #external,
|
||||||
provides: #provides,
|
provides: #provides,
|
||||||
requires: #requires,
|
requires: #requires,
|
||||||
|
visible: #visible,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -148,6 +151,8 @@ pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult<TokenStream
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let visible = visible_fn(&object_args.visible);
|
||||||
|
|
||||||
let expanded = quote! {
|
let expanded = quote! {
|
||||||
#[allow(clippy::all, clippy::pedantic)]
|
#[allow(clippy::all, clippy::pedantic)]
|
||||||
impl #generics #ident #generics #where_clause {
|
impl #generics #ident #generics #where_clause {
|
||||||
|
@ -172,6 +177,7 @@ pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult<TokenStream
|
||||||
cache_control: #cache_control,
|
cache_control: #cache_control,
|
||||||
extends: #extends,
|
extends: #extends,
|
||||||
keys: ::std::option::Option::None,
|
keys: ::std::option::Option::None,
|
||||||
|
visible: #visible,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crate::output_type::OutputType;
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
generate_default, generate_guards, generate_validator, get_cfg_attrs, get_crate_name,
|
generate_default, generate_guards, generate_validator, get_cfg_attrs, get_crate_name,
|
||||||
get_param_getter_ident, get_rustdoc, get_type_path_and_name, parse_graphql_attrs,
|
get_param_getter_ident, get_rustdoc, get_type_path_and_name, parse_graphql_attrs,
|
||||||
remove_graphql_attrs, GeneratorResult,
|
remove_graphql_attrs, visible_fn, GeneratorResult,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn generate(
|
pub fn generate(
|
||||||
|
@ -150,6 +150,7 @@ pub fn generate(
|
||||||
default,
|
default,
|
||||||
default_with,
|
default_with,
|
||||||
validator,
|
validator,
|
||||||
|
visible: arg_visible,
|
||||||
},
|
},
|
||||||
) in args
|
) in args
|
||||||
{
|
{
|
||||||
|
@ -183,6 +184,7 @@ pub fn generate(
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| quote! {::std::option::Option::None});
|
.unwrap_or_else(|| quote! {::std::option::Option::None});
|
||||||
|
|
||||||
|
let visible = visible_fn(&arg_visible);
|
||||||
schema_args.push(quote! {
|
schema_args.push(quote! {
|
||||||
args.insert(#name, #crate_name::registry::MetaInputValue {
|
args.insert(#name, #crate_name::registry::MetaInputValue {
|
||||||
name: #name,
|
name: #name,
|
||||||
|
@ -190,6 +192,7 @@ pub fn generate(
|
||||||
ty: <#ty as #crate_name::Type>::create_type_info(registry),
|
ty: <#ty as #crate_name::Type>::create_type_info(registry),
|
||||||
default_value: #schema_default,
|
default_value: #schema_default,
|
||||||
validator: #validator,
|
validator: #validator,
|
||||||
|
visible: #visible,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -235,6 +238,7 @@ pub fn generate(
|
||||||
.expect("invalid result type");
|
.expect("invalid result type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let visible = visible_fn(&field.visible);
|
||||||
schema_fields.push(quote! {
|
schema_fields.push(quote! {
|
||||||
#(#cfg_attrs)*
|
#(#cfg_attrs)*
|
||||||
fields.insert(::std::borrow::ToOwned::to_owned(#field_name), #crate_name::registry::MetaField {
|
fields.insert(::std::borrow::ToOwned::to_owned(#field_name), #crate_name::registry::MetaField {
|
||||||
|
@ -251,6 +255,7 @@ pub fn generate(
|
||||||
external: false,
|
external: false,
|
||||||
requires: ::std::option::Option::None,
|
requires: ::std::option::Option::None,
|
||||||
provides: ::std::option::Option::None,
|
provides: ::std::option::Option::None,
|
||||||
|
visible: #visible,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -388,6 +393,7 @@ pub fn generate(
|
||||||
cache_control: ::std::default::Default::default(),
|
cache_control: ::std::default::Default::default(),
|
||||||
extends: false,
|
extends: false,
|
||||||
keys: ::std::option::Option::None,
|
keys: ::std::option::Option::None,
|
||||||
|
visible: ::std::option::Option::None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use syn::visit_mut::VisitMut;
|
||||||
use syn::{visit_mut, Error, Lifetime, Type};
|
use syn::{visit_mut, Error, Lifetime, Type};
|
||||||
|
|
||||||
use crate::args::{self, RenameTarget};
|
use crate::args::{self, RenameTarget};
|
||||||
use crate::utils::{get_crate_name, get_rustdoc, GeneratorResult};
|
use crate::utils::{get_crate_name, get_rustdoc, visible_fn, GeneratorResult};
|
||||||
|
|
||||||
pub fn generate(union_args: &args::Union) -> GeneratorResult<TokenStream> {
|
pub fn generate(union_args: &args::Union) -> GeneratorResult<TokenStream> {
|
||||||
let crate_name = get_crate_name(union_args.internal);
|
let crate_name = get_crate_name(union_args.internal);
|
||||||
|
@ -148,6 +148,7 @@ pub fn generate(union_args: &args::Union) -> GeneratorResult<TokenStream> {
|
||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let visible = visible_fn(&union_args.visible);
|
||||||
let expanded = quote! {
|
let expanded = quote! {
|
||||||
#(#type_into_impls)*
|
#(#type_into_impls)*
|
||||||
|
|
||||||
|
@ -174,7 +175,8 @@ pub fn generate(union_args: &args::Union) -> GeneratorResult<TokenStream> {
|
||||||
let mut possible_types = #crate_name::indexmap::IndexSet::new();
|
let mut possible_types = #crate_name::indexmap::IndexSet::new();
|
||||||
#(#possible_types)*
|
#(#possible_types)*
|
||||||
possible_types
|
possible_types
|
||||||
}
|
},
|
||||||
|
visible: #visible,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ use syn::{
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::args;
|
use crate::args;
|
||||||
|
use crate::args::Visible;
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum GeneratorError {
|
pub enum GeneratorError {
|
||||||
|
@ -389,3 +390,14 @@ pub fn get_type_path_and_name(ty: &Type) -> GeneratorResult<(&TypePath, String)>
|
||||||
_ => Err(Error::new_spanned(ty, "Invalid type").into()),
|
_ => Err(Error::new_spanned(ty, "Invalid type").into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn visible_fn(visible: &Option<Visible>) -> TokenStream {
|
||||||
|
match visible {
|
||||||
|
None | Some(Visible::None) => quote! { ::std::option::Option::None },
|
||||||
|
Some(Visible::HiddenAlways) => quote! { ::std::option::Option::Some(|_| false) },
|
||||||
|
Some(Visible::FnName(name)) => {
|
||||||
|
let ident = Ident::new(name, Span::call_site());
|
||||||
|
quote! { ::std::option::Option::Some(#ident) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
32
src/lib.rs
32
src/lib.rs
|
@ -244,6 +244,8 @@ pub type FieldResult<T> = Result<T>;
|
||||||
/// | cache_control | Object cache control | [`CacheControl`](struct.CacheControl.html) | Y |
|
/// | cache_control | Object cache control | [`CacheControl`](struct.CacheControl.html) | Y |
|
||||||
/// | extends | Add fields to an entity that's defined in another service | bool | Y |
|
/// | extends | Add fields to an entity that's defined in another service | bool | Y |
|
||||||
/// | use_type_description | Specifies that the description of the type is on the type declaration. [`Description`]()(derive.Description.html) | bool | Y |
|
/// | use_type_description | Specifies that the description of the type is on the type declaration. [`Description`]()(derive.Description.html) | bool | Y |
|
||||||
|
/// | visible | If `false`, it will not be displayed in introspection. | bool | Y |
|
||||||
|
/// | visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||||
///
|
///
|
||||||
/// # Field parameters
|
/// # Field parameters
|
||||||
///
|
///
|
||||||
|
@ -258,6 +260,8 @@ pub type FieldResult<T> = Result<T>;
|
||||||
/// | provides | Annotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the gateway. | string | Y |
|
/// | provides | Annotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the gateway. | string | Y |
|
||||||
/// | requires | Annotate the required input fieldset from a base type for a resolver. It is used to develop a query plan where the required fields may not be needed by the client, but the service may need additional information from other services. | string | Y |
|
/// | requires | Annotate the required input fieldset from a base type for a resolver. It is used to develop a query plan where the required fields may not be needed by the client, but the service may need additional information from other services. | string | Y |
|
||||||
/// | guard | Field of guard | [`Guard`](guard/trait.Guard.html) | Y |
|
/// | guard | Field of guard | [`Guard`](guard/trait.Guard.html) | Y |
|
||||||
|
/// | visible | If `false`, it will not be displayed in introspection. | bool | Y |
|
||||||
|
/// | visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||||
///
|
///
|
||||||
/// # Field argument parameters
|
/// # Field argument parameters
|
||||||
///
|
///
|
||||||
|
@ -270,6 +274,8 @@ pub type FieldResult<T> = Result<T>;
|
||||||
/// | default_with | Expression to generate default value | code string | Y |
|
/// | default_with | Expression to generate default value | code string | Y |
|
||||||
/// | validator | Input value validator | [`InputValueValidator`](validators/trait.InputValueValidator.html) | Y |
|
/// | validator | Input value validator | [`InputValueValidator`](validators/trait.InputValueValidator.html) | Y |
|
||||||
/// | key | Is entity key | bool | Y |
|
/// | key | Is entity key | bool | Y |
|
||||||
|
/// | visible | If `false`, it will not be displayed in introspection. | bool | Y |
|
||||||
|
/// | visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||||
///
|
///
|
||||||
/// # Valid field return types
|
/// # Valid field return types
|
||||||
///
|
///
|
||||||
|
@ -360,6 +366,8 @@ pub use async_graphql_derive::Object;
|
||||||
/// | rename_fields | Rename all the fields according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE".| string | Y |
|
/// | rename_fields | Rename all the fields according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE".| string | Y |
|
||||||
/// | cache_control | Object cache control | [`CacheControl`](struct.CacheControl.html) | Y |
|
/// | cache_control | Object cache control | [`CacheControl`](struct.CacheControl.html) | Y |
|
||||||
/// | extends | Add fields to an entity that's defined in another service | bool | Y |
|
/// | extends | Add fields to an entity that's defined in another service | bool | Y |
|
||||||
|
/// | visible | If `false`, it will not be displayed in introspection. | bool | Y |
|
||||||
|
/// | visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||||
///
|
///
|
||||||
/// # Field parameters
|
/// # Field parameters
|
||||||
///
|
///
|
||||||
|
@ -374,6 +382,8 @@ pub use async_graphql_derive::Object;
|
||||||
/// | provides | Annotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the gateway. | string | Y |
|
/// | provides | Annotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the gateway. | string | Y |
|
||||||
/// | requires | Annotate the required input fieldset from a base type for a resolver. It is used to develop a query plan where the required fields may not be needed by the client, but the service may need additional information from other services. | string | Y |
|
/// | requires | Annotate the required input fieldset from a base type for a resolver. It is used to develop a query plan where the required fields may not be needed by the client, but the service may need additional information from other services. | string | Y |
|
||||||
/// | guard | Field of guard | [`Guard`](guard/trait.Guard.html) | Y |
|
/// | guard | Field of guard | [`Guard`](guard/trait.Guard.html) | Y |
|
||||||
|
/// | visible | If `false`, it will not be displayed in introspection. | bool | Y |
|
||||||
|
/// | visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -406,6 +416,8 @@ pub use async_graphql_derive::SimpleObject;
|
||||||
/// | name | Enum name | string | Y |
|
/// | name | Enum name | string | Y |
|
||||||
/// | rename_items | Rename all the fields according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE".| string | Y |
|
/// | rename_items | Rename all the fields according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE".| string | Y |
|
||||||
/// | remote | Derive a remote enum | string | Y |
|
/// | remote | Derive a remote enum | string | Y |
|
||||||
|
/// | visible | If `false`, it will not be displayed in introspection. | bool | Y |
|
||||||
|
/// | visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||||
///
|
///
|
||||||
/// # Item parameters
|
/// # Item parameters
|
||||||
///
|
///
|
||||||
|
@ -413,6 +425,8 @@ pub use async_graphql_derive::SimpleObject;
|
||||||
/// |-------------|---------------------------|----------|----------|
|
/// |-------------|---------------------------|----------|----------|
|
||||||
/// | name | Item name | string | Y |
|
/// | name | Item name | string | Y |
|
||||||
/// | deprecation | Item deprecation reason | string | Y |
|
/// | deprecation | Item deprecation reason | string | Y |
|
||||||
|
/// | visible | If `false`, it will not be displayed in introspection. | bool | Y |
|
||||||
|
/// | visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -461,6 +475,8 @@ pub use async_graphql_derive::Enum;
|
||||||
/// |---------------|---------------------------|----------|----------|
|
/// |---------------|---------------------------|----------|----------|
|
||||||
/// | name | Object name | string | Y |
|
/// | name | Object name | string | Y |
|
||||||
/// | rename_fields | Rename all the fields according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE".| string | Y |
|
/// | rename_fields | Rename all the fields according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE".| string | Y |
|
||||||
|
/// | visible | If `false`, it will not be displayed in introspection. | bool | Y |
|
||||||
|
/// | visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||||
///
|
///
|
||||||
/// # Field parameters
|
/// # Field parameters
|
||||||
///
|
///
|
||||||
|
@ -472,6 +488,8 @@ pub use async_graphql_derive::Enum;
|
||||||
/// | default_with | Expression to generate default value | code string | Y |
|
/// | default_with | Expression to generate default value | code string | Y |
|
||||||
/// | validator | Input value validator | [`InputValueValidator`](validators/trait.InputValueValidator.html) | Y |
|
/// | validator | Input value validator | [`InputValueValidator`](validators/trait.InputValueValidator.html) | Y |
|
||||||
/// | flatten | Similar to serde (flatten) | boolean | Y |
|
/// | flatten | Similar to serde (flatten) | boolean | Y |
|
||||||
|
/// | visible | If `false`, it will not be displayed in introspection. | bool | Y |
|
||||||
|
/// | visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -520,6 +538,8 @@ pub use async_graphql_derive::InputObject;
|
||||||
/// | rename_args | Rename all the arguments according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE".| string | Y |
|
/// | rename_args | Rename all the arguments according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE".| string | Y |
|
||||||
/// | field | Fields of this Interface | [InterfaceField] | N |
|
/// | field | Fields of this Interface | [InterfaceField] | N |
|
||||||
/// | extends | Add fields to an entity that's defined in another service | bool | Y |
|
/// | extends | Add fields to an entity that's defined in another service | bool | Y |
|
||||||
|
/// | visible | If `false`, it will not be displayed in introspection. | bool | Y |
|
||||||
|
/// | visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||||
///
|
///
|
||||||
/// # Field parameters
|
/// # Field parameters
|
||||||
///
|
///
|
||||||
|
@ -534,6 +554,8 @@ pub use async_graphql_derive::InputObject;
|
||||||
/// | 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 |
|
/// | 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 |
|
||||||
/// | provides | Annotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the gateway. | string | Y |
|
/// | provides | Annotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the gateway. | string | Y |
|
||||||
/// | requires | Annotate the required input fieldset from a base type for a resolver. It is used to develop a query plan where the required fields may not be needed by the client, but the service may need additional information from other services. | string | Y |
|
/// | requires | Annotate the required input fieldset from a base type for a resolver. It is used to develop a query plan where the required fields may not be needed by the client, but the service may need additional information from other services. | string | Y |
|
||||||
|
/// | visible | If `false`, it will not be displayed in introspection. | bool | Y |
|
||||||
|
/// | visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||||
///
|
///
|
||||||
/// # Field argument parameters
|
/// # Field argument parameters
|
||||||
///
|
///
|
||||||
|
@ -545,6 +567,8 @@ pub use async_graphql_derive::InputObject;
|
||||||
/// | default | Use `Default::default` for default value | none | Y |
|
/// | default | Use `Default::default` for default value | none | Y |
|
||||||
/// | default | Argument default value | literal | Y |
|
/// | default | Argument default value | literal | Y |
|
||||||
/// | default_with | Expression to generate default value | code string | Y |
|
/// | default_with | Expression to generate default value | code string | Y |
|
||||||
|
/// | visible | If `false`, it will not be displayed in introspection. | bool | Y |
|
||||||
|
/// | visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||||
///
|
///
|
||||||
/// # Define an interface
|
/// # Define an interface
|
||||||
///
|
///
|
||||||
|
@ -650,6 +674,8 @@ pub use async_graphql_derive::Interface;
|
||||||
/// | Attribute | description | Type | Optional |
|
/// | Attribute | description | Type | Optional |
|
||||||
/// |-------------|---------------------------|----------|----------|
|
/// |-------------|---------------------------|----------|----------|
|
||||||
/// | name | Object name | string | Y |
|
/// | name | Object name | string | Y |
|
||||||
|
/// | visible | If `false`, it will not be displayed in introspection. | bool | Y |
|
||||||
|
/// | visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||||
///
|
///
|
||||||
/// # Item parameters
|
/// # Item parameters
|
||||||
///
|
///
|
||||||
|
@ -737,6 +763,8 @@ pub use async_graphql_derive::Union;
|
||||||
/// | name | Field name | string | Y |
|
/// | name | Field name | string | Y |
|
||||||
/// | deprecation | Field deprecation reason | string | Y |
|
/// | deprecation | Field deprecation reason | string | Y |
|
||||||
/// | guard | Field of guard | [`Guard`](guard/trait.Guard.html) | Y |
|
/// | guard | Field of guard | [`Guard`](guard/trait.Guard.html) | Y |
|
||||||
|
/// | visible | If `false`, it will not be displayed in introspection. | bool | Y |
|
||||||
|
/// | visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||||
///
|
///
|
||||||
/// # Field argument parameters
|
/// # Field argument parameters
|
||||||
///
|
///
|
||||||
|
@ -748,6 +776,8 @@ pub use async_graphql_derive::Union;
|
||||||
/// | default | Argument default value | literal | Y |
|
/// | default | Argument default value | literal | Y |
|
||||||
/// | default_with | Expression to generate default value | code string | Y |
|
/// | default_with | Expression to generate default value | code string | Y |
|
||||||
/// | validator | Input value validator | [`InputValueValidator`](validators/trait.InputValueValidator.html) | Y |
|
/// | validator | Input value validator | [`InputValueValidator`](validators/trait.InputValueValidator.html) | Y |
|
||||||
|
/// | visible | If `false`, it will not be displayed in introspection. | bool | Y |
|
||||||
|
/// | visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -789,6 +819,8 @@ pub use async_graphql_derive::Scalar;
|
||||||
/// | cache_control | Object cache control | [`CacheControl`](struct.CacheControl.html) | Y |
|
/// | cache_control | Object cache control | [`CacheControl`](struct.CacheControl.html) | Y |
|
||||||
/// | extends | Add fields to an entity that's defined in another service | bool | Y |
|
/// | extends | Add fields to an entity that's defined in another service | bool | Y |
|
||||||
/// | use_type_description | Specifies that the description of the type is on the type declaration. [`Description`]()(derive.Description.html) | bool | Y |
|
/// | use_type_description | Specifies that the description of the type is on the type declaration. [`Description`]()(derive.Description.html) | bool | Y |
|
||||||
|
/// | visible | If `false`, it will not be displayed in introspection. | bool | Y |
|
||||||
|
/// | visible | Call the specified function. If the return value is `false`, it will not be displayed in introspection. | string | Y |
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::model::{__InputValue, __Type};
|
use crate::model::{__InputValue, __Type};
|
||||||
use crate::{registry, Object};
|
use crate::{registry, Context, Object};
|
||||||
|
|
||||||
pub struct __Field<'a> {
|
pub struct __Field<'a> {
|
||||||
pub registry: &'a registry::Registry,
|
pub registry: &'a registry::Registry,
|
||||||
|
@ -17,10 +17,14 @@ impl<'a> __Field<'a> {
|
||||||
self.field.description.map(ToString::to_string)
|
self.field.description.map(ToString::to_string)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn args(&self) -> Vec<__InputValue<'a>> {
|
async fn args(&self, ctx: &Context<'_>) -> Vec<__InputValue<'a>> {
|
||||||
self.field
|
self.field
|
||||||
.args
|
.args
|
||||||
.values()
|
.values()
|
||||||
|
.filter(|input_value| match &input_value.visible {
|
||||||
|
Some(f) => f(ctx),
|
||||||
|
None => true,
|
||||||
|
})
|
||||||
.map(|input_value| __InputValue {
|
.map(|input_value| __InputValue {
|
||||||
registry: self.registry,
|
registry: self.registry,
|
||||||
input_value,
|
input_value,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::model::{__Directive, __Type};
|
use crate::model::{__Directive, __Type};
|
||||||
use crate::{registry, Object};
|
use crate::{registry, Context, Object};
|
||||||
|
|
||||||
pub struct __Schema<'a> {
|
pub struct __Schema<'a> {
|
||||||
pub registry: &'a registry::Registry,
|
pub registry: &'a registry::Registry,
|
||||||
|
@ -9,12 +9,18 @@ pub struct __Schema<'a> {
|
||||||
#[Object(internal, name = "__Schema")]
|
#[Object(internal, name = "__Schema")]
|
||||||
impl<'a> __Schema<'a> {
|
impl<'a> __Schema<'a> {
|
||||||
/// A list of all types supported by this server.
|
/// A list of all types supported by this server.
|
||||||
async fn types(&self) -> Vec<__Type<'a>> {
|
async fn types(&self, ctx: &Context<'_>) -> Vec<__Type<'a>> {
|
||||||
let mut types: Vec<_> = self
|
let mut types: Vec<_> = self
|
||||||
.registry
|
.registry
|
||||||
.types
|
.types
|
||||||
.values()
|
.values()
|
||||||
.map(|ty| (ty.name(), __Type::new_simple(self.registry, ty)))
|
.filter_map(|ty| {
|
||||||
|
if ty.is_visible(ctx) {
|
||||||
|
Some((ty.name(), __Type::new_simple(self.registry, ty)))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
types.sort_by(|a, b| a.0.cmp(b.0));
|
types.sort_by(|a, b| a.0.cmp(b.0));
|
||||||
types.into_iter().map(|(_, ty)| ty).collect()
|
types.into_iter().map(|(_, ty)| ty).collect()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::model::{__EnumValue, __Field, __InputValue, __TypeKind};
|
use crate::model::{__EnumValue, __Field, __InputValue, __TypeKind};
|
||||||
use crate::{registry, Object};
|
use crate::{registry, Context, Object};
|
||||||
|
|
||||||
enum TypeDetail<'a> {
|
enum TypeDetail<'a> {
|
||||||
Named(&'a registry::MetaType),
|
Named(&'a registry::MetaType),
|
||||||
|
@ -95,12 +95,17 @@ impl<'a> __Type<'a> {
|
||||||
|
|
||||||
async fn fields(
|
async fn fields(
|
||||||
&self,
|
&self,
|
||||||
|
ctx: &Context<'_>,
|
||||||
#[graphql(default = false)] include_deprecated: bool,
|
#[graphql(default = false)] include_deprecated: bool,
|
||||||
) -> Option<Vec<__Field<'a>>> {
|
) -> Option<Vec<__Field<'a>>> {
|
||||||
if let TypeDetail::Named(ty) = &self.detail {
|
if let TypeDetail::Named(ty) = &self.detail {
|
||||||
ty.fields().map(|fields| {
|
ty.fields().map(|fields| {
|
||||||
fields
|
fields
|
||||||
.values()
|
.values()
|
||||||
|
.filter(|field| match &field.visible {
|
||||||
|
Some(f) => f(ctx),
|
||||||
|
None => true,
|
||||||
|
})
|
||||||
.filter(|field| {
|
.filter(|field| {
|
||||||
(include_deprecated || field.deprecation.is_none())
|
(include_deprecated || field.deprecation.is_none())
|
||||||
&& !field.name.starts_with("__")
|
&& !field.name.starts_with("__")
|
||||||
|
@ -158,13 +163,18 @@ impl<'a> __Type<'a> {
|
||||||
|
|
||||||
async fn enum_values(
|
async fn enum_values(
|
||||||
&self,
|
&self,
|
||||||
|
ctx: &Context<'_>,
|
||||||
#[graphql(default = false)] include_deprecated: bool,
|
#[graphql(default = false)] include_deprecated: bool,
|
||||||
) -> Option<Vec<__EnumValue<'a>>> {
|
) -> Option<Vec<__EnumValue<'a>>> {
|
||||||
if let TypeDetail::Named(registry::MetaType::Enum { enum_values, .. }) = &self.detail {
|
if let TypeDetail::Named(registry::MetaType::Enum { enum_values, .. }) = &self.detail {
|
||||||
Some(
|
Some(
|
||||||
enum_values
|
enum_values
|
||||||
.values()
|
.values()
|
||||||
.filter(|field| include_deprecated || field.deprecation.is_none())
|
.filter(|value| match &value.visible {
|
||||||
|
Some(f) => f(ctx),
|
||||||
|
None => true,
|
||||||
|
})
|
||||||
|
.filter(|value| include_deprecated || value.deprecation.is_none())
|
||||||
.map(|value| __EnumValue {
|
.map(|value| __EnumValue {
|
||||||
registry: self.registry,
|
registry: self.registry,
|
||||||
value,
|
value,
|
||||||
|
@ -176,13 +186,17 @@ impl<'a> __Type<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn input_fields(&self) -> Option<Vec<__InputValue<'a>>> {
|
async fn input_fields(&self, ctx: &Context<'_>) -> Option<Vec<__InputValue<'a>>> {
|
||||||
if let TypeDetail::Named(registry::MetaType::InputObject { input_fields, .. }) =
|
if let TypeDetail::Named(registry::MetaType::InputObject { input_fields, .. }) =
|
||||||
&self.detail
|
&self.detail
|
||||||
{
|
{
|
||||||
Some(
|
Some(
|
||||||
input_fields
|
input_fields
|
||||||
.values()
|
.values()
|
||||||
|
.filter(|input_value| match &input_value.visible {
|
||||||
|
Some(f) => f(ctx),
|
||||||
|
None => true,
|
||||||
|
})
|
||||||
.map(|input_value| __InputValue {
|
.map(|input_value| __InputValue {
|
||||||
registry: self.registry,
|
registry: self.registry,
|
||||||
input_value,
|
input_value,
|
||||||
|
|
|
@ -9,7 +9,7 @@ use indexmap::set::IndexSet;
|
||||||
|
|
||||||
use crate::parser::types::{BaseType as ParsedBaseType, Type as ParsedType};
|
use crate::parser::types::{BaseType as ParsedBaseType, Type as ParsedType};
|
||||||
use crate::validators::InputValueValidator;
|
use crate::validators::InputValueValidator;
|
||||||
use crate::{model, Any, Type, Value};
|
use crate::{model, Any, Context, Type, Value};
|
||||||
|
|
||||||
pub use cache_control::CacheControl;
|
pub use cache_control::CacheControl;
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ pub struct MetaInputValue {
|
||||||
pub ty: String,
|
pub ty: String,
|
||||||
pub default_value: Option<String>,
|
pub default_value: Option<String>,
|
||||||
pub validator: Option<Arc<dyn InputValueValidator>>,
|
pub validator: Option<Arc<dyn InputValueValidator>>,
|
||||||
|
pub visible: Option<MetaVisibleFn>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -105,6 +106,7 @@ pub struct MetaField {
|
||||||
pub external: bool,
|
pub external: bool,
|
||||||
pub requires: Option<&'static str>,
|
pub requires: Option<&'static str>,
|
||||||
pub provides: Option<&'static str>,
|
pub provides: Option<&'static str>,
|
||||||
|
pub visible: Option<MetaVisibleFn>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -112,13 +114,17 @@ 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>,
|
||||||
|
pub visible: Option<MetaVisibleFn>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MetaVisibleFn = fn(&Context<'_>) -> bool;
|
||||||
|
|
||||||
pub enum MetaType {
|
pub enum MetaType {
|
||||||
Scalar {
|
Scalar {
|
||||||
name: String,
|
name: String,
|
||||||
description: Option<&'static str>,
|
description: Option<&'static str>,
|
||||||
is_valid: fn(value: &Value) -> bool,
|
is_valid: fn(value: &Value) -> bool,
|
||||||
|
visible: Option<MetaVisibleFn>,
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
name: String,
|
name: String,
|
||||||
|
@ -127,6 +133,7 @@ pub enum MetaType {
|
||||||
cache_control: CacheControl,
|
cache_control: CacheControl,
|
||||||
extends: bool,
|
extends: bool,
|
||||||
keys: Option<Vec<String>>,
|
keys: Option<Vec<String>>,
|
||||||
|
visible: Option<MetaVisibleFn>,
|
||||||
},
|
},
|
||||||
Interface {
|
Interface {
|
||||||
name: String,
|
name: String,
|
||||||
|
@ -135,21 +142,25 @@ pub enum MetaType {
|
||||||
possible_types: IndexSet<String>,
|
possible_types: IndexSet<String>,
|
||||||
extends: bool,
|
extends: bool,
|
||||||
keys: Option<Vec<String>>,
|
keys: Option<Vec<String>>,
|
||||||
|
visible: Option<MetaVisibleFn>,
|
||||||
},
|
},
|
||||||
Union {
|
Union {
|
||||||
name: String,
|
name: String,
|
||||||
description: Option<&'static str>,
|
description: Option<&'static str>,
|
||||||
possible_types: IndexSet<String>,
|
possible_types: IndexSet<String>,
|
||||||
|
visible: Option<MetaVisibleFn>,
|
||||||
},
|
},
|
||||||
Enum {
|
Enum {
|
||||||
name: String,
|
name: String,
|
||||||
description: Option<&'static str>,
|
description: Option<&'static str>,
|
||||||
enum_values: IndexMap<&'static str, MetaEnumValue>,
|
enum_values: IndexMap<&'static str, MetaEnumValue>,
|
||||||
|
visible: Option<MetaVisibleFn>,
|
||||||
},
|
},
|
||||||
InputObject {
|
InputObject {
|
||||||
name: String,
|
name: String,
|
||||||
description: Option<&'static str>,
|
description: Option<&'static str>,
|
||||||
input_fields: IndexMap<String, MetaInputValue>,
|
input_fields: IndexMap<String, MetaInputValue>,
|
||||||
|
visible: Option<MetaVisibleFn>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,6 +177,21 @@ impl MetaType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_visible(&self, ctx: &Context<'_>) -> bool {
|
||||||
|
let visible = match self {
|
||||||
|
MetaType::Scalar { visible, .. } => visible,
|
||||||
|
MetaType::Object { visible, .. } => visible,
|
||||||
|
MetaType::Interface { visible, .. } => visible,
|
||||||
|
MetaType::Union { visible, .. } => visible,
|
||||||
|
MetaType::Enum { visible, .. } => visible,
|
||||||
|
MetaType::InputObject { visible, .. } => visible,
|
||||||
|
};
|
||||||
|
match visible {
|
||||||
|
Some(f) => f(ctx),
|
||||||
|
None => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> &str {
|
pub fn name(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
MetaType::Scalar { name, .. } => &name,
|
MetaType::Scalar { name, .. } => &name,
|
||||||
|
@ -281,6 +307,7 @@ impl Registry {
|
||||||
cache_control: Default::default(),
|
cache_control: Default::default(),
|
||||||
extends: false,
|
extends: false,
|
||||||
keys: None,
|
keys: None,
|
||||||
|
visible: None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let ty = f(self);
|
let ty = f(self);
|
||||||
|
@ -394,6 +421,7 @@ impl Registry {
|
||||||
name: "_Entity".to_string(),
|
name: "_Entity".to_string(),
|
||||||
description: None,
|
description: None,
|
||||||
possible_types,
|
possible_types,
|
||||||
|
visible: None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -420,6 +448,7 @@ impl Registry {
|
||||||
external: false,
|
external: false,
|
||||||
requires: None,
|
requires: None,
|
||||||
provides: None,
|
provides: None,
|
||||||
|
visible: None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
fields
|
fields
|
||||||
|
@ -427,6 +456,7 @@ impl Registry {
|
||||||
cache_control: Default::default(),
|
cache_control: Default::default(),
|
||||||
extends: false,
|
extends: false,
|
||||||
keys: None,
|
keys: None,
|
||||||
|
visible: None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -446,6 +476,7 @@ impl Registry {
|
||||||
external: false,
|
external: false,
|
||||||
requires: None,
|
requires: None,
|
||||||
provides: None,
|
provides: None,
|
||||||
|
visible: None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -464,6 +495,7 @@ impl Registry {
|
||||||
ty: "[_Any!]!".to_string(),
|
ty: "[_Any!]!".to_string(),
|
||||||
default_value: None,
|
default_value: None,
|
||||||
validator: None,
|
validator: None,
|
||||||
|
visible: None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
args
|
args
|
||||||
|
@ -474,6 +506,7 @@ impl Registry {
|
||||||
external: false,
|
external: false,
|
||||||
requires: None,
|
requires: None,
|
||||||
provides: None,
|
provides: None,
|
||||||
|
visible: None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,6 +121,7 @@ macro_rules! scalar_internal {
|
||||||
name: ::std::borrow::ToOwned::to_owned($name),
|
name: ::std::borrow::ToOwned::to_owned($name),
|
||||||
description: $desc,
|
description: $desc,
|
||||||
is_valid: |value| <$ty as $crate::ScalarType>::is_valid(value),
|
is_valid: |value| <$ty as $crate::ScalarType>::is_valid(value),
|
||||||
|
visible: ::std::option::Option::None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -266,6 +266,7 @@ where
|
||||||
ty: "Boolean!".to_string(),
|
ty: "Boolean!".to_string(),
|
||||||
default_value: None,
|
default_value: None,
|
||||||
validator: None,
|
validator: None,
|
||||||
|
visible: None,
|
||||||
});
|
});
|
||||||
args
|
args
|
||||||
}
|
}
|
||||||
|
@ -287,6 +288,7 @@ where
|
||||||
ty: "Boolean!".to_string(),
|
ty: "Boolean!".to_string(),
|
||||||
default_value: None,
|
default_value: None,
|
||||||
validator: None,
|
validator: None,
|
||||||
|
visible: None,
|
||||||
});
|
});
|
||||||
args
|
args
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,6 +159,7 @@ where
|
||||||
external: false,
|
external: false,
|
||||||
requires: None,
|
requires: None,
|
||||||
provides: None,
|
provides: None,
|
||||||
|
visible: None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -176,6 +177,7 @@ where
|
||||||
external: false,
|
external: false,
|
||||||
requires: None,
|
requires: None,
|
||||||
provides: None,
|
provides: None,
|
||||||
|
visible: None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -185,6 +187,7 @@ where
|
||||||
cache_control: Default::default(),
|
cache_control: Default::default(),
|
||||||
extends: false,
|
extends: false,
|
||||||
keys: None,
|
keys: None,
|
||||||
|
visible: None,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,7 @@ where
|
||||||
external: false,
|
external: false,
|
||||||
requires: None,
|
requires: None,
|
||||||
provides: None,
|
provides: None,
|
||||||
|
visible: None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -93,6 +94,7 @@ where
|
||||||
external: false,
|
external: false,
|
||||||
requires: None,
|
requires: None,
|
||||||
provides: None,
|
provides: None,
|
||||||
|
visible: None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -102,6 +104,7 @@ where
|
||||||
cache_control: Default::default(),
|
cache_control: Default::default(),
|
||||||
extends: false,
|
extends: false,
|
||||||
keys: None,
|
keys: None,
|
||||||
|
visible: None,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ impl Type for EmptyMutation {
|
||||||
cache_control: Default::default(),
|
cache_control: Default::default(),
|
||||||
extends: false,
|
extends: false,
|
||||||
keys: None,
|
keys: None,
|
||||||
|
visible: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ impl Type for EmptySubscription {
|
||||||
cache_control: Default::default(),
|
cache_control: Default::default(),
|
||||||
extends: false,
|
extends: false,
|
||||||
keys: None,
|
keys: None,
|
||||||
|
visible: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,7 @@ impl<T> Type for OutputJson<T> {
|
||||||
name: Self::type_name().to_string(),
|
name: Self::type_name().to_string(),
|
||||||
description: None,
|
description: None,
|
||||||
is_valid: |_| true,
|
is_valid: |_| true,
|
||||||
|
visible: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ impl<A: Type, B: Type> Type for MergedObject<A, B> {
|
||||||
cache_control: cc,
|
cache_control: cc,
|
||||||
extends: false,
|
extends: false,
|
||||||
keys: None,
|
keys: None,
|
||||||
|
visible: None,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ impl<T: Type> Type for QueryRoot<T> {
|
||||||
external: false,
|
external: false,
|
||||||
requires: None,
|
requires: None,
|
||||||
provides: None,
|
provides: None,
|
||||||
|
visible: None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -63,6 +64,7 @@ impl<T: Type> Type for QueryRoot<T> {
|
||||||
ty: "String!".to_string(),
|
ty: "String!".to_string(),
|
||||||
default_value: None,
|
default_value: None,
|
||||||
validator: None,
|
validator: None,
|
||||||
|
visible: None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
args
|
args
|
||||||
|
@ -73,6 +75,7 @@ impl<T: Type> Type for QueryRoot<T> {
|
||||||
external: false,
|
external: false,
|
||||||
requires: None,
|
requires: None,
|
||||||
provides: None,
|
provides: None,
|
||||||
|
visible: None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -106,6 +109,7 @@ impl<T: ObjectType + Send + Sync> ContainerType for QueryRoot<T> {
|
||||||
.registry
|
.registry
|
||||||
.types
|
.types
|
||||||
.get(&type_name)
|
.get(&type_name)
|
||||||
|
.filter(|ty| ty.is_visible(ctx))
|
||||||
.map(|ty| __Type::new_simple(&ctx.schema_env.registry, ty)),
|
.map(|ty| __Type::new_simple(&ctx.schema_env.registry, ty)),
|
||||||
&ctx_obj,
|
&ctx_obj,
|
||||||
ctx.item,
|
ctx.item,
|
||||||
|
|
|
@ -110,6 +110,7 @@ impl Type for Upload {
|
||||||
name: Self::type_name().to_string(),
|
name: Self::type_name().to_string(),
|
||||||
description: None,
|
description: None,
|
||||||
is_valid: |value| matches!(value, Value::String(_)),
|
is_valid: |value| matches!(value, Value::String(_)),
|
||||||
|
visible: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
254
tests/introspection_visible.rs
Normal file
254
tests/introspection_visible.rs
Normal file
|
@ -0,0 +1,254 @@
|
||||||
|
use async_graphql::*;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[async_std::test]
|
||||||
|
pub async fn test_type_visible() {
|
||||||
|
#[derive(SimpleObject)]
|
||||||
|
#[graphql(visible = false)]
|
||||||
|
struct MyObj {
|
||||||
|
a: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Query;
|
||||||
|
|
||||||
|
#[Object]
|
||||||
|
impl Query {
|
||||||
|
async fn obj(&self) -> MyObj {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let schema = Schema::new(Query, EmptyMutation, EmptySubscription);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
schema
|
||||||
|
.execute(r#"{ __type(name: "MyObj") { name } }"#)
|
||||||
|
.await
|
||||||
|
.into_result()
|
||||||
|
.unwrap()
|
||||||
|
.data,
|
||||||
|
value!({
|
||||||
|
"__type": null,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct QueryResponse {
|
||||||
|
#[serde(rename = "__schema")]
|
||||||
|
schema: SchemaResponse,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct SchemaResponse {
|
||||||
|
types: Vec<TypeResponse>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct TypeResponse {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
let resp: QueryResponse = from_value(
|
||||||
|
schema
|
||||||
|
.execute(r#"{ __schema { types { name } } }"#)
|
||||||
|
.await
|
||||||
|
.into_result()
|
||||||
|
.unwrap()
|
||||||
|
.data,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert!(resp
|
||||||
|
.schema
|
||||||
|
.types
|
||||||
|
.into_iter()
|
||||||
|
.find(|ty| ty.name == "MyObj")
|
||||||
|
.is_none());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_std::test]
|
||||||
|
pub async fn test_field_visible() {
|
||||||
|
#[derive(SimpleObject)]
|
||||||
|
struct MyObj {
|
||||||
|
a: i32,
|
||||||
|
#[graphql(visible = false)]
|
||||||
|
b: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Query;
|
||||||
|
|
||||||
|
#[Object]
|
||||||
|
impl Query {
|
||||||
|
async fn obj(&self) -> MyObj {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[graphql(visible = false)]
|
||||||
|
async fn c(&self) -> i32 {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let schema = Schema::new(Query, EmptyMutation, EmptySubscription);
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct QueryResponse {
|
||||||
|
#[serde(rename = "__type")]
|
||||||
|
ty: TypeResponse,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct TypeResponse {
|
||||||
|
fields: Vec<FieldResposne>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct FieldResposne {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
let resp: QueryResponse = from_value(
|
||||||
|
schema
|
||||||
|
.execute(r#"{ __type(name: "MyObj") { fields { name } } }"#)
|
||||||
|
.await
|
||||||
|
.into_result()
|
||||||
|
.unwrap()
|
||||||
|
.data,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
resp.ty
|
||||||
|
.fields
|
||||||
|
.iter()
|
||||||
|
.map(|field| field.name.as_str())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
vec!["a"]
|
||||||
|
);
|
||||||
|
|
||||||
|
let resp: QueryResponse = from_value(
|
||||||
|
schema
|
||||||
|
.execute(r#"{ __type(name: "Query") { fields { name } } }"#)
|
||||||
|
.await
|
||||||
|
.into_result()
|
||||||
|
.unwrap()
|
||||||
|
.data,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
resp.ty
|
||||||
|
.fields
|
||||||
|
.iter()
|
||||||
|
.map(|field| field.name.as_str())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
vec!["obj"]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_std::test]
|
||||||
|
pub async fn test_enum_value_visible() {
|
||||||
|
#[derive(Enum, Eq, PartialEq, Copy, Clone)]
|
||||||
|
enum MyEnum {
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
#[graphql(visible = false)]
|
||||||
|
C,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Query;
|
||||||
|
|
||||||
|
#[Object]
|
||||||
|
impl Query {
|
||||||
|
async fn e(&self) -> MyEnum {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let schema = Schema::new(Query, EmptyMutation, EmptySubscription);
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct QueryResponse {
|
||||||
|
#[serde(rename = "__type")]
|
||||||
|
ty: TypeResponse,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct TypeResponse {
|
||||||
|
enum_values: Vec<EnumValueResponse>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct EnumValueResponse {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
let resp: QueryResponse = from_value(
|
||||||
|
schema
|
||||||
|
.execute(r#"{ __type(name: "MyEnum") { enumValues { name } } }"#)
|
||||||
|
.await
|
||||||
|
.into_result()
|
||||||
|
.unwrap()
|
||||||
|
.data,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
resp.ty
|
||||||
|
.enum_values
|
||||||
|
.iter()
|
||||||
|
.map(|value| value.name.as_str())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
vec!["A", "B"]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_std::test]
|
||||||
|
pub async fn test_visible_fn() {
|
||||||
|
struct IsAdmin(bool);
|
||||||
|
|
||||||
|
#[derive(SimpleObject)]
|
||||||
|
#[graphql(visible = "is_admin")]
|
||||||
|
struct MyObj {
|
||||||
|
a: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_admin(ctx: &Context<'_>) -> bool {
|
||||||
|
ctx.data_unchecked::<IsAdmin>().0
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Query;
|
||||||
|
|
||||||
|
#[Object]
|
||||||
|
impl Query {
|
||||||
|
async fn obj(&self) -> MyObj {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let schema = Schema::new(Query, EmptyMutation, EmptySubscription);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
schema
|
||||||
|
.execute(Request::new(r#"{ __type(name: "MyObj") { name } }"#).data(IsAdmin(false)))
|
||||||
|
.await
|
||||||
|
.into_result()
|
||||||
|
.unwrap()
|
||||||
|
.data,
|
||||||
|
value!({
|
||||||
|
"__type": null,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
schema
|
||||||
|
.execute(Request::new(r#"{ __type(name: "MyObj") { name } }"#).data(IsAdmin(true)))
|
||||||
|
.await
|
||||||
|
.into_result()
|
||||||
|
.unwrap()
|
||||||
|
.data,
|
||||||
|
value!({
|
||||||
|
"__type": {
|
||||||
|
"name": "MyObj",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user