Add directive @ifdef
This commit is contained in:
parent
efaccb47e0
commit
a193a8e51a
|
@ -462,6 +462,16 @@ impl<'a, T> ContextBase<'a, T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn is_ifdef(&self, directives: &[Positioned<Directive>]) -> bool {
|
||||
for directive in directives {
|
||||
if directive.name.node == "ifdef" {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn is_skip(&self, directives: &[Positioned<Directive>]) -> Result<bool> {
|
||||
for directive in directives {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::extensions::{ErrorLogger, Extension, ResolveInfo};
|
||||
use crate::parser::query::{Selection, TypeCondition};
|
||||
use crate::registry::MetaType;
|
||||
use crate::{ContextSelectionSet, Error, ObjectType, QueryError, Result};
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
|
@ -47,6 +48,16 @@ fn do_resolve<'a, T: ObjectType + Send + Sync>(
|
|||
continue;
|
||||
}
|
||||
|
||||
if ctx.is_ifdef(&field.directives) {
|
||||
if let Some(MetaType::Object { fields, .. }) =
|
||||
ctx.schema_env.registry.types.get(T::type_name().as_ref())
|
||||
{
|
||||
if !fields.contains_key(field.name.as_str()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let ctx_field = ctx.with_field(field);
|
||||
let field_name = ctx_field.result_name().to_string();
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::base::BoxFieldFuture;
|
||||
use crate::extensions::{ErrorLogger, Extension, ResolveInfo};
|
||||
use crate::parser::query::{Selection, TypeCondition};
|
||||
use crate::registry::MetaType;
|
||||
use crate::{ContextSelectionSet, Error, ObjectType, QueryError, Result};
|
||||
use futures::{future, TryFutureExt};
|
||||
|
||||
|
@ -63,6 +64,16 @@ pub fn collect_fields<'a, T: ObjectType + Send + Sync>(
|
|||
continue;
|
||||
}
|
||||
|
||||
if ctx.is_ifdef(&field.directives) {
|
||||
if let Some(MetaType::Object { fields, .. }) =
|
||||
ctx.schema_env.registry.types.get(T::type_name().as_ref())
|
||||
{
|
||||
if !fields.contains_key(field.name.as_str()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
futures.push(Box::pin({
|
||||
let ctx = ctx.clone();
|
||||
async move {
|
||||
|
|
|
@ -241,6 +241,13 @@ where
|
|||
}
|
||||
});
|
||||
|
||||
registry.add_directive(MetaDirective {
|
||||
name: "ifdef",
|
||||
description: Some("Directs the executor to query only when the field exists."),
|
||||
locations: vec![__DirectiveLocation::FIELD],
|
||||
args: Default::default(),
|
||||
});
|
||||
|
||||
// register scalars
|
||||
bool::create_type_info(&mut registry);
|
||||
i32::create_type_info(&mut registry);
|
||||
|
|
|
@ -21,6 +21,10 @@ impl<'a> Visitor<'a> for FieldsOnCorrectType {
|
|||
.fields()
|
||||
.and_then(|fields| fields.get(field.name.as_str()))
|
||||
.is_none()
|
||||
&& !field
|
||||
.directives
|
||||
.iter()
|
||||
.any(|directive| directive.node.name.as_str() == "ifdef")
|
||||
{
|
||||
ctx.report_error(
|
||||
vec![field.position()],
|
||||
|
|
|
@ -61,3 +61,61 @@ pub async fn test_directive_include() {
|
|||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
pub async fn test_directive_ifdef() {
|
||||
struct QueryRoot;
|
||||
|
||||
#[Object]
|
||||
impl QueryRoot {
|
||||
pub async fn value1(&self) -> i32 {
|
||||
10
|
||||
}
|
||||
}
|
||||
|
||||
struct MutationRoot;
|
||||
|
||||
#[Object]
|
||||
impl MutationRoot {
|
||||
pub async fn action1(&self) -> i32 {
|
||||
10
|
||||
}
|
||||
}
|
||||
|
||||
let schema = Schema::new(QueryRoot, MutationRoot, EmptySubscription);
|
||||
let resp = schema
|
||||
.execute(
|
||||
r#"
|
||||
{
|
||||
value1 @ifdef
|
||||
value2 @ifdef
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
resp.data,
|
||||
serde_json::json!({
|
||||
"value1": 10,
|
||||
})
|
||||
);
|
||||
|
||||
let resp = schema
|
||||
.execute(
|
||||
r#"
|
||||
mutation {
|
||||
action1 @ifdef
|
||||
action2 @ifdef
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
resp.data,
|
||||
serde_json::json!({
|
||||
"action1": 10,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user