Fix attributes naming on fields and arguments for interfaces and unions (#806)
Additionally: - revive macros/tests/object - revive executor_tests/interfaces_unions
This commit is contained in:
parent
bcbf44ecbd
commit
3472fe6d10
21 changed files with 213 additions and 344 deletions
|
@ -167,7 +167,7 @@ use juniper::{graphql_interface, GraphQLObject};
|
|||
trait Character {
|
||||
fn id(&self) -> &str;
|
||||
|
||||
#[graphql_interface(ignore)] // or `#[graphql_interface(skip)]`, your choice
|
||||
#[graphql(ignore)] // or `#[graphql(skip)]`, your choice
|
||||
fn ignored(&self) -> u32 { 0 }
|
||||
}
|
||||
|
||||
|
@ -205,26 +205,26 @@ use juniper::graphql_interface;
|
|||
/// This doc is absent in GraphQL schema.
|
||||
trait Character {
|
||||
// Renames the field in GraphQL schema.
|
||||
#[graphql_interface(name = "myId")]
|
||||
#[graphql(name = "myId")]
|
||||
// Deprecates the field in GraphQL schema.
|
||||
// Usual Rust `#[deprecated]` attribute is supported too as field deprecation,
|
||||
// but `deprecated` attribute argument takes precedence over it, if specified.
|
||||
#[graphql_interface(deprecated = "Do not use it.")]
|
||||
#[graphql(deprecated = "Do not use it.")]
|
||||
// Describes the field in GraphQL schema.
|
||||
#[graphql_interface(description = "ID of my own character.")]
|
||||
#[graphql(description = "ID of my own character.")]
|
||||
// Usual Rust docs are supported too as field description,
|
||||
// but `description` attribute argument takes precedence over them, if specified.
|
||||
/// This description is absent in GraphQL schema.
|
||||
fn id(
|
||||
&self,
|
||||
// Renames the argument in GraphQL schema.
|
||||
#[graphql_interface(name = "myNum")]
|
||||
#[graphql(name = "myNum")]
|
||||
// Describes the argument in GraphQL schema.
|
||||
#[graphql_interface(description = "ID number of my own character.")]
|
||||
#[graphql(description = "ID number of my own character.")]
|
||||
// Specifies the default value for the argument.
|
||||
// The concrete value may be omitted, and the `Default::default` one
|
||||
// will be used in such case.
|
||||
#[graphql_interface(default = 5)]
|
||||
#[graphql(default = 5)]
|
||||
num: i32,
|
||||
) -> &str;
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ trait Character { // while still can be specified via `Context =
|
|||
fn id(&self, context: &Database) -> Option<&str>;
|
||||
|
||||
// Otherwise, you may mark it explicitly as a context argument.
|
||||
fn name(&self, #[graphql_interface(context)] db: &Database) -> Option<&str>;
|
||||
fn name(&self, #[graphql(context)] db: &Database) -> Option<&str>;
|
||||
}
|
||||
|
||||
#[derive(GraphQLObject)]
|
||||
|
@ -307,7 +307,7 @@ trait Character<S: ScalarValue> {
|
|||
// Otherwise, you may mark it explicitly as an executor argument.
|
||||
async fn name<'b>(
|
||||
&'b self,
|
||||
#[graphql_interface(executor)] another: &Executor<'_, '_, (), S>,
|
||||
#[graphql(executor)] another: &Executor<'_, '_, (), S>,
|
||||
) -> &'b str
|
||||
where
|
||||
S: Send + Sync;
|
||||
|
@ -319,7 +319,7 @@ struct Human {
|
|||
id: String,
|
||||
name: String,
|
||||
}
|
||||
#[graphql_interface(Scalar = S)]
|
||||
#[graphql_interface(scalar = S)]
|
||||
impl<S: ScalarValue> Character<S> for Human {
|
||||
async fn id<'a>(&self, executor: &'a Executor<'_, '_, (), S>) -> &'a str
|
||||
where
|
||||
|
@ -356,12 +356,12 @@ struct Database {
|
|||
}
|
||||
impl juniper::Context for Database {}
|
||||
|
||||
#[graphql_interface(for = [Human, Droid], Context = Database)]
|
||||
#[graphql_interface(for = [Human, Droid], context = Database)]
|
||||
#[graphql_interface(on Droid = get_droid)] // enables downcasting `Droid` via `get_droid()` function
|
||||
trait Character {
|
||||
fn id(&self) -> &str;
|
||||
|
||||
#[graphql_interface(downcast)] // makes method a downcast to `Human`, not a field
|
||||
#[graphql(downcast)] // makes method a downcast to `Human`, not a field
|
||||
// NOTICE: The method signature may optionally contain `&Database` context argument.
|
||||
fn as_human(&self) -> Option<&Human> {
|
||||
None
|
||||
|
@ -419,7 +419,7 @@ By default, `#[graphql_interface]` macro generates code, which is generic over a
|
|||
use juniper::{graphql_interface, DefaultScalarValue, GraphQLObject};
|
||||
|
||||
#[graphql_interface(for = [Human, Droid])]
|
||||
#[graphql_interface(Scalar = DefaultScalarValue)] // removing this line will fail compilation
|
||||
#[graphql_interface(scalar = DefaultScalarValue)] // removing this line will fail compilation
|
||||
trait Character {
|
||||
fn id(&self) -> &str;
|
||||
}
|
||||
|
@ -430,7 +430,7 @@ struct Human {
|
|||
id: String,
|
||||
home_planet: String,
|
||||
}
|
||||
#[graphql_interface(Scalar = DefaultScalarValue)]
|
||||
#[graphql_interface(scalar = DefaultScalarValue)]
|
||||
impl Character for Human {
|
||||
fn id(&self) -> &str {
|
||||
&self.id
|
||||
|
@ -443,7 +443,7 @@ struct Droid {
|
|||
id: String,
|
||||
primary_function: String,
|
||||
}
|
||||
#[graphql_interface(Scalar = DefaultScalarValue)]
|
||||
#[graphql_interface(scalar = DefaultScalarValue)]
|
||||
impl Character for Droid {
|
||||
fn id(&self) -> &str {
|
||||
&self.id
|
||||
|
|
|
@ -316,7 +316,7 @@ struct Database {
|
|||
}
|
||||
impl juniper::Context for Database {}
|
||||
|
||||
#[graphql_union(Context = Database)]
|
||||
#[graphql_union(context = Database)]
|
||||
trait Character {
|
||||
// NOTICE: The method signature may optionally contain `&Context`.
|
||||
fn as_human<'db>(&self, ctx: &'db Database) -> Option<&'db Human> { None }
|
||||
|
@ -363,7 +363,7 @@ struct Droid {
|
|||
trait Character {
|
||||
fn as_human(&self) -> Option<&Human> { None }
|
||||
fn as_droid(&self) -> Option<&Droid> { None }
|
||||
#[graphql_union(ignore)] // or `#[graphql_union(skip)]`, your choice
|
||||
#[graphql(ignore)] // or `#[graphql(skip)]`, your choice
|
||||
fn id(&self) -> &str;
|
||||
}
|
||||
|
||||
|
@ -410,13 +410,13 @@ struct Database {
|
|||
}
|
||||
impl juniper::Context for Database {}
|
||||
|
||||
#[graphql_union(Context = Database)]
|
||||
#[graphql_union(context = Database)]
|
||||
#[graphql_union(
|
||||
on Human = DynCharacter::get_human,
|
||||
on Droid = get_droid,
|
||||
)]
|
||||
trait Character {
|
||||
#[graphql_union(ignore)] // or `#[graphql_union(skip)]`, your choice
|
||||
#[graphql(ignore)] // or `#[graphql(skip)]`, your choice
|
||||
fn id(&self) -> &str;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ impl Character for ObjA {
|
|||
trait Character {
|
||||
fn id(&self, num: i32) -> &str;
|
||||
|
||||
#[graphql_interface(downcast)]
|
||||
#[graphql(downcast)]
|
||||
fn as_obja(&self) -> Option<&ObjA>;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ error: GraphQL interface trait method `as_obja` conflicts with the external down
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: https://spec.graphql.org/June2018/#sec-Interfaces
|
||||
= note: use `#[graphql_interface(ignore)]` attribute argument to ignore this trait method for interface implementers downcasting
|
||||
= note: use `#[graphql(ignore)]` attribute argument to ignore this trait method for interface implementers downcasting
|
||||
|
||||
error[E0412]: cannot find type `CharacterValue` in this scope
|
||||
--> $DIR/downcast_method_conflicts_with_external_downcast_fn.rs:4:18
|
||||
|
|
|
@ -6,7 +6,7 @@ trait Character {
|
|||
0
|
||||
}
|
||||
|
||||
#[graphql_interface(downcast)]
|
||||
#[graphql(downcast)]
|
||||
fn a(&self, ctx: &(), rand: u8) -> Option<&Human> {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ trait Character {
|
|||
0
|
||||
}
|
||||
|
||||
#[graphql_interface(downcast)]
|
||||
#[graphql(downcast)]
|
||||
fn a(&self, ctx: &(), rand: u8) -> &Human {
|
||||
unimplemented!()
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ trait Character {
|
|||
"funA"
|
||||
}
|
||||
|
||||
#[graphql_interface(name = "id")]
|
||||
#[graphql(name = "id")]
|
||||
fn id2(&self) -> &str {
|
||||
"funB"
|
||||
}
|
||||
|
|
|
@ -5,4 +5,4 @@ error: GraphQL union trait method `a` conflicts with the external resolver funct
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: https://spec.graphql.org/June2018/#sec-Unions
|
||||
= note: use `#[graphql_union(ignore)]` attribute to ignore this trait method for union variants resolution
|
||||
= note: use `#[graphql(ignore)]` attribute to ignore this trait method for union variants resolution
|
||||
|
|
|
@ -2,7 +2,7 @@ use juniper::{graphql_union, GraphQLObject};
|
|||
|
||||
#[graphql_union]
|
||||
trait Character {
|
||||
#[graphql_union(with = something)]
|
||||
#[graphql(with = something)]
|
||||
fn a(&self) -> Option<&Human>;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error: GraphQL union cannot use #[graphql_union(with = ...)] attribute on a trait method
|
||||
--> $DIR/trait_with_attr_on_method.rs:5:21
|
||||
error: GraphQL union cannot use #[graphql(with = ...)] attribute on a trait method
|
||||
--> $DIR/trait_with_attr_on_method.rs:5:15
|
||||
|
|
||||
5 | #[graphql_union(with = something)]
|
||||
| ^^^^
|
||||
5 | #[graphql(with = something)]
|
||||
| ^^^^
|
||||
|
|
||||
= note: https://spec.graphql.org/June2018/#sec-Unions
|
||||
= note: instead use #[graphql_union(ignore)] on the method with #[graphql_union(on ... = ...)] on the trait itself
|
||||
= note: instead use #[graphql(ignore)] on the method with #[graphql_union(on ... = ...)] on the trait itself
|
||||
|
|
|
@ -2451,9 +2451,9 @@ mod default_argument {
|
|||
trait Character {
|
||||
async fn id(
|
||||
&self,
|
||||
#[graphql_interface(default)] first: String,
|
||||
#[graphql_interface(default = "second".to_string())] second: String,
|
||||
#[graphql_interface(default = "t")] third: String,
|
||||
#[graphql(default)] first: String,
|
||||
#[graphql(default = "second".to_string())] second: String,
|
||||
#[graphql(default = "t")] third: String,
|
||||
) -> String;
|
||||
}
|
||||
|
||||
|
@ -2741,14 +2741,14 @@ mod explicit_name_description_and_deprecation {
|
|||
#[graphql_interface(name = "MyChar", desc = "My character.", for = Human)]
|
||||
trait Character {
|
||||
/// Rust `id` docs.
|
||||
#[graphql_interface(name = "myId", desc = "My character ID.", deprecated = "Not used.")]
|
||||
#[graphql(name = "myId", desc = "My character ID.", deprecated = "Not used.")]
|
||||
#[deprecated(note = "Should be omitted.")]
|
||||
fn id(
|
||||
&self,
|
||||
#[graphql_interface(name = "myName", desc = "My argument.", default)] n: Option<String>,
|
||||
#[graphql(name = "myName", desc = "My argument.", default)] n: Option<String>,
|
||||
) -> &str;
|
||||
|
||||
#[graphql_interface(deprecated)]
|
||||
#[graphql(deprecated)]
|
||||
#[deprecated(note = "Should be omitted.")]
|
||||
fn a(&self) -> &str {
|
||||
"a"
|
||||
|
@ -3605,7 +3605,7 @@ mod explicit_custom_context {
|
|||
|
||||
async fn info<'b>(&'b self, ctx: &()) -> &'b str;
|
||||
|
||||
fn more<'c>(&'c self, #[graphql_interface(context)] custom: &CustomContext) -> &'c str;
|
||||
fn more<'c>(&'c self, #[graphql(context)] custom: &CustomContext) -> &'c str;
|
||||
}
|
||||
|
||||
#[graphql_interface(dyn = DynHero, for = [Human, Droid])]
|
||||
|
@ -3615,7 +3615,7 @@ mod explicit_custom_context {
|
|||
|
||||
async fn info<'b>(&'b self, ctx: &()) -> &'b str;
|
||||
|
||||
fn more<'c>(&'c self, #[graphql_interface(context)] custom: &CustomContext) -> &'c str;
|
||||
fn more<'c>(&'c self, #[graphql(context)] custom: &CustomContext) -> &'c str;
|
||||
}
|
||||
|
||||
#[derive(GraphQLObject)]
|
||||
|
@ -4118,7 +4118,7 @@ mod inferred_custom_context_from_downcast {
|
|||
|
||||
#[graphql_interface(for = [Human, Droid])]
|
||||
trait Character {
|
||||
#[graphql_interface(downcast)]
|
||||
#[graphql(downcast)]
|
||||
fn as_human<'s>(&'s self, _: &Database) -> Option<&'s Human>;
|
||||
|
||||
async fn id(&self) -> &str;
|
||||
|
@ -4126,7 +4126,7 @@ mod inferred_custom_context_from_downcast {
|
|||
|
||||
#[graphql_interface(dyn = DynHero, for = [Human, Droid])]
|
||||
trait Hero {
|
||||
#[graphql_interface(downcast)]
|
||||
#[graphql(downcast)]
|
||||
fn as_droid<'db>(&self, db: &'db Database) -> Option<&'db Droid>;
|
||||
|
||||
async fn info(&self) -> &str;
|
||||
|
@ -4390,7 +4390,7 @@ mod executor {
|
|||
|
||||
async fn info<'b>(
|
||||
&'b self,
|
||||
#[graphql_interface(executor)] another: &Executor<'_, '_, (), S>,
|
||||
#[graphql(executor)] another: &Executor<'_, '_, (), S>,
|
||||
) -> &'b str
|
||||
where
|
||||
S: Send + Sync;
|
||||
|
@ -4407,7 +4407,7 @@ mod executor {
|
|||
|
||||
async fn info<'b>(
|
||||
&'b self,
|
||||
#[graphql_interface(executor)] another: &Executor<'_, '_, (), S>,
|
||||
#[graphql(executor)] another: &Executor<'_, '_, (), S>,
|
||||
) -> &'b str
|
||||
where
|
||||
S: Send + Sync;
|
||||
|
@ -4631,12 +4631,12 @@ mod ignored_method {
|
|||
trait Character {
|
||||
fn id(&self) -> &str;
|
||||
|
||||
#[graphql_interface(ignore)]
|
||||
#[graphql(ignore)]
|
||||
fn ignored(&self) -> Option<&Human> {
|
||||
None
|
||||
}
|
||||
|
||||
#[graphql_interface(skip)]
|
||||
#[graphql(skip)]
|
||||
fn skipped(&self) {}
|
||||
}
|
||||
|
||||
|
@ -4734,7 +4734,7 @@ mod downcast_method {
|
|||
trait Character {
|
||||
fn id(&self) -> &str;
|
||||
|
||||
#[graphql_interface(downcast)]
|
||||
#[graphql(downcast)]
|
||||
fn as_human(&self) -> Option<&Human> {
|
||||
None
|
||||
}
|
||||
|
@ -4744,7 +4744,7 @@ mod downcast_method {
|
|||
trait Hero {
|
||||
fn info(&self) -> &str;
|
||||
|
||||
#[graphql_interface(downcast)]
|
||||
#[graphql(downcast)]
|
||||
fn as_droid(&self) -> Option<&Droid> {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -842,11 +842,11 @@ mod ignored_method {
|
|||
fn as_human(&self) -> Option<&Human> {
|
||||
None
|
||||
}
|
||||
#[graphql_union(ignore)]
|
||||
#[graphql(ignore)]
|
||||
fn ignored(&self) -> Option<&Ewok> {
|
||||
None
|
||||
}
|
||||
#[graphql_union(skip)]
|
||||
#[graphql(skip)]
|
||||
fn skipped(&self) {}
|
||||
}
|
||||
|
||||
|
@ -1030,11 +1030,11 @@ mod full_featured {
|
|||
fn as_droid(&self) -> Option<&DroidCustomContext> {
|
||||
None
|
||||
}
|
||||
#[graphql_union(ignore)]
|
||||
#[graphql(ignore)]
|
||||
fn as_ewok(&self) -> Option<&EwokCustomContext> {
|
||||
None
|
||||
}
|
||||
#[graphql_union(ignore)]
|
||||
#[graphql(ignore)]
|
||||
fn ignored(&self) {}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,35 +1,31 @@
|
|||
mod interface {
|
||||
use crate::{
|
||||
graphql_interface, graphql_object,
|
||||
schema::model::RootNode,
|
||||
types::scalars::{EmptyMutation, EmptySubscription},
|
||||
value::Value,
|
||||
};
|
||||
|
||||
#[graphql_interface(for = [Cat, Dog])]
|
||||
trait Pet {
|
||||
fn name(&self) -> &str;
|
||||
|
||||
#[graphql(downcast)]
|
||||
fn as_dog(&self) -> Option<&Dog> {
|
||||
None
|
||||
}
|
||||
#[graphql(downcast)]
|
||||
fn as_cat(&self) -> Option<&Cat> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
graphql_interface!(<'a> &'a dyn Pet: () as "Pet" |&self| {
|
||||
field name() -> &str { self.name() }
|
||||
|
||||
instance_resolvers: |&_| {
|
||||
&Dog => self.as_dog(),
|
||||
&Cat => self.as_cat(),
|
||||
}
|
||||
});
|
||||
|
||||
struct Dog {
|
||||
name: String,
|
||||
woofs: bool,
|
||||
}
|
||||
|
||||
#[graphql_interface]
|
||||
impl Pet for Dog {
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
|
@ -39,9 +35,7 @@ mod interface {
|
|||
}
|
||||
}
|
||||
|
||||
#[crate::graphql_object(
|
||||
interfaces = [&dyn Pet]
|
||||
)]
|
||||
#[graphql_object(impl = PetValue)]
|
||||
impl Dog {
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
|
@ -56,6 +50,7 @@ mod interface {
|
|||
meows: bool,
|
||||
}
|
||||
|
||||
#[graphql_interface]
|
||||
impl Pet for Cat {
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
|
@ -65,9 +60,7 @@ mod interface {
|
|||
}
|
||||
}
|
||||
|
||||
#[crate::graphql_object(
|
||||
interfaces = [&dyn Pet]
|
||||
)]
|
||||
#[graphql_object(impl = PetValue)]
|
||||
impl Cat {
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
|
@ -78,13 +71,13 @@ mod interface {
|
|||
}
|
||||
|
||||
struct Schema {
|
||||
pets: Vec<Box<dyn Pet>>,
|
||||
pets: Vec<PetValue>,
|
||||
}
|
||||
|
||||
#[crate::graphql_object]
|
||||
#[graphql_object]
|
||||
impl Schema {
|
||||
fn pets(&self) -> Vec<&dyn Pet> {
|
||||
self.pets.iter().map(|p| p.as_ref()).collect()
|
||||
fn pets(&self) -> &Vec<PetValue> {
|
||||
&self.pets
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,14 +86,16 @@ mod interface {
|
|||
let schema = RootNode::new(
|
||||
Schema {
|
||||
pets: vec![
|
||||
Box::new(Dog {
|
||||
Dog {
|
||||
name: "Odie".to_owned(),
|
||||
woofs: true,
|
||||
}),
|
||||
Box::new(Cat {
|
||||
}
|
||||
.into(),
|
||||
Cat {
|
||||
name: "Garfield".to_owned(),
|
||||
meows: false,
|
||||
}),
|
||||
}
|
||||
.into(),
|
||||
],
|
||||
},
|
||||
EmptyMutation::<()>::new(),
|
||||
|
@ -162,12 +157,13 @@ mod interface {
|
|||
|
||||
mod union {
|
||||
use crate::{
|
||||
graphql_object, graphql_union,
|
||||
schema::model::RootNode,
|
||||
types::scalars::{EmptyMutation, EmptySubscription},
|
||||
value::Value,
|
||||
};
|
||||
|
||||
#[crate::graphql_union]
|
||||
#[graphql_union]
|
||||
trait Pet {
|
||||
fn as_dog(&self) -> Option<&Dog> {
|
||||
None
|
||||
|
@ -188,7 +184,7 @@ mod union {
|
|||
}
|
||||
}
|
||||
|
||||
#[crate::graphql_object]
|
||||
#[graphql_object]
|
||||
impl Dog {
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
|
@ -209,7 +205,7 @@ mod union {
|
|||
}
|
||||
}
|
||||
|
||||
#[crate::graphql_object]
|
||||
#[graphql_object]
|
||||
impl Cat {
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
|
@ -220,12 +216,12 @@ mod union {
|
|||
}
|
||||
|
||||
struct Schema {
|
||||
pets: Vec<Box<dyn Pet>>,
|
||||
pets: Vec<Box<dyn Pet + Send + Sync>>,
|
||||
}
|
||||
|
||||
#[crate::graphql_object]
|
||||
#[graphql_object]
|
||||
impl Schema {
|
||||
fn pets(&self) -> Vec<&dyn Pet> {
|
||||
fn pets(&self) -> Vec<&(dyn Pet + Send + Sync)> {
|
||||
self.pets.iter().map(|p| p.as_ref()).collect()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,6 @@ mod executor;
|
|||
mod introspection;
|
||||
mod variables;
|
||||
|
||||
// FIXME: re-enable
|
||||
#[cfg(TODO)]
|
||||
mod interfaces_unions;
|
||||
|
||||
mod async_await;
|
||||
|
|
|
@ -151,13 +151,13 @@ impl Interface for Root {
|
|||
trait Interface {
|
||||
fn simple(&self) -> i32;
|
||||
|
||||
#[graphql_interface(desc = "Field description")]
|
||||
#[graphql(desc = "Field description")]
|
||||
fn description(&self) -> i32;
|
||||
|
||||
#[graphql_interface(deprecated = "Deprecation reason")]
|
||||
#[graphql(deprecated = "Deprecation reason")]
|
||||
fn deprecated(&self) -> i32;
|
||||
|
||||
#[graphql_interface(desc = "Field description", deprecated = "Deprecation reason")]
|
||||
#[graphql(desc = "Field description", deprecated = "Deprecation reason")]
|
||||
fn deprecated_descr(&self) -> i32;
|
||||
|
||||
/// Field description
|
||||
|
|
|
@ -1,18 +1,4 @@
|
|||
// TODO: make sure proc macro tests cover all
|
||||
// variants of the below
|
||||
|
||||
/*
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use crate::{
|
||||
ast::InputValue,
|
||||
executor::{Context, FieldResult},
|
||||
schema::model::RootNode,
|
||||
types::scalars::{EmptyMutation, EmptySubscription},
|
||||
value::{DefaultScalarValue, Object, Value},
|
||||
};
|
||||
|
||||
|
||||
Syntax to validate:
|
||||
|
||||
* Order of items: fields, description, interfaces
|
||||
|
@ -20,125 +6,125 @@ Syntax to validate:
|
|||
* Custom name vs. default name
|
||||
* Optional commas between items
|
||||
* Nullable/fallible context switching
|
||||
*/
|
||||
|
||||
*/
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use crate::{
|
||||
ast::InputValue,
|
||||
executor::{Context, FieldResult},
|
||||
graphql_interface, graphql_object,
|
||||
schema::model::RootNode,
|
||||
types::scalars::{EmptyMutation, EmptySubscription},
|
||||
value::{DefaultScalarValue, Object, Value},
|
||||
GraphQLObject,
|
||||
};
|
||||
|
||||
/*
|
||||
struct CustomName;
|
||||
graphql_object!(CustomName: () as "ACustomNamedType" |&self| {
|
||||
field simple() -> i32 { 0 }
|
||||
});
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[graphql_object(name = "ACustomNamedType")]
|
||||
impl CustomName {
|
||||
fn simple() -> i32 {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
struct WithLifetime<'a> {
|
||||
data: PhantomData<&'a i32>,
|
||||
}
|
||||
graphql_object!(<'a> WithLifetime<'a>: () as "WithLifetime" |&self| {
|
||||
field simple() -> i32 { 0 }
|
||||
});
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[graphql_object]
|
||||
impl<'a> WithLifetime<'a> {
|
||||
fn simple() -> i32 {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
struct WithGenerics<T> {
|
||||
data: T,
|
||||
}
|
||||
graphql_object!(<T> WithGenerics<T>: () as "WithGenerics" |&self| {
|
||||
field simple() -> i32 { 0 }
|
||||
});
|
||||
|
||||
struct Interface;
|
||||
struct DescriptionFirst;
|
||||
graphql_interface!(Interface: () |&self| {
|
||||
field simple() -> i32 { 0 }
|
||||
|
||||
instance_resolvers: |_| {
|
||||
DescriptionFirst => Some(DescriptionFirst {}),
|
||||
#[graphql_object]
|
||||
impl<T> WithGenerics<T> {
|
||||
fn simple() -> i32 {
|
||||
0
|
||||
}
|
||||
});
|
||||
graphql_object!(DescriptionFirst: () |&self| {
|
||||
description: "A description"
|
||||
}
|
||||
|
||||
field simple() -> i32 { 0 }
|
||||
#[graphql_interface(for = SimpleObject)]
|
||||
trait Interface {
|
||||
fn simple(&self) -> i32 {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
interfaces: [Interface]
|
||||
});
|
||||
#[derive(GraphQLObject)]
|
||||
#[graphql(impl = InterfaceValue, description = "A description")]
|
||||
struct SimpleObject {
|
||||
simple: i32,
|
||||
}
|
||||
|
||||
struct FieldsFirst;
|
||||
graphql_object!(FieldsFirst: () |&self| {
|
||||
field simple() -> i32 { 0 }
|
||||
|
||||
description: "A description"
|
||||
|
||||
interfaces: [Interface]
|
||||
});
|
||||
|
||||
struct InterfacesFirst;
|
||||
graphql_object!(InterfacesFirst: ()|&self| {
|
||||
interfaces: [Interface]
|
||||
|
||||
field simple() -> i32 { 0 }
|
||||
|
||||
description: "A description"
|
||||
});
|
||||
|
||||
struct CommasWithTrailing;
|
||||
graphql_object!(CommasWithTrailing: () |&self| {
|
||||
interfaces: [Interface],
|
||||
|
||||
field simple() -> i32 { 0 },
|
||||
|
||||
description: "A description",
|
||||
});
|
||||
|
||||
struct CommasOnMeta;
|
||||
graphql_object!(CommasOnMeta: () |&self| {
|
||||
interfaces: [Interface],
|
||||
description: "A description",
|
||||
|
||||
field simple() -> i32 { 0 }
|
||||
});
|
||||
|
||||
struct Root;
|
||||
#[graphql_interface]
|
||||
impl Interface for SimpleObject {}
|
||||
|
||||
struct InnerContext;
|
||||
impl Context for InnerContext {}
|
||||
|
||||
struct InnerType;
|
||||
graphql_object!(InnerType: InnerContext | &self | {});
|
||||
#[derive(GraphQLObject)]
|
||||
#[graphql(context = InnerContext)]
|
||||
struct InnerType {
|
||||
a: i32,
|
||||
}
|
||||
|
||||
struct CtxSwitcher;
|
||||
graphql_object!(CtxSwitcher: InnerContext |&self| {
|
||||
field ctx_switch_always(&executor) -> (&InnerContext, InnerType) {
|
||||
(executor.context(), InnerType)
|
||||
|
||||
#[graphql_object(context = InnerContext)]
|
||||
impl CtxSwitcher {
|
||||
fn ctx_switch_always() -> (&InnerContext, InnerType) {
|
||||
(executor.context(), InnerType { a: 0 })
|
||||
}
|
||||
|
||||
field ctx_switch_opt(&executor) -> Option<(&InnerContext, InnerType)> {
|
||||
Some((executor.context(), InnerType))
|
||||
fn ctx_switch_opt() -> Option<(&InnerContext, InnerType)> {
|
||||
Some((executor.context(), InnerType { a: 0 }))
|
||||
}
|
||||
|
||||
field ctx_switch_res(&executor) -> FieldResult<(&InnerContext, InnerType)> {
|
||||
Ok((executor.context(), InnerType))
|
||||
fn ctx_switch_res() -> FieldResult<(&InnerContext, InnerType)> {
|
||||
Ok((executor.context(), InnerType { a: 0 }))
|
||||
}
|
||||
|
||||
field ctx_switch_res_opt(&executor) -> FieldResult<Option<(&InnerContext, InnerType)>> {
|
||||
Ok(Some((executor.context(), InnerType)))
|
||||
fn ctx_switch_res_opt() -> FieldResult<Option<(&InnerContext, InnerType)>> {
|
||||
Ok(Some((executor.context(), InnerType { a: 0 })))
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
graphql_object!(<'a> Root: InnerContext as "Root" |&self| {
|
||||
field custom_name() -> CustomName { CustomName {} }
|
||||
struct Root;
|
||||
|
||||
field with_lifetime() -> WithLifetime<'a> { WithLifetime { data: PhantomData } }
|
||||
field with_generics() -> WithGenerics<i32> { WithGenerics { data: 123 } }
|
||||
#[graphql_object(context = InnerContext)]
|
||||
impl Root {
|
||||
fn custom_name() -> CustomName {
|
||||
CustomName {}
|
||||
}
|
||||
|
||||
field description_first() -> DescriptionFirst { DescriptionFirst {} }
|
||||
field fields_first() -> FieldsFirst { FieldsFirst {} }
|
||||
field interfaces_first() -> InterfacesFirst { InterfacesFirst {} }
|
||||
fn with_lifetime() -> WithLifetime<'static> {
|
||||
WithLifetime { data: PhantomData }
|
||||
}
|
||||
fn with_generics() -> WithGenerics<i32> {
|
||||
WithGenerics { data: 123 }
|
||||
}
|
||||
|
||||
field commas_with_trailing() -> CommasWithTrailing { CommasWithTrailing {} }
|
||||
field commas_on_meta() -> CommasOnMeta { CommasOnMeta {} }
|
||||
fn description_first() -> SimpleObject {
|
||||
SimpleObject { simple: 0 }
|
||||
}
|
||||
fn interface() -> InterfaceValue {
|
||||
SimpleObject { simple: 0 }.into()
|
||||
}
|
||||
|
||||
field ctx_switcher() -> CtxSwitcher { CtxSwitcher {} }
|
||||
});
|
||||
fn ctx_switcher() -> CtxSwitcher {
|
||||
CtxSwitcher {}
|
||||
}
|
||||
}
|
||||
|
||||
fn run_type_info_query<F>(type_name: &str, f: F)
|
||||
where
|
||||
|
@ -170,7 +156,7 @@ where
|
|||
let schema = RootNode::new(
|
||||
Root {},
|
||||
EmptyMutation::<InnerContext>::new(),
|
||||
EmptySubscription::<()>::new(),
|
||||
EmptySubscription::<InnerContext>::new(),
|
||||
);
|
||||
let vars = vec![("typeName".to_owned(), InputValue::scalar(type_name))]
|
||||
.into_iter()
|
||||
|
@ -215,7 +201,11 @@ fn introspect_custom_name() {
|
|||
|
||||
assert!(fields.contains(&graphql_value!({
|
||||
"name": "simple",
|
||||
"type": { "kind": "NON_NULL", "name": None, "ofType": { "kind": "SCALAR", "name": "Int" } }
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": None,
|
||||
"ofType": { "kind": "SCALAR", "name": "Int" }
|
||||
}
|
||||
})));
|
||||
});
|
||||
}
|
||||
|
@ -235,7 +225,9 @@ fn introspect_with_lifetime() {
|
|||
|
||||
assert!(fields.contains(&graphql_value!({
|
||||
"name": "simple",
|
||||
"type": { "kind": "NON_NULL", "name": None, "ofType": { "kind": "SCALAR", "name": "Int" } }
|
||||
"type": {
|
||||
"kind": "NON_NULL", "name": None, "ofType": { "kind": "SCALAR", "name": "Int" }
|
||||
}
|
||||
})));
|
||||
});
|
||||
}
|
||||
|
@ -255,17 +247,19 @@ fn introspect_with_generics() {
|
|||
|
||||
assert!(fields.contains(&graphql_value!({
|
||||
"name": "simple",
|
||||
"type": { "kind": "NON_NULL", "name": None, "ofType": { "kind": "SCALAR", "name": "Int" } }
|
||||
"type": {
|
||||
"kind": "NON_NULL", "name": None, "ofType": { "kind": "SCALAR", "name": "Int" }
|
||||
}
|
||||
})));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn introspect_description_first() {
|
||||
run_type_info_query("DescriptionFirst", |object, fields| {
|
||||
fn introspect_simple_object() {
|
||||
run_type_info_query("SimpleObject", |object, fields| {
|
||||
assert_eq!(
|
||||
object.get_field_value("name"),
|
||||
Some(&Value::scalar("DescriptionFirst"))
|
||||
Some(&Value::scalar("SimpleObject"))
|
||||
);
|
||||
assert_eq!(
|
||||
object.get_field_value("description"),
|
||||
|
@ -285,127 +279,9 @@ fn introspect_description_first() {
|
|||
|
||||
assert!(fields.contains(&graphql_value!({
|
||||
"name": "simple",
|
||||
"type": { "kind": "NON_NULL", "name": None, "ofType": { "kind": "SCALAR", "name": "Int" } }
|
||||
})));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn introspect_fields_first() {
|
||||
run_type_info_query("FieldsFirst", |object, fields| {
|
||||
assert_eq!(
|
||||
object.get_field_value("name"),
|
||||
Some(&Value::scalar("FieldsFirst"))
|
||||
);
|
||||
assert_eq!(
|
||||
object.get_field_value("description"),
|
||||
Some(&Value::scalar("A description"))
|
||||
);
|
||||
assert_eq!(
|
||||
object.get_field_value("interfaces"),
|
||||
Some(&Value::list(vec![Value::object(
|
||||
vec![
|
||||
("name", Value::scalar("Interface")),
|
||||
("kind", Value::scalar("INTERFACE")),
|
||||
]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
)]))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&graphql_value!({
|
||||
"name": "simple",
|
||||
"type": { "kind": "NON_NULL", "name": None, "ofType": { "kind": "SCALAR", "name": "Int" } }
|
||||
})));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn introspect_interfaces_first() {
|
||||
run_type_info_query("InterfacesFirst", |object, fields| {
|
||||
assert_eq!(
|
||||
object.get_field_value("name"),
|
||||
Some(&Value::scalar("InterfacesFirst"))
|
||||
);
|
||||
assert_eq!(
|
||||
object.get_field_value("description"),
|
||||
Some(&Value::scalar("A description"))
|
||||
);
|
||||
assert_eq!(
|
||||
object.get_field_value("interfaces"),
|
||||
Some(&Value::list(vec![Value::object(
|
||||
vec![
|
||||
("name", Value::scalar("Interface")),
|
||||
("kind", Value::scalar("INTERFACE")),
|
||||
]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
)]))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&graphql_value!({
|
||||
"name": "simple",
|
||||
"type": { "kind": "NON_NULL", "name": None, "ofType": { "kind": "SCALAR", "name": "Int" } }
|
||||
})));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn introspect_commas_with_trailing() {
|
||||
run_type_info_query("CommasWithTrailing", |object, fields| {
|
||||
assert_eq!(
|
||||
object.get_field_value("name"),
|
||||
Some(&Value::scalar("CommasWithTrailing"))
|
||||
);
|
||||
assert_eq!(
|
||||
object.get_field_value("description"),
|
||||
Some(&Value::scalar("A description"))
|
||||
);
|
||||
assert_eq!(
|
||||
object.get_field_value("interfaces"),
|
||||
Some(&Value::list(vec![Value::object(
|
||||
vec![
|
||||
("name", Value::scalar("Interface")),
|
||||
("kind", Value::scalar("INTERFACE")),
|
||||
]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
)]))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&graphql_value!({
|
||||
"name": "simple",
|
||||
"type": { "kind": "NON_NULL", "name": None, "ofType": { "kind": "SCALAR", "name": "Int" } }
|
||||
})));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn introspect_commas_on_meta() {
|
||||
run_type_info_query("CommasOnMeta", |object, fields| {
|
||||
assert_eq!(
|
||||
object.get_field_value("name"),
|
||||
Some(&Value::scalar("CommasOnMeta"))
|
||||
);
|
||||
assert_eq!(
|
||||
object.get_field_value("description"),
|
||||
Some(&Value::scalar("A description"))
|
||||
);
|
||||
assert_eq!(
|
||||
object.get_field_value("interfaces"),
|
||||
Some(&Value::list(vec![Value::object(
|
||||
vec![
|
||||
("name", Value::scalar("Interface")),
|
||||
("kind", Value::scalar("INTERFACE")),
|
||||
]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
)]))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&graphql_value!({
|
||||
"name": "simple",
|
||||
"type": { "kind": "NON_NULL", "name": None, "ofType": { "kind": "SCALAR", "name": "Int" } }
|
||||
"type": {
|
||||
"kind": "NON_NULL", "name": None, "ofType": { "kind": "SCALAR", "name": "Int" }
|
||||
}
|
||||
})));
|
||||
});
|
||||
}
|
||||
|
@ -456,4 +332,3 @@ fn introspect_ctx_switch() {
|
|||
})));
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -63,7 +63,7 @@ pub trait Character {
|
|||
/// Which movies they appear in
|
||||
fn appears_in(&self) -> &[Episode];
|
||||
|
||||
#[graphql_interface(ignore)]
|
||||
#[graphql(ignore)]
|
||||
fn friends_ids(&self) -> &[String];
|
||||
}
|
||||
|
||||
|
|
|
@ -360,7 +360,7 @@ enum TraitMethod {
|
|||
impl TraitMethod {
|
||||
/// Parses this [`TraitMethod`] from the given trait method definition.
|
||||
///
|
||||
/// Returns [`None`] if the trait method marked with `#[graphql_interface(ignore)]` attribute,
|
||||
/// Returns [`None`] if the trait method marked with `#[graphql(ignore)]` attribute,
|
||||
/// or parsing fails.
|
||||
#[must_use]
|
||||
fn parse(method: &mut syn::TraitItemMethod) -> Option<Self> {
|
||||
|
@ -369,10 +369,10 @@ impl TraitMethod {
|
|||
// Remove repeated attributes from the method, to omit incorrect expansion.
|
||||
method.attrs = mem::take(&mut method.attrs)
|
||||
.into_iter()
|
||||
.filter(|attr| !path_eq_single(&attr.path, "graphql_interface"))
|
||||
.filter(|attr| !path_eq_single(&attr.path, "graphql"))
|
||||
.collect();
|
||||
|
||||
let meta = MethodMeta::from_attrs("graphql_interface", &method_attrs)
|
||||
let meta = MethodMeta::from_attrs("graphql", &method_attrs)
|
||||
.map_err(|e| proc_macro_error::emit_error!(e))
|
||||
.ok()?;
|
||||
|
||||
|
@ -514,10 +514,10 @@ impl TraitMethod {
|
|||
// Remove repeated attributes from the method, to omit incorrect expansion.
|
||||
argument.attrs = mem::take(&mut argument.attrs)
|
||||
.into_iter()
|
||||
.filter(|attr| !path_eq_single(&attr.path, "graphql_interface"))
|
||||
.filter(|attr| !path_eq_single(&attr.path, "graphql"))
|
||||
.collect();
|
||||
|
||||
let meta = ArgumentMeta::from_attrs("graphql_interface", &argument_attrs)
|
||||
let meta = ArgumentMeta::from_attrs("graphql", &argument_attrs)
|
||||
.map_err(|e| proc_macro_error::emit_error!(e))
|
||||
.ok()?;
|
||||
|
||||
|
@ -551,8 +551,8 @@ impl TraitMethod {
|
|||
"trait method argument should be declared as a single identifier",
|
||||
)
|
||||
.note(String::from(
|
||||
"use `#[graphql_interface(name = ...)]` attribute to specify custom argument's \
|
||||
name without requiring it being a single identifier",
|
||||
"use `#[graphql(name = ...)]` attribute to specify custom argument's name without \
|
||||
requiring it being a single identifier",
|
||||
))
|
||||
.emit();
|
||||
return None;
|
||||
|
@ -598,7 +598,7 @@ fn err_disallowed_attr<T, S: Spanned>(span: &S, arg: &str) -> Option<T> {
|
|||
ERR.custom(
|
||||
span.span(),
|
||||
format!(
|
||||
"attribute argument `#[graphql_interface({} = ...)]` is not allowed here",
|
||||
"attribute argument `#[graphql({} = ...)]` is not allowed here",
|
||||
arg,
|
||||
),
|
||||
)
|
||||
|
@ -663,8 +663,8 @@ fn err_duplicate_downcast(
|
|||
),
|
||||
)
|
||||
.note(String::from(
|
||||
"use `#[graphql_interface(ignore)]` attribute argument to ignore this trait method for \
|
||||
interface implementers downcasting",
|
||||
"use `#[graphql(ignore)]` attribute argument to ignore this trait method for interface \
|
||||
implementers downcasting",
|
||||
))
|
||||
.emit()
|
||||
}
|
||||
|
|
|
@ -367,7 +367,7 @@ impl ImplMeta {
|
|||
}
|
||||
}
|
||||
|
||||
/// Available metadata (arguments) behind `#[graphql_interface]` attribute placed on a trait method
|
||||
/// Available metadata (arguments) behind `#[graphql]` attribute placed on a trait method
|
||||
/// definition, when generating code for [GraphQL interface][1] type.
|
||||
///
|
||||
/// [1]: https://spec.graphql.org/June2018/#sec-Interfaces
|
||||
|
@ -534,8 +534,8 @@ impl MethodMeta {
|
|||
}
|
||||
}
|
||||
|
||||
/// Available metadata (arguments) behind `#[graphql_interface]` attribute placed on a trait method
|
||||
/// argument, when generating code for [GraphQL interface][1] type.
|
||||
/// Available metadata (arguments) behind `#[graphql]` attribute placed on a trait method argument,
|
||||
/// when generating code for [GraphQL interface][1] type.
|
||||
///
|
||||
/// [1]: https://spec.graphql.org/June2018/#sec-Interfaces
|
||||
#[derive(Debug, Default)]
|
||||
|
|
|
@ -115,21 +115,21 @@ fn parse_variant_from_trait_method(
|
|||
// Remove repeated attributes from the method, to omit incorrect expansion.
|
||||
method.attrs = mem::take(&mut method.attrs)
|
||||
.into_iter()
|
||||
.filter(|attr| !path_eq_single(&attr.path, "graphql_union"))
|
||||
.filter(|attr| !path_eq_single(&attr.path, "graphql"))
|
||||
.collect();
|
||||
|
||||
let meta = UnionVariantMeta::from_attrs("graphql_union", &method_attrs)
|
||||
let meta = UnionVariantMeta::from_attrs("graphql", &method_attrs)
|
||||
.map_err(|e| proc_macro_error::emit_error!(e))
|
||||
.ok()?;
|
||||
|
||||
if let Some(rslvr) = meta.external_resolver {
|
||||
ERR.custom(
|
||||
rslvr.span_ident(),
|
||||
"cannot use #[graphql_union(with = ...)] attribute on a trait method",
|
||||
"cannot use #[graphql(with = ...)] attribute on a trait method",
|
||||
)
|
||||
.note(String::from(
|
||||
"instead use #[graphql_union(ignore)] on the method with \
|
||||
#[graphql_union(on ... = ...)] on the trait itself",
|
||||
"instead use #[graphql(ignore)] on the method with #[graphql_union(on ... = ...)] on \
|
||||
the trait itself",
|
||||
))
|
||||
.emit()
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ fn parse_variant_from_trait_method(
|
|||
),
|
||||
)
|
||||
.note(String::from(
|
||||
"use `#[graphql_union(ignore)]` attribute to ignore this trait method for union \
|
||||
"use `#[graphql(ignore)]` attribute to ignore this trait method for union \
|
||||
variants resolution",
|
||||
))
|
||||
.emit();
|
||||
|
|
|
@ -638,12 +638,12 @@ pub fn graphql_subscription(args: TokenStream, input: TokenStream) -> TokenStrea
|
|||
/// #
|
||||
/// #[graphql_interface(name = "Character", desc = "Possible episode characters.")]
|
||||
/// trait Chrctr {
|
||||
/// #[graphql_interface(name = "id", desc = "ID of the character.")]
|
||||
/// #[graphql_interface(deprecated = "Don't use it")]
|
||||
/// #[graphql(name = "id", desc = "ID of the character.")]
|
||||
/// #[graphql(deprecated = "Don't use it")]
|
||||
/// fn some_id(
|
||||
/// &self,
|
||||
/// #[graphql_interface(name = "number", desc = "Arbitrary number.")]
|
||||
/// #[graphql_interface(default = 5)]
|
||||
/// #[graphql(name = "number", desc = "Arbitrary number.")]
|
||||
/// #[graphql(default = 5)]
|
||||
/// num: i32,
|
||||
/// ) -> &str;
|
||||
/// }
|
||||
|
@ -654,7 +654,7 @@ pub fn graphql_subscription(args: TokenStream, input: TokenStream) -> TokenStrea
|
|||
/// trait CharacterWithDocs {
|
||||
/// /// ID of the character.
|
||||
/// #[deprecated]
|
||||
/// fn id(&self, #[graphql_interface(default)] num: i32) -> &str;
|
||||
/// fn id(&self, #[graphql(default)] num: i32) -> &str;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
|
@ -683,7 +683,7 @@ pub fn graphql_subscription(args: TokenStream, input: TokenStream) -> TokenStrea
|
|||
/// #[graphql_interface(for = [Human, Droid], Context = Database)]
|
||||
/// trait Character {
|
||||
/// fn id<'db>(&self, ctx: &'db Database) -> Option<&'db str>;
|
||||
/// fn info<'db>(&self, #[graphql_interface(context)] db: &'db Database) -> Option<&'db str>;
|
||||
/// fn info<'db>(&self, #[graphql(context)] db: &'db Database) -> Option<&'db str>;
|
||||
/// }
|
||||
///
|
||||
/// #[derive(GraphQLObject)]
|
||||
|
@ -739,7 +739,7 @@ pub fn graphql_subscription(args: TokenStream, input: TokenStream) -> TokenStrea
|
|||
///
|
||||
/// async fn name<'b>(
|
||||
/// &'b self,
|
||||
/// #[graphql_interface(executor)] another: &Executor<'_, '_, (), S>,
|
||||
/// #[graphql(executor)] another: &Executor<'_, '_, (), S>,
|
||||
/// ) -> &'b str
|
||||
/// where
|
||||
/// S: Send + Sync;
|
||||
|
@ -825,7 +825,7 @@ pub fn graphql_subscription(args: TokenStream, input: TokenStream) -> TokenStrea
|
|||
/// trait Character {
|
||||
/// fn id(&self) -> &str;
|
||||
///
|
||||
/// #[graphql_interface(ignore)] // or `#[graphql_interface(skip)]`, your choice
|
||||
/// #[graphql(ignore)] // or `#[graphql(skip)]`, your choice
|
||||
/// fn kaboom(&mut self);
|
||||
/// }
|
||||
/// ```
|
||||
|
@ -856,7 +856,7 @@ pub fn graphql_subscription(args: TokenStream, input: TokenStream) -> TokenStrea
|
|||
/// trait Character {
|
||||
/// fn id(&self) -> &str;
|
||||
///
|
||||
/// #[graphql_interface(downcast)] // makes method a downcast to `Human`, not a field
|
||||
/// #[graphql(downcast)] // makes method a downcast to `Human`, not a field
|
||||
/// // NOTICE: The method signature may optionally contain `&Database` context argument.
|
||||
/// fn as_human(&self) -> Option<&Human> {
|
||||
/// None
|
||||
|
@ -1423,7 +1423,7 @@ pub fn derive_union(input: TokenStream) -> TokenStream {
|
|||
/// trait Character {
|
||||
/// fn as_human(&self) -> Option<&Human> { None }
|
||||
/// fn as_droid(&self) -> Option<&Droid> { None }
|
||||
/// #[graphql_union(ignore)] // or `#[graphql_union(skip)]`, your choice
|
||||
/// #[graphql(ignore)] // or `#[graphql(skip)]`, your choice
|
||||
/// fn id(&self) -> &str;
|
||||
/// }
|
||||
/// #
|
||||
|
@ -1471,7 +1471,7 @@ pub fn derive_union(input: TokenStream) -> TokenStream {
|
|||
/// on Droid = get_droid,
|
||||
/// )]
|
||||
/// trait Character {
|
||||
/// #[graphql_union(ignore)]
|
||||
/// #[graphql(ignore)]
|
||||
/// fn id(&self) -> &str;
|
||||
/// }
|
||||
///
|
||||
|
|
Loading…
Reference in a new issue