Skip to content

Commit

Permalink
Implement #[derive(GraphQLInterface)] to use structs as GraphQL int…
Browse files Browse the repository at this point in the history
…erfaces (#1026)

- support `#[graphql_interface]` on structs
  • Loading branch information
ilslv committed Apr 1, 2022
1 parent 744b808 commit d0b56f9
Show file tree
Hide file tree
Showing 125 changed files with 6,537 additions and 384 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
error[E0277]: the trait bound `ObjectA: IsInputType<__S>` is not satisfied
--> fail/input-object/derive_incompatible_object.rs:6:10
|
6 | #[derive(juniper::GraphQLInputObject)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `IsInputType<__S>` is not implemented for `ObjectA`
--> fail/input-object/derive_incompatible_object.rs:8:12
|
= note: this error originates in the derive macro `juniper::GraphQLInputObject` (in Nightly builds, run with -Z macro-backtrace for more info)
8 | field: ObjectA,
| ^^^^^^^ the trait `IsInputType<__S>` is not implemented for `ObjectA`

error[E0277]: the trait bound `ObjectA: FromInputValue<__S>` is not satisfied
--> fail/input-object/derive_incompatible_object.rs:6:10
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
error: GraphQL interface #[graphql_interface] attribute is applicable to trait and struct definitions only
--> fail/interface/attr_wrong_item.rs:9:1
|
9 | enum Character {}
| ^^^^^^^^^^^^^^^^^
12 changes: 12 additions & 0 deletions integration_tests/codegen_fail/fail/interface/derive_wrong_item.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use juniper::{GraphQLInterface, GraphQLObject};

#[derive(GraphQLObject)]
pub struct ObjA {
test: String,
}

#[derive(GraphQLInterface)]
#[graphql(for = ObjA)]
enum Character {}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
error: GraphQL interface can only be derived on structs
--> fail/interface/derive_wrong_item.rs:9:1
|
9 | / #[graphql(for = ObjA)]
10 | | enum Character {}
| |_________________^

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use juniper::{graphql_interface, graphql_object};

pub struct ObjA {
id: String,
}

#[graphql_object(impl = CharacterValue)]
impl ObjA {
fn id(&self, is_present: bool) -> &str {
is_present.then(|| self.id.as_str()).unwrap_or("missing")
}
}

#[graphql_interface(for = ObjA)]
struct Character {
id: String,
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_additional_non_nullable_argument.rs:16:5
|
16 | id: String,
| ^^ the evaluated program panicked at 'Failed to implement interface `Character` on `ObjA`: Field `id`: Argument `isPresent` of type `Boolean!` isn't present on the interface and so has to be nullable.', $DIR/fail/interface/struct/attr_additional_non_nullable_argument.rs:16:5
|
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use juniper::graphql_interface;

#[graphql_interface]
struct Character {
__id: String,
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
error: All types and directives defined within a schema must not have a name which begins with `__` (two underscores), as this is used exclusively by GraphQL’s introspection system.
--> fail/interface/struct/attr_field_double_underscored.rs:5:5
|
5 | __id: String,
| ^^^^
|
= note: https://spec.graphql.org/June2018/#sec-Schema
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use juniper::{graphql_interface, GraphQLInputObject};

#[derive(GraphQLInputObject)]
pub struct ObjB {
id: i32,
}

#[graphql_interface]
struct Character {
id: ObjB,
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
error[E0277]: the trait bound `ObjB: IsOutputType<__S>` is not satisfied
--> fail/interface/struct/attr_field_non_output_return_type.rs:10:9
|
10 | id: ObjB,
| ^^^^ the trait `IsOutputType<__S>` is not implemented for `ObjB`
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use juniper::graphql_interface;

#[graphql_interface]
struct Character {
id: String,

#[graphql(name = "id")]
id2: String,
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error: GraphQL interface must have a different name for each field
--> fail/interface/struct/attr_fields_duplicate.rs:4:1
|
4 | / struct Character {
5 | | id: String,
6 | |
7 | | #[graphql(name = "id")]
8 | | id2: String,
9 | | }
| |_^
|
= note: https://spec.graphql.org/June2018/#sec-Interfaces
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use juniper::{graphql_interface, GraphQLObject};

#[derive(GraphQLObject)]
#[graphql(impl = CharacterValue)]
pub struct ObjA {
id: String,
}

#[graphql_interface(for = [ObjA, ObjA])]
struct Character {
id: String,
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error: duplicated attribute argument found
--> fail/interface/struct/attr_implementers_duplicate_pretty.rs:9:34
|
9 | #[graphql_interface(for = [ObjA, ObjA])]
| ^^^^

error[E0412]: cannot find type `CharacterValue` in this scope
--> fail/interface/struct/attr_implementers_duplicate_pretty.rs:4:18
|
4 | #[graphql(impl = CharacterValue)]
| ^^^^^^^^^^^^^^ not found in this scope
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use juniper::{graphql_interface, GraphQLObject};

#[derive(GraphQLObject)]
#[graphql(impl = CharacterValue)]
pub struct ObjA {
id: String,
}

type ObjAlias = ObjA;

#[graphql_interface(for = [ObjA, ObjAlias])]
struct Character {
id: String,
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0119]: conflicting implementations of trait `std::convert::From<ObjA>` for type `CharacterValueEnum<ObjA, ObjA>`
--> fail/interface/struct/attr_implementers_duplicate_ugly.rs:11:1
|
11 | #[graphql_interface(for = [ObjA, ObjAlias])]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| first implementation here
| conflicting implementation for `CharacterValueEnum<ObjA, ObjA>`
|
= note: this error originates in the attribute macro `graphql_interface` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0119]: conflicting implementations of trait `<CharacterValueEnum<ObjA, ObjA> as juniper::GraphQLInterface<__S>>::mark::_::{closure#0}::MutuallyExclusive` for type `ObjA`
--> fail/interface/struct/attr_implementers_duplicate_ugly.rs:11:1
|
11 | #[graphql_interface(for = [ObjA, ObjAlias])]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| first implementation here
| conflicting implementation for `ObjA`
|
= note: this error originates in the macro `::juniper::sa::assert_type_ne_all` (in Nightly builds, run with -Z macro-backtrace for more info)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use juniper::{graphql_interface, GraphQLObject};

#[derive(GraphQLObject)]
#[graphql(impl = CharacterValue)]
pub struct ObjA {
test: String,
}

#[graphql_interface(for = ObjA)]
struct Character {
id: String,
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ the evaluated program panicked at 'Failed to implement interface `Character` on `ObjA`: Field `id` isn't implemented on `ObjA`.', $DIR/fail/interface/struct/attr_missing_field.rs:11:5
|
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use juniper::{graphql_interface, GraphQLObject};

#[derive(GraphQLObject)]
#[graphql(impl = CharacterValue)]
pub struct ObjA {
id: String,
}

#[graphql_interface]
struct Character {
id: String,
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_for_attr.rs:3:10
|
3 | #[derive(GraphQLObject)]
| ^^^^^^^^^^^^^ the evaluated program panicked at 'Failed to implement interface `Character` on `ObjA`: missing implementer reference in interface's `for` attribute.', $DIR/fail/interface/struct/attr_missing_for_attr.rs:3:10
|
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ use juniper::{graphql_interface, GraphQLObject};

#[derive(GraphQLObject)]
pub struct ObjA {
test: String,
id: String,
}

#[graphql_interface(for = ObjA)]
impl ObjA {}
struct Character {
id: String,
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_impl_attr.rs:8:1
|
8 | #[graphql_interface(for = ObjA)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'Failed to implement interface `Character` on `ObjA`: missing interface reference in implementer's `impl` attribute.', $DIR/fail/interface/struct/attr_missing_impl_attr.rs:8:1
|
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use juniper::graphql_interface;

#[graphql_interface]
struct __Character {
id: String,
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
error: All types and directives defined within a schema must not have a name which begins with `__` (two underscores), as this is used exclusively by GraphQL’s introspection system.
--> fail/interface/struct/attr_name_double_underscored.rs:4:8
|
4 | struct __Character {
| ^^^^^^^^^^^
|
= note: https://spec.graphql.org/June2018/#sec-Schema
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use juniper::graphql_interface;

#[graphql_interface]
struct Character {}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
error: GraphQL interface must have at least one field
--> fail/interface/struct/attr_no_fields.rs:4:1
|
4 | struct Character {}
| ^^^^^^^^^^^^^^^^^^^
|
= note: https://spec.graphql.org/June2018/#sec-Interfaces
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use juniper::{graphql_interface, GraphQLObject};

#[derive(GraphQLObject)]
#[graphql(impl = CharacterValue)]
pub struct ObjA {
id: Vec<String>,
}

#[graphql_interface(for = ObjA)]
struct Character {
id: String,
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_non_subtype_return.rs:11:5
|
11 | id: String,
| ^^ the evaluated program panicked at 'Failed to implement interface `Character` on `ObjA`: Field `id`: implementor is expected to return a subtype of interface's return object: `[String!]!` is not a subtype of `String!`.', $DIR/fail/interface/struct/attr_non_subtype_return.rs:11:5
|
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use juniper::graphql_interface;

#[graphql_interface]
struct Character(i32);

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
error: GraphQL interface expected named struct field
--> fail/interface/struct/attr_unnamed_field.rs:4:18
|
4 | struct Character(i32);
| ^^^
|
= note: https://spec.graphql.org/June2018/#sec-Interfaces
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use juniper::{graphql_object, GraphQLInterface};

pub struct ObjA {
id: String,
}

#[graphql_object(impl = CharacterValue)]
impl ObjA {
fn id(&self, is_present: bool) -> &str {
is_present.then(|| self.id.as_str()).unwrap_or("missing")
}
}

#[derive(GraphQLInterface)]
#[graphql(for = ObjA)]
struct Character {
id: String,
}

fn main() {}
Loading

0 comments on commit d0b56f9

Please sign in to comment.