Merge branch master into rework-core-traits [skip ci]

This commit is contained in:
tyranron 2022-06-27 14:28:17 +02:00
commit 2e2d365d64
No known key found for this signature in database
GPG key ID: 762E144FB230A4F0
62 changed files with 7413 additions and 649 deletions

View file

@ -21,8 +21,7 @@ jobs:
################ ################
pr: pr:
if: ${{ github.event_name == 'pull_request' if: ${{ github.event_name == 'pull_request' }}
&& !contains(github.event.head_commit.message, '[skip ci]') }}
needs: needs:
- clippy - clippy
- example - example
@ -43,9 +42,6 @@ jobs:
########################## ##########################
clippy: clippy:
if: ${{ github.ref == 'refs/heads/master'
|| startsWith(github.ref, 'refs/tags/juniper')
|| !contains(github.event.head_commit.message, '[skip ci]') }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@ -58,9 +54,6 @@ jobs:
- run: make cargo.lint - run: make cargo.lint
rustfmt: rustfmt:
if: ${{ github.ref == 'refs/heads/master'
|| startsWith(github.ref, 'refs/tags/juniper')
|| !contains(github.event.head_commit.message, '[skip ci]') }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@ -80,9 +73,6 @@ jobs:
########### ###########
example: example:
if: ${{ github.ref == 'refs/heads/master'
|| startsWith(github.ref, 'refs/tags/juniper')
|| !contains(github.event.head_commit.message, '[skip ci]') }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@ -111,9 +101,6 @@ jobs:
- run: cargo check -p example_${{ matrix.example }} - run: cargo check -p example_${{ matrix.example }}
feature: feature:
if: ${{ github.ref == 'refs/heads/master'
|| startsWith(github.ref, 'refs/tags/juniper')
|| !contains(github.event.head_commit.message, '[skip ci]') }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@ -174,9 +161,6 @@ jobs:
- run: cargo package -p ${{ steps.crate.outputs.NAME }} - run: cargo package -p ${{ steps.crate.outputs.NAME }}
test: test:
if: ${{ github.ref == 'refs/heads/master'
|| startsWith(github.ref, 'refs/tags/juniper')
|| !contains(github.event.head_commit.message, '[skip ci]') }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@ -230,9 +214,6 @@ jobs:
- run: make test.cargo crate=${{ matrix.crate }} - run: make test.cargo crate=${{ matrix.crate }}
wasm: wasm:
if: ${{ github.ref == 'refs/heads/master'
|| startsWith(github.ref, 'refs/tags/juniper')
|| !contains(github.event.head_commit.message, '[skip ci]') }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@ -264,9 +245,7 @@ jobs:
release-check: release-check:
name: Check release automation name: Check release automation
if: ${{ !startsWith(github.ref, 'refs/tags/juniper') if: ${{ !startsWith(github.ref, 'refs/tags/juniper') }}
&& (github.ref == 'refs/heads/master'
|| !contains(github.event.head_commit.message, '[skip ci]')) }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:

View file

@ -77,6 +77,190 @@ struct Human {
``` ```
### Interfaces implementing other interfaces
GraphQL allows implementing interfaces on other interfaces in addition to objects.
```rust
# extern crate juniper;
use juniper::{graphql_interface, graphql_object, ID};
#[graphql_interface(for = [HumanValue, Luke])]
struct Node {
id: ID,
}
#[graphql_interface(impl = NodeValue, for = Luke)]
struct Human {
id: ID,
home_planet: String,
}
struct Luke {
id: ID,
}
#[graphql_object(impl = [HumanValue, NodeValue])]
impl Luke {
fn id(&self) -> &ID {
&self.id
}
// As `String` and `&str` aren't distinguished by
// GraphQL spec, you can use them interchangeably.
// Same is applied for `Cow<'a, str>`.
// ⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄
fn home_planet() -> &'static str {
"Tatooine"
}
}
#
# fn main() {}
```
> __NOTE:__ Every interface has to specify all other interfaces/objects it implements or implemented for. Missing one of `for = ` or `impl = ` attributes is a compile-time error.
```compile_fail
# extern crate juniper;
use juniper::{graphql_interface, GraphQLObject};
#[derive(GraphQLObject)]
pub struct ObjA {
id: String,
}
#[graphql_interface(for = ObjA)]
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at
// 'Failed to implement interface `Character` on `ObjA`: missing interface reference in implementer's `impl` attribute.'
struct Character {
id: String,
}
fn main() {}
```
### GraphQL subtyping and additional `null`able fields
GraphQL allows implementers (both objects and other interfaces) to return "subtypes" instead of an original value. Basically, this allows you to impose additional bounds on the implementation.
Valid "subtypes" are:
- interface implementer instead of an interface itself:
- `I implements T` in place of a `T`;
- `Vec<I implements T>` in place of a `Vec<T>`.
- non-null value in place of a nullable:
- `T` in place of a `Option<T>`;
- `Vec<T>` in place of a `Vec<Option<T>>`.
These rules are recursively applied, so `Vec<Vec<I implements T>>` is a valid "subtype" of a `Option<Vec<Option<Vec<Option<T>>>>>`.
Also, GraphQL allows implementers to add `null`able fields, which aren't present on an original interface.
```rust
# extern crate juniper;
use juniper::{graphql_interface, graphql_object, ID};
#[graphql_interface(for = [HumanValue, Luke])]
struct Node {
id: ID,
}
#[graphql_interface(for = HumanConnectionValue)]
struct Connection {
nodes: Vec<NodeValue>,
}
#[graphql_interface(impl = NodeValue, for = Luke)]
struct Human {
id: ID,
home_planet: String,
}
#[graphql_interface(impl = ConnectionValue)]
struct HumanConnection {
nodes: Vec<HumanValue>,
// ^^^^^^^^^^ notice not `NodeValue`
// This can happen, because every `Human` is a `Node` too, so we are just
// imposing additional bounds, which still can be resolved with
// `... on Connection { nodes }`.
}
struct Luke {
id: ID,
}
#[graphql_object(impl = [HumanValue, NodeValue])]
impl Luke {
fn id(&self) -> &ID {
&self.id
}
fn home_planet(language: Option<String>) -> &'static str {
// ^^^^^^^^^^^^^^
// Notice additional `null`able field, which is missing on `Human`.
// Resolving `...on Human { homePlanet }` will provide `None` for this
// argument.
match language.as_deref() {
None | Some("en") => "Tatooine",
Some("ko") => "타투인",
_ => todo!(),
}
}
}
#
# fn main() {}
```
Violating GraphQL "subtyping" or additional nullable field rules is a compile-time error.
```compile_fail
# extern crate juniper;
use juniper::{graphql_interface, graphql_object};
pub struct ObjA {
id: String,
}
#[graphql_object(impl = CharacterValue)]
impl ObjA {
fn id(&self, is_present: bool) -> &str {
// ^^ 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.'
is_present.then(|| self.id.as_str()).unwrap_or("missing")
}
}
#[graphql_interface(for = ObjA)]
struct Character {
id: String,
}
#
# fn main() {}
```
```compile_fail
# extern crate juniper;
use juniper::{graphql_interface, GraphQLObject};
#[derive(GraphQLObject)]
#[graphql(impl = CharacterValue)]
pub struct ObjA {
id: Vec<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!`.'
}
#[graphql_interface(for = ObjA)]
struct Character {
id: String,
}
#
# fn main() {}
```
### Ignoring trait methods ### Ignoring trait methods
We may want to omit some trait methods to be assumed as [GraphQL interface][1] fields and ignore them. We may want to omit some trait methods to be assumed as [GraphQL interface][1] fields and ignore them.

View file

@ -31,6 +31,7 @@ All user visible changes to `juniper` crate will be documented in this file. Thi
- Forbade default implementations of non-ignored trait methods. - Forbade default implementations of non-ignored trait methods.
- Supported coercion of additional `null`able arguments and return sub-typing on implementer. - Supported coercion of additional `null`able arguments and return sub-typing on implementer.
- Supported `rename_all = "<policy>"` attribute argument influencing all its fields and their arguments. ([#971]) - Supported `rename_all = "<policy>"` attribute argument influencing all its fields and their arguments. ([#971])
- Supported interfaces implementing other interfaces. ([#1028])
- Split `#[derive(GraphQLScalarValue)]` macro into: - Split `#[derive(GraphQLScalarValue)]` macro into:
- `#[derive(GraphQLScalar)]` for implementing GraphQL scalar: ([#1017]) - `#[derive(GraphQLScalar)]` for implementing GraphQL scalar: ([#1017])
- Supported generic `ScalarValue`. - Supported generic `ScalarValue`.
@ -94,6 +95,7 @@ All user visible changes to `juniper` crate will be documented in this file. Thi
[#1017]: /../../pull/1017 [#1017]: /../../pull/1017
[#1025]: /../../pull/1025 [#1025]: /../../pull/1025
[#1026]: /../../pull/1026 [#1026]: /../../pull/1026
[#1028]: /../../pull/1028
[#1051]: /../../issues/1051 [#1051]: /../../issues/1051
[#1054]: /../../pull/1054 [#1054]: /../../pull/1054
[#1057]: /../../pull/1057 [#1057]: /../../pull/1057

View file

@ -38,7 +38,7 @@ schema-language = ["graphql-parser"]
anyhow = { version = "1.0.32", default-features = false, optional = true } anyhow = { version = "1.0.32", default-features = false, optional = true }
async-trait = "0.1.39" async-trait = "0.1.39"
bigdecimal = { version = "0.3", optional = true } bigdecimal = { version = "0.3", optional = true }
bson = { version = "2.0", features = ["chrono-0_4"], optional = true } bson = { version = "2.3", features = ["chrono-0_4"], optional = true }
chrono = { version = "0.4", features = ["alloc"], default-features = false, optional = true } chrono = { version = "0.4", features = ["alloc"], default-features = false, optional = true }
chrono-tz = { version = "0.6", default-features = false, optional = true } chrono-tz = { version = "0.6", default-features = false, optional = true }
fnv = "1.0.3" fnv = "1.0.3"

View file

@ -247,7 +247,7 @@ async fn interface_introspection() {
); );
assert_eq!( assert_eq!(
type_info.get_field_value("interfaces"), type_info.get_field_value("interfaces"),
Some(&graphql_value!(null)), Some(&graphql_value!([])),
); );
assert_eq!( assert_eq!(
type_info.get_field_value("enumValues"), type_info.get_field_value("enumValues"),

View file

@ -28,7 +28,10 @@ mod utc_date_time {
use super::*; use super::*;
pub(super) fn to_output<S: ScalarValue>(v: &UtcDateTime) -> Value<S> { pub(super) fn to_output<S: ScalarValue>(v: &UtcDateTime) -> Value<S> {
Value::scalar((*v).to_rfc3339_string()) Value::scalar(
(*v).try_to_rfc3339_string()
.unwrap_or_else(|e| panic!("failed to format `UtcDateTime` as RFC3339: {}", e)),
)
} }
pub(super) fn from_input<S: ScalarValue>(v: &InputValue<S>) -> Result<UtcDateTime, String> { pub(super) fn from_input<S: ScalarValue>(v: &InputValue<S>) -> Result<UtcDateTime, String> {

View file

@ -409,6 +409,38 @@ macro_rules! assert_interfaces_impls {
}; };
} }
/// Asserts that all [transitive interfaces][0] (the ones implemented by the
/// `$interface`) are also implemented by the `$implementor`.
///
/// [0]: https://spec.graphql.org/October2021#sel-FAHbhBHCAACGB35P
#[macro_export]
macro_rules! assert_transitive_impls {
($scalar: ty, $interface: ty, $implementor: ty $(, $transitive: ty)* $(,)?) => {
const _: () = {
$({
let is_present = $crate::macros::reflect::str_exists_in_arr(
<$implementor as ::juniper::macros::reflect::BaseType<$scalar>>::NAME,
<$transitive as ::juniper::macros::reflect::BaseSubTypes<$scalar>>::NAMES,
);
if !is_present {
const MSG: &str = $crate::const_concat!(
"Failed to implement interface `",
<$interface as $crate::macros::reflect::BaseType<$scalar>>::NAME,
"` on `",
<$implementor as $crate::macros::reflect::BaseType<$scalar>>::NAME,
"`: missing `impl = ` for transitive interface `",
<$transitive as $crate::macros::reflect::BaseType<$scalar>>::NAME,
"` on `",
<$implementor as $crate::macros::reflect::BaseType<$scalar>>::NAME,
"`."
);
::std::panic!("{}", MSG);
}
})*
};
};
}
/// Asserts validness of [`Field`] [`Arguments`] and returned [`Type`]. /// Asserts validness of [`Field`] [`Arguments`] and returned [`Type`].
/// ///
/// This assertion is a combination of [`assert_subtype`] and /// This assertion is a combination of [`assert_subtype`] and

View file

@ -5,7 +5,7 @@ use crate::behavior;
#[doc(inline)] #[doc(inline)]
pub use self::macros::{ pub use self::macros::{
assert_field, assert_field_args, assert_field_type, assert_has_field, assert_implemented_for, assert_field, assert_field_args, assert_field_type, assert_has_field, assert_implemented_for,
assert_interfaces_impls, const_concat, format_type, assert_interfaces_impls, assert_transitive_impls, const_concat, format_type,
}; };
/// Name of a [GraphQL type][0] in a GraphQL schema. /// Name of a [GraphQL type][0] in a GraphQL schema.
@ -332,8 +332,7 @@ mod macros {
#[macro_export] #[macro_export]
macro_rules! reflect_assert_implemented_for { macro_rules! reflect_assert_implemented_for {
($behavior: ty, $implementor: ty $(, $interfaces: ty)* $(,)?) => { ($behavior: ty, $implementor: ty $(, $interfaces: ty)* $(,)?) => {
const _: () = { const _: () = { $({
$({
let is_present = $crate::reflect::str_exists_in_arr( let is_present = $crate::reflect::str_exists_in_arr(
<$implementor as $crate::reflect::BaseType<$behavior>>::NAME, <$implementor as $crate::reflect::BaseType<$behavior>>::NAME,
<$interfaces as $crate::reflect::BaseSubTypes<$behavior>>::NAMES, <$interfaces as $crate::reflect::BaseSubTypes<$behavior>>::NAMES,
@ -348,8 +347,7 @@ mod macros {
); );
::std::panic!("{}", MSG); ::std::panic!("{}", MSG);
} }
})* })* };
};
}; };
} }
@ -360,8 +358,7 @@ mod macros {
#[macro_export] #[macro_export]
macro_rules! reflect_assert_interfaces_impls { macro_rules! reflect_assert_interfaces_impls {
($behavior: ty, $interface: ty $(, $implementers: ty)* $(,)?) => { ($behavior: ty, $interface: ty $(, $implementers: ty)* $(,)?) => {
const _: () = { const _: () = { $({
$({
let is_present = $crate::reflect::str_exists_in_arr( let is_present = $crate::reflect::str_exists_in_arr(
<$interface as $crate::reflect::BaseType<$behavior>>::NAME, <$interface as $crate::reflect::BaseType<$behavior>>::NAME,
<$implementers as $crate::reflect::Implements<$behavior>>::NAMES, <$implementers as $crate::reflect::Implements<$behavior>>::NAMES,
@ -376,8 +373,37 @@ mod macros {
); );
::std::panic!("{}", MSG); ::std::panic!("{}", MSG);
} }
})* })* };
}; };
}
/// Asserts that all [transitive interfaces][0] (the ones implemented by the
/// `$interface`) are also implemented by the `$implementor`.
///
/// [0]: https://spec.graphql.org/October2021#sel-FAHbhBHCAACGB35P
#[macro_export]
macro_rules! reflect_assert_transitive_impls {
($behavior: ty, $interface: ty, $implementor: ty $(, $transitive: ty)* $(,)?) => {
const _: () = { $({
let is_present = $crate::reflect::str_exists_in_arr(
<$implementor as $crate::reflect::BaseType<$behavior>>::NAME,
<$transitive as $crate::reflect::BaseSubTypes<$behavior>>::NAMES,
);
if !is_present {
const MSG: &str = $crate::reflect::const_concat!(
"Failed to implement interface `",
<$interface as $crate::reflect::BaseType<$behavior>>::NAME,
"` on `",
<$implementor as $crate::reflect::BaseType<$behavior>>::NAME,
"`: missing `impl = ` for transitive interface `",
<$transitive as $crate::reflect::BaseType<$behavior>>::NAME,
"` on `",
<$implementor as $crate::reflect::BaseType<$behavior>>::NAME,
"`.",
);
::std::panic!("{}", MSG);
}
})* };
}; };
} }
@ -843,6 +869,7 @@ mod macros {
reflect_assert_has_field as assert_has_field, reflect_assert_has_field as assert_has_field,
reflect_assert_implemented_for as assert_implemented_for, reflect_assert_implemented_for as assert_implemented_for,
reflect_assert_interfaces_impls as assert_interfaces_impls, reflect_assert_interfaces_impls as assert_interfaces_impls,
reflect_assert_transitive_impls as assert_transitive_impls,
reflect_const_concat as const_concat, reflect_format_type as format_type, reflect_const_concat as const_concat, reflect_format_type as format_type,
}; };
} }

View file

@ -137,6 +137,8 @@ pub struct InterfaceMeta<'a, S> {
pub description: Option<String>, pub description: Option<String>,
#[doc(hidden)] #[doc(hidden)]
pub fields: Vec<Field<'a, S>>, pub fields: Vec<Field<'a, S>>,
#[doc(hidden)]
pub interface_names: Vec<String>,
} }
/// Union type metadata /// Union type metadata
@ -675,6 +677,7 @@ impl<'a, S> InterfaceMeta<'a, S> {
name, name,
description: None, description: None,
fields: fields.to_vec(), fields: fields.to_vec(),
interface_names: Vec::new(),
} }
} }
@ -687,6 +690,18 @@ impl<'a, S> InterfaceMeta<'a, S> {
self self
} }
/// Sets the `interfaces` this [`InterfaceMeta`] interface implements.
///
/// Overwrites any previously set list of interfaces.
#[must_use]
pub fn interfaces(mut self, interfaces: &[Type<'a>]) -> Self {
self.interface_names = interfaces
.iter()
.map(|t| t.innermost_name().to_owned())
.collect();
self
}
/// Wraps this [`InterfaceMeta`] type into a generic [`MetaType`]. /// Wraps this [`InterfaceMeta`] type into a generic [`MetaType`].
pub fn into_meta(self) -> MetaType<'a, S> { pub fn into_meta(self) -> MetaType<'a, S> {
MetaType::Interface(self) MetaType::Interface(self)

View file

@ -244,10 +244,16 @@ impl<'a, S: ScalarValue + 'a> TypeType<'a, S> {
fn interfaces<'s>(&self, context: &'s SchemaType<'a, S>) -> Option<Vec<TypeType<'s, S>>> { fn interfaces<'s>(&self, context: &'s SchemaType<'a, S>) -> Option<Vec<TypeType<'s, S>>> {
match self { match self {
TypeType::Concrete(&MetaType::Object(ObjectMeta { TypeType::Concrete(
&MetaType::Object(ObjectMeta {
ref interface_names, ref interface_names,
.. ..
})) => Some( })
| &MetaType::Interface(InterfaceMeta {
ref interface_names,
..
}),
) => Some(
interface_names interface_names
.iter() .iter()
.filter_map(|n| context.type_by_name(n)) .filter_map(|n| context.type_by_name(n))

View file

@ -190,8 +190,11 @@ impl GraphQLParserTranslator {
position: Pos::default(), position: Pos::default(),
description: x.description.as_ref().map(|s| From::from(s.as_str())), description: x.description.as_ref().map(|s| From::from(s.as_str())),
name: From::from(x.name.as_ref()), name: From::from(x.name.as_ref()),
// TODO: Support this with GraphQL October 2021 Edition. implements_interfaces: x
implements_interfaces: vec![], .interface_names
.iter()
.map(|s| From::from(s.as_str()))
.collect(),
directives: vec![], directives: vec![],
fields: x fields: x
.fields .fields

View file

@ -1173,7 +1173,7 @@ pub(crate) fn schema_introspection_result() -> Value {
} }
], ],
"inputFields": null, "inputFields": null,
"interfaces": null, "interfaces": [],
"enumValues": null, "enumValues": null,
"possibleTypes": [ "possibleTypes": [
{ {
@ -2500,7 +2500,7 @@ pub(crate) fn schema_introspection_result_without_descriptions() -> Value {
} }
], ],
"inputFields": null, "inputFields": null,
"interfaces": null, "interfaces": [],
"enumValues": null, "enumValues": null,
"possibleTypes": [ "possibleTypes": [
{ {

View file

@ -2,6 +2,7 @@ use std::fmt::Debug;
use crate::{ use crate::{
ast::{Definition, Document, FragmentSpread, InlineFragment}, ast::{Definition, Document, FragmentSpread, InlineFragment},
meta::InterfaceMeta,
parser::Spanning, parser::Spanning,
schema::meta::MetaType, schema::meta::MetaType,
validation::{ValidatorContext, Visitor}, validation::{ValidatorContext, Visitor},
@ -45,6 +46,23 @@ where
.as_ref() .as_ref()
.and_then(|s| ctx.schema.concrete_type_by_name(s.item)), .and_then(|s| ctx.schema.concrete_type_by_name(s.item)),
) { ) {
// Even if there is no object type in the overlap of interfaces
// implementers, it's OK to spread in case `frag_type` implements
// `parent_type`.
// https://spec.graphql.org/October2021#sel-JALVFJNRDABABqDy5B
if let MetaType::Interface(InterfaceMeta {
interface_names, ..
}) = frag_type
{
let implements_parent = parent_type
.name()
.map(|parent| interface_names.iter().any(|i| i == parent))
.unwrap_or_default();
if implements_parent {
return;
}
}
if !ctx.schema.type_overlap(parent_type, frag_type) { if !ctx.schema.type_overlap(parent_type, frag_type) {
ctx.report_error( ctx.report_error(
&error_message( &error_message(
@ -67,6 +85,23 @@ where
ctx.parent_type(), ctx.parent_type(),
self.fragment_types.get(spread.item.name.item), self.fragment_types.get(spread.item.name.item),
) { ) {
// Even if there is no object type in the overlap of interfaces
// implementers, it's OK to spread in case `frag_type` implements
// `parent_type`.
// https://spec.graphql.org/October2021/#sel-JALVFJNRDABABqDy5B
if let MetaType::Interface(InterfaceMeta {
interface_names, ..
}) = frag_type
{
let implements_parent = parent_type
.name()
.map(|parent| interface_names.iter().any(|i| i == parent))
.unwrap_or_default();
if implements_parent {
return;
}
}
if !ctx.schema.type_overlap(parent_type, frag_type) { if !ctx.schema.type_overlap(parent_type, frag_type) {
ctx.report_error( ctx.report_error(
&error_message( &error_message(
@ -226,6 +261,27 @@ mod tests {
); );
} }
#[test]
fn no_object_overlap_but_implements_parent() {
expect_passes_rule::<_, _, DefaultScalarValue>(
factory,
r#"
fragment beingFragment on Being { ...unpopulatedFragment }
fragment unpopulatedFragment on Unpopulated { name }
"#,
);
}
#[test]
fn no_object_overlap_but_implements_parent_inline() {
expect_passes_rule::<_, _, DefaultScalarValue>(
factory,
r#"
fragment beingFragment on Being { ...on Unpopulated { name } }
"#,
);
}
#[test] #[test]
fn different_object_into_object() { fn different_object_into_object() {
expect_fails_rule::<_, _, DefaultScalarValue>( expect_fails_rule::<_, _, DefaultScalarValue>(

View file

@ -20,6 +20,7 @@ use crate::{
struct Being; struct Being;
struct Pet; struct Pet;
struct Canine; struct Canine;
struct Unpopulated;
struct Dog; struct Dog;
struct Cat; struct Cat;
@ -167,6 +168,41 @@ where
} }
} }
impl<S> GraphQLType<S> for Unpopulated
where
S: ScalarValue,
{
fn name(_: &()) -> Option<&'static str> {
Some("Unpopulated")
}
fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S>
where
S: 'r,
{
let fields = &[registry
.field::<Option<String>>("name", i)
.argument(registry.arg::<Option<bool>>("surname", i))];
registry
.build_interface_type::<Self>(i, fields)
.interfaces(&[registry.get_type::<Being>(i)])
.into_meta()
}
}
impl<S> GraphQLValue<S> for Unpopulated
where
S: ScalarValue,
{
type Context = ();
type TypeInfo = ();
fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> {
<Self as GraphQLType>::name(info)
}
}
impl<S> GraphQLType<S> for DogCommand impl<S> GraphQLType<S> for DogCommand
where where
S: ScalarValue, S: ScalarValue,
@ -777,6 +813,8 @@ where
where where
S: 'r, S: 'r,
{ {
let _ = registry.get_type::<Unpopulated>(i);
let fields = [registry.field::<i32>("testInput", i).argument( let fields = [registry.field::<i32>("testInput", i).argument(
registry.arg_with_default::<TestInput>( registry.arg_with_default::<TestInput>(
"input", "input",

View file

@ -1,153 +0,0 @@
use proc_macro2::TokenStream;
use quote::quote;
use syn::{ext::IdentExt, spanned::Spanned, Data, Fields};
use crate::{
result::{GraphQLScope, UnsupportedAttribute},
util::{self, span_container::SpanContainer, RenameRule},
};
pub fn impl_enum(ast: syn::DeriveInput, error: GraphQLScope) -> syn::Result<TokenStream> {
let ast_span = ast.span();
if !ast.generics.params.is_empty() {
return Err(error.custom_error(ast_span, "does not support generics or lifetimes"));
}
let variants = match ast.data {
Data::Enum(enum_data) => enum_data.variants,
_ => return Err(error.custom_error(ast_span, "can only be applied to enums")),
};
// Parse attributes.
let attrs = util::ObjectAttributes::from_attrs(&ast.attrs)?;
let ident = &ast.ident;
let name = attrs
.name
.clone()
.map(SpanContainer::into_inner)
.unwrap_or_else(|| ident.unraw().to_string());
let fields = variants
.into_iter()
.filter_map(|field| {
let span = field.span();
let field_attrs = match util::FieldAttributes::from_attrs(
&field.attrs,
util::FieldAttributeParseMode::Object,
) {
Ok(attrs) => attrs,
Err(err) => {
proc_macro_error::emit_error!(err);
return None;
}
};
let field_name = field.ident;
let name = field_attrs
.name
.clone()
.map(SpanContainer::into_inner)
.unwrap_or_else(|| {
attrs
.rename
.unwrap_or(RenameRule::ScreamingSnakeCase)
.apply(&field_name.unraw().to_string())
});
let resolver_code = quote!( #ident::#field_name );
let _type = match field.fields {
Fields::Unit => syn::parse_str(&field_name.to_string()).unwrap(),
_ => {
error.emit_custom(
field.fields.span(),
"all fields of the enum must be unnamed, e.g., None",
);
return None;
}
};
if let Some(skip) = field_attrs.skip {
error.unsupported_attribute(skip.span(), UnsupportedAttribute::Skip);
return None;
}
if name.starts_with("__") {
error.no_double_underscore(if let Some(name) = field_attrs.name {
name.span_ident()
} else {
field_name.span()
});
}
if let Some(default) = field_attrs.default {
error.unsupported_attribute_within(
default.span_ident(),
UnsupportedAttribute::Default,
);
}
Some(util::GraphQLTypeDefinitionField {
name,
_type,
args: Vec::new(),
description: field_attrs.description.map(SpanContainer::into_inner),
deprecation: field_attrs.deprecation.map(SpanContainer::into_inner),
resolver_code,
is_type_inferred: true,
is_async: false,
default: None,
span,
})
})
.collect::<Vec<_>>();
proc_macro_error::abort_if_dirty();
if fields.is_empty() {
error.not_empty(ast_span);
}
if let Some(duplicates) =
crate::util::duplicate::Duplicate::find_by_key(&fields, |field| &field.name)
{
error.duplicate(duplicates.iter())
}
if !attrs.interfaces.is_empty() {
attrs.interfaces.iter().for_each(|elm| {
error.unsupported_attribute(elm.span(), UnsupportedAttribute::Interface)
});
}
if let Some(scalar) = attrs.scalar {
error.unsupported_attribute(scalar.span_ident(), UnsupportedAttribute::Scalar);
}
if !attrs.is_internal && name.starts_with("__") {
error.no_double_underscore(if let Some(name) = attrs.name {
name.span_ident()
} else {
ident.span()
});
}
proc_macro_error::abort_if_dirty();
let definition = util::GraphQLTypeDefiniton {
name,
_type: syn::parse_str(&ast.ident.to_string()).unwrap(),
context: attrs.context.map(SpanContainer::into_inner),
scalar: None,
description: attrs.description.map(SpanContainer::into_inner),
fields,
// NOTICE: only unit variants allow -> no generics possible
generics: syn::Generics::default(),
interfaces: vec![],
include_type_generics: true,
generic_scalar: true,
no_async: attrs.no_async.is_some(),
};
Ok(definition.into_enum_tokens())
}

View file

@ -0,0 +1,147 @@
//! Code generation for `#[derive(GraphQLEnum)]` macro.
use proc_macro2::TokenStream;
use quote::ToTokens as _;
use std::collections::HashSet;
use syn::{ext::IdentExt as _, parse_quote, spanned::Spanned};
use crate::{
common::scalar,
result::GraphQLScope,
util::{span_container::SpanContainer, RenameRule},
};
use super::{ContainerAttr, Definition, ValueDefinition, VariantAttr};
/// [`GraphQLScope`] of errors for `#[derive(GraphQLEnum)]` macro.
const ERR: GraphQLScope = GraphQLScope::EnumDerive;
/// Expands `#[derive(GraphQLEnum)]` macro into generated code.
pub(crate) fn expand(input: TokenStream) -> syn::Result<TokenStream> {
let ast = syn::parse2::<syn::DeriveInput>(input)?;
let attr = ContainerAttr::from_attrs("graphql", &ast.attrs)?;
let data = if let syn::Data::Enum(data) = &ast.data {
data
} else {
return Err(ERR.custom_error(ast.span(), "can only be derived on enums"));
};
let mut has_ignored_variants = false;
let renaming = attr
.rename_values
.map(SpanContainer::into_inner)
.unwrap_or(RenameRule::ScreamingSnakeCase);
let values = data
.variants
.iter()
.filter_map(|v| {
parse_value(v, renaming).or_else(|| {
has_ignored_variants = true;
None
})
})
.collect::<Vec<_>>();
proc_macro_error::abort_if_dirty();
if values.is_empty() {
return Err(ERR.custom_error(
data.variants.span(),
"expected at least 1 non-ignored enum variant",
));
}
let unique_values = values.iter().map(|v| &v.name).collect::<HashSet<_>>();
if unique_values.len() != values.len() {
return Err(ERR.custom_error(
data.variants.span(),
"expected all GraphQL enum values to have unique names",
));
}
let name = attr
.name
.clone()
.map(SpanContainer::into_inner)
.unwrap_or_else(|| ast.ident.unraw().to_string())
.into_boxed_str();
if !attr.is_internal && name.starts_with("__") {
ERR.no_double_underscore(
attr.name
.as_ref()
.map(SpanContainer::span_ident)
.unwrap_or_else(|| ast.ident.span()),
);
}
let context = attr
.context
.map_or_else(|| parse_quote! { () }, SpanContainer::into_inner);
let description = attr.description.map(|d| d.into_inner().into_boxed_str());
let scalar = scalar::Type::parse(attr.scalar.as_deref(), &ast.generics);
proc_macro_error::abort_if_dirty();
let definition = Definition {
ident: ast.ident,
generics: ast.generics,
name,
description,
context,
scalar,
values,
has_ignored_variants,
};
Ok(definition.into_token_stream())
}
/// Parses a [`ValueDefinition`] from the given Rust enum variant definition.
///
/// Returns [`None`] if the parsing fails, or the enum variant is ignored.
fn parse_value(v: &syn::Variant, renaming: RenameRule) -> Option<ValueDefinition> {
let attr = VariantAttr::from_attrs("graphql", &v.attrs)
.map_err(|e| proc_macro_error::emit_error!(e))
.ok()?;
if attr.ignore.is_some() {
return None;
}
if !v.fields.is_empty() {
err_variant_with_fields(&v.fields)?;
}
let name = attr
.name
.map_or_else(
|| renaming.apply(&v.ident.unraw().to_string()),
SpanContainer::into_inner,
)
.into_boxed_str();
let description = attr.description.map(|d| d.into_inner().into_boxed_str());
let deprecated = attr.deprecated.map(|desc| {
desc.into_inner()
.as_ref()
.map(|lit| lit.value().into_boxed_str())
});
Some(ValueDefinition {
ident: v.ident.clone(),
name,
description,
deprecated,
})
}
/// Emits "no fields allowed for non-ignored variants" [`syn::Error`] pointing
/// to the given `span`.
pub fn err_variant_with_fields<T, S: Spanned>(span: &S) -> Option<T> {
ERR.emit_custom(span.span(), "no fields allowed for non-ignored variants");
None
}

View file

@ -0,0 +1,790 @@
//! Code generation for [GraphQL enums][0].
//!
//! [0]: https://spec.graphql.org/October2021#sec-Enums
pub(crate) mod derive;
use std::convert::TryInto as _;
use proc_macro2::TokenStream;
use quote::{format_ident, quote, ToTokens};
use syn::{
ext::IdentExt as _,
parse::{Parse, ParseStream},
parse_quote,
spanned::Spanned as _,
token,
};
use crate::{
common::{
parse::{
attr::{err, OptionExt as _},
ParseBufferExt as _,
},
scalar,
},
util::{
filter_attrs, get_deprecated, get_doc_comment, span_container::SpanContainer, RenameRule,
},
};
/// Available arguments behind `#[graphql]` attribute placed on a Rust enum
/// definition, when generating code for a [GraphQL enum][0] type.
///
/// [0]: https://spec.graphql.org/October2021#sec-Enums
#[derive(Debug, Default)]
struct ContainerAttr {
/// Explicitly specified name of this [GraphQL enum][0].
///
/// If [`None`], then Rust enum name will be used by default.
///
/// [0]: https://spec.graphql.org/October2021#sec-Enums
name: Option<SpanContainer<String>>,
/// Explicitly specified [description][2] of this [GraphQL enum][0].
///
/// If [`None`], then Rust doc comment will be used as [description][2], if
/// any.
///
/// [0]: https://spec.graphql.org/October2021#sec-Enums
/// [2]: https://spec.graphql.org/October2021#sec-Descriptions
description: Option<SpanContainer<String>>,
/// Explicitly specified type of [`Context`] to use for resolving this
/// [GraphQL enum][0] type with.
///
/// If [`None`], then unit type `()` is assumed as a type of [`Context`].
///
/// [`Context`]: juniper::Context
/// [0]: https://spec.graphql.org/October2021#sec-Enums
context: Option<SpanContainer<syn::Type>>,
/// Explicitly specified type (or type parameter with its bounds) of
/// [`ScalarValue`] to resolve this [GraphQL enum][0] type with.
///
/// If [`None`], then generated code will be generic over any
/// [`ScalarValue`] type.
///
/// [`GraphQLType`]: juniper::GraphQLType
/// [`ScalarValue`]: juniper::ScalarValue
/// [0]: https://spec.graphql.org/October2021#sec-Enums
scalar: Option<SpanContainer<scalar::AttrValue>>,
/// Explicitly specified [`RenameRule`] for all [values][1] of this
/// [GraphQL enum][0].
///
/// If [`None`], then the [`RenameRule::ScreamingSnakeCase`] rule will be
/// applied by default.
///
/// [0]: https://spec.graphql.org/October2021#sec-Enums
/// [1]: https://spec.graphql.org/October2021#EnumValuesDefinition
rename_values: Option<SpanContainer<RenameRule>>,
/// Indicator whether the generated code is intended to be used only inside
/// the [`juniper`] library.
is_internal: bool,
}
impl Parse for ContainerAttr {
fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
let mut out = Self::default();
while !input.is_empty() {
let ident = input.parse_any_ident()?;
match ident.to_string().as_str() {
"name" => {
input.parse::<token::Eq>()?;
let name = input.parse::<syn::LitStr>()?;
out.name
.replace(SpanContainer::new(
ident.span(),
Some(name.span()),
name.value(),
))
.none_or_else(|_| err::dup_arg(&ident))?
}
"desc" | "description" => {
input.parse::<token::Eq>()?;
let desc = input.parse::<syn::LitStr>()?;
out.description
.replace(SpanContainer::new(
ident.span(),
Some(desc.span()),
desc.value(),
))
.none_or_else(|_| err::dup_arg(&ident))?
}
"ctx" | "context" | "Context" => {
input.parse::<token::Eq>()?;
let ctx = input.parse::<syn::Type>()?;
out.context
.replace(SpanContainer::new(ident.span(), Some(ctx.span()), ctx))
.none_or_else(|_| err::dup_arg(&ident))?
}
"scalar" | "Scalar" | "ScalarValue" => {
input.parse::<token::Eq>()?;
let scl = input.parse::<scalar::AttrValue>()?;
out.scalar
.replace(SpanContainer::new(ident.span(), Some(scl.span()), scl))
.none_or_else(|_| err::dup_arg(&ident))?
}
"rename_all" => {
input.parse::<token::Eq>()?;
let val = input.parse::<syn::LitStr>()?;
out.rename_values
.replace(SpanContainer::new(
ident.span(),
Some(val.span()),
val.try_into()?,
))
.none_or_else(|_| err::dup_arg(&ident))?;
}
"internal" => {
out.is_internal = true;
}
name => {
return Err(err::unknown_arg(&ident, name));
}
}
input.try_parse::<token::Comma>()?;
}
Ok(out)
}
}
impl ContainerAttr {
/// Tries to merge two [`ContainerAttr`]s into a single one, reporting about
/// duplicates, if any.
fn try_merge(self, mut another: Self) -> syn::Result<Self> {
Ok(Self {
name: try_merge_opt!(name: self, another),
description: try_merge_opt!(description: self, another),
context: try_merge_opt!(context: self, another),
scalar: try_merge_opt!(scalar: self, another),
rename_values: try_merge_opt!(rename_values: self, another),
is_internal: self.is_internal || another.is_internal,
})
}
/// Parses [`ContainerAttr`] from the given multiple `name`d
/// [`syn::Attribute`]s placed on a trait definition.
fn from_attrs(name: &str, attrs: &[syn::Attribute]) -> syn::Result<Self> {
let mut attr = filter_attrs(name, attrs)
.map(|attr| attr.parse_args())
.try_fold(Self::default(), |prev, curr| prev.try_merge(curr?))?;
if attr.description.is_none() {
attr.description = get_doc_comment(attrs);
}
Ok(attr)
}
}
/// Available arguments behind `#[graphql]` attribute when generating code for
/// a [GraphQL enum][0]'s [value][1].
///
/// [0]: https://spec.graphql.org/October2021#sec-Enums
/// [1]: https://spec.graphql.org/October2021#sec-Enum-Value
#[derive(Debug, Default)]
struct VariantAttr {
/// Explicitly specified name of this [GraphQL enum value][1].
///
/// If [`None`], then Rust enum variant's name is used by default.
///
/// [1]: https://spec.graphql.org/October2021#sec-Enum-Value
name: Option<SpanContainer<String>>,
/// Explicitly specified [description][2] of this [GraphQL enum value][1].
///
/// If [`None`], then Rust doc comment is used as [description][2], if any.
///
/// [1]: https://spec.graphql.org/October2021#sec-Enum-Value
/// [2]: https://spec.graphql.org/October2021#sec-Descriptions
description: Option<SpanContainer<String>>,
/// Explicitly specified [deprecation][2] of this [GraphQL enum value][1].
///
/// If [`None`], then Rust `#[deprecated]` attribute is used as the
/// [deprecation][2], if any.
///
/// If the inner [`Option`] is [`None`], then no [reason][3] was provided.
///
/// [1]: https://spec.graphql.org/October2021#sec-Enum-Value
/// [2]: https://spec.graphql.org/October2021#sec--deprecated
/// [3]: https://spec.graphql.org/October2021#sel-GAHnBZDACEDDGAA_6L
deprecated: Option<SpanContainer<Option<syn::LitStr>>>,
/// Explicitly specified marker for the Rust enum variant to be ignored and
/// not included into the code generated for a [GraphQL enum][0]
/// implementation.
///
/// [0]: https://spec.graphql.org/October20210#sec-Enums
ignore: Option<SpanContainer<syn::Ident>>,
}
impl Parse for VariantAttr {
fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
let mut out = Self::default();
while !input.is_empty() {
let ident = input.parse_any_ident()?;
match ident.to_string().as_str() {
"name" => {
input.parse::<token::Eq>()?;
let name = input.parse::<syn::LitStr>()?;
out.name
.replace(SpanContainer::new(
ident.span(),
Some(name.span()),
name.value(),
))
.none_or_else(|_| err::dup_arg(&ident))?
}
"desc" | "description" => {
input.parse::<token::Eq>()?;
let desc = input.parse::<syn::LitStr>()?;
out.description
.replace(SpanContainer::new(
ident.span(),
Some(desc.span()),
desc.value(),
))
.none_or_else(|_| err::dup_arg(&ident))?
}
"deprecated" => {
let mut reason = None;
if input.is_next::<token::Eq>() {
input.parse::<token::Eq>()?;
reason = Some(input.parse::<syn::LitStr>()?);
}
out.deprecated
.replace(SpanContainer::new(
ident.span(),
reason.as_ref().map(|r| r.span()),
reason,
))
.none_or_else(|_| err::dup_arg(&ident))?
}
"ignore" | "skip" => out
.ignore
.replace(SpanContainer::new(ident.span(), None, ident.clone()))
.none_or_else(|_| err::dup_arg(&ident))?,
name => {
return Err(err::unknown_arg(&ident, name));
}
}
input.try_parse::<token::Comma>()?;
}
Ok(out)
}
}
impl VariantAttr {
/// Tries to merge two [`VariantAttr`]s into a single one, reporting about
/// duplicates, if any.
fn try_merge(self, mut another: Self) -> syn::Result<Self> {
Ok(Self {
name: try_merge_opt!(name: self, another),
description: try_merge_opt!(description: self, another),
deprecated: try_merge_opt!(deprecated: self, another),
ignore: try_merge_opt!(ignore: self, another),
})
}
/// Parses [`VariantAttr`] from the given multiple `name`d
/// [`syn::Attribute`]s placed on a trait definition.
fn from_attrs(name: &str, attrs: &[syn::Attribute]) -> syn::Result<Self> {
let mut attr = filter_attrs(name, attrs)
.map(|attr| attr.parse_args())
.try_fold(Self::default(), |prev, curr| prev.try_merge(curr?))?;
if attr.description.is_none() {
attr.description = get_doc_comment(attrs);
}
if attr.deprecated.is_none() {
attr.deprecated = get_deprecated(attrs).map(|sc| {
let span = sc.span_ident();
sc.map(|depr| depr.reason.map(|rsn| syn::LitStr::new(&rsn, span)))
});
}
Ok(attr)
}
}
/// Representation of a [GraphQL enum value][1] for code generation.
///
/// [1]: https://spec.graphql.org/October2021#sec-Enum-Value
#[derive(Debug)]
struct ValueDefinition {
/// [`Ident`] of the Rust enum variant behind this [GraphQL enum value][1].
///
/// [`Ident`]: syn::Ident
/// [1]: https://spec.graphql.org/October2021#sec-Enum-Value
ident: syn::Ident,
/// Name of this [GraphQL enum value][1] in GraphQL schema.
///
/// [1]: https://spec.graphql.org/October2021#sec-Enum-Value
name: Box<str>,
/// [Description][2] of this [GraphQL enum value][1] to put into GraphQL
/// schema.
///
/// [1]: https://spec.graphql.org/October2021#sec-Enum-Value
/// [2]: https://spec.graphql.org/October2021#sec-Descriptions
description: Option<Box<str>>,
/// [Deprecation][2] of this [GraphQL enum value][1] to put into GraphQL
/// schema.
///
/// If the inner [`Option`] is [`None`], then [deprecation][2] has no
/// [reason][3] attached.
///
/// [1]: https://spec.graphql.org/October2021#sec-Enum-Value
/// [2]: https://spec.graphql.org/October2021#sec--deprecated
/// [3]: https://spec.graphql.org/October2021#sel-GAHnBZDACEDDGAA_6L
deprecated: Option<Option<Box<str>>>,
}
/// Representation of a [GraphQL enum][0] for code generation.
///
/// [0]: https://spec.graphql.org/October2021#sec-Enums
struct Definition {
/// [`Ident`] of the Rust enum behind this [GraphQL enum][0].
///
/// [0]: https://spec.graphql.org/October2021#sec-Enums
ident: syn::Ident,
/// [`syn::Generics`] of the Rust enum behind this [GraphQL enum][0].
///
/// [0]: https://spec.graphql.org/October2021#sec-Enums
generics: syn::Generics,
/// Name of this [GraphQL enum][0] in GraphQL schema.
///
/// [0]: https://spec.graphql.org/October2021#sec-Enums
name: Box<str>,
/// [Description][2] of this [GraphQL enum][0] to put into GraphQL schema.
///
/// [0]: https://spec.graphql.org/October2021#sec-Enums
/// [2]: https://spec.graphql.org/October2021#sec-Descriptions
description: Option<Box<str>>,
/// Rust type of [`Context`] to generate [`GraphQLType`] implementation with
/// for this [GraphQL enum][0].
///
/// [`GraphQLType`]: juniper::GraphQLType
/// [`Context`]: juniper::Context
/// [0]: https://spec.graphql.org/October2021#sec-Enums
context: syn::Type,
/// [`ScalarValue`] parametrization to generate [`GraphQLType`]
/// implementation with for this [GraphQL enum][0].
///
/// [`GraphQLType`]: juniper::GraphQLType
/// [`ScalarValue`]: juniper::ScalarValue
/// [0]: https://spec.graphql.org/October2021#sec-Enums
scalar: scalar::Type,
/// [Values][1] of this [GraphQL enum][0].
///
/// [0]: https://spec.graphql.org/October2021#sec-Enums
/// [1]: https://spec.graphql.org/October2021#EnumValuesDefinition
values: Vec<ValueDefinition>,
/// Indicates whether the Rust enum behind this [GraphQL enum][0] contains
/// ignored variants.
///
/// [0]: https://spec.graphql.org/October2021#sec-Enums
has_ignored_variants: bool,
}
impl ToTokens for Definition {
fn to_tokens(&self, into: &mut TokenStream) {
self.impl_input_and_output_type_tokens().to_tokens(into);
self.impl_graphql_type_tokens().to_tokens(into);
self.impl_graphql_value_tokens().to_tokens(into);
self.impl_graphql_value_async_tokens().to_tokens(into);
self.impl_from_input_value_tokens().to_tokens(into);
self.impl_to_input_value_tokens().to_tokens(into);
self.impl_reflection_traits_tokens().to_tokens(into);
}
}
impl Definition {
/// Returns generated code implementing [`marker::IsOutputType`] trait for
/// this [GraphQL enum][0].
///
/// [`marker::IsOutputType`]: juniper::marker::IsOutputType
/// [0]: https://spec.graphql.org/October2021#sec-Enums
fn impl_input_and_output_type_tokens(&self) -> TokenStream {
let ident = &self.ident;
let scalar = &self.scalar;
let generics = self.impl_generics(false);
let (impl_generics, _, where_clause) = generics.split_for_impl();
let (_, ty_generics, _) = self.generics.split_for_impl();
quote! {
#[automatically_derived]
impl#impl_generics ::juniper::marker::IsInputType<#scalar>
for #ident#ty_generics
#where_clause {}
#[automatically_derived]
impl#impl_generics ::juniper::marker::IsOutputType<#scalar>
for #ident#ty_generics
#where_clause {}
}
}
/// Returns generated code implementing [`GraphQLType`] trait for this
/// [GraphQL enum][0].
///
/// [`GraphQLType`]: juniper::GraphQLType
/// [0]: https://spec.graphql.org/October2021#sec-Enums
fn impl_graphql_type_tokens(&self) -> TokenStream {
let ident = &self.ident;
let scalar = &self.scalar;
let generics = self.impl_generics(false);
let (impl_generics, _, where_clause) = generics.split_for_impl();
let (_, ty_generics, _) = self.generics.split_for_impl();
let name = &self.name;
let description = self
.description
.as_ref()
.map(|desc| quote! { .description(#desc) });
let variants_meta = self.values.iter().map(|v| {
let name = &v.name;
let description = v.description.as_ref().map_or_else(
|| quote! { None },
|desc| quote! { Some(String::from(#desc)) },
);
let deprecation_status = match &v.deprecated {
None => quote! { ::juniper::meta::DeprecationStatus::Current },
Some(None) => quote! {
::juniper::meta::DeprecationStatus::Deprecated(None)
},
Some(Some(reason)) => {
quote! {
::juniper::meta::DeprecationStatus::Deprecated(
Some(String::from(#reason))
)
}
}
};
quote! {
::juniper::meta::EnumValue {
name: String::from(#name),
description: #description,
deprecation_status: #deprecation_status,
}
}
});
quote! {
#[automatically_derived]
impl#impl_generics ::juniper::GraphQLType<#scalar>
for #ident#ty_generics
#where_clause
{
fn name(_ : &Self::TypeInfo) -> Option<&'static str> {
Some(#name)
}
fn meta<'r>(
info: &Self::TypeInfo,
registry: &mut ::juniper::Registry<'r, #scalar>
) -> ::juniper::meta::MetaType<'r, #scalar>
where #scalar: 'r,
{
let variants = [#( #variants_meta ),*];
registry.build_enum_type::<#ident#ty_generics>(info, &variants)
#description
.into_meta()
}
}
}
}
/// Returns generated code implementing [`GraphQLValue`] trait for this
/// [GraphQL enum][0].
///
/// [`GraphQLValue`]: juniper::GraphQLValue
/// [0]: https://spec.graphql.org/October2021#sec-Enums
fn impl_graphql_value_tokens(&self) -> TokenStream {
let ident = &self.ident;
let scalar = &self.scalar;
let context = &self.context;
let generics = self.impl_generics(false);
let (impl_generics, _, where_clause) = generics.split_for_impl();
let (_, ty_generics, _) = self.generics.split_for_impl();
let variants = self.values.iter().map(|v| {
let ident = &v.ident;
let name = &v.name;
quote! {
Self::#ident => Ok(::juniper::Value::scalar(String::from(#name))),
}
});
let ignored = self.has_ignored_variants.then(|| {
quote! {
_ => Err(::juniper::FieldError::<#scalar>::from(
"Cannot resolve ignored enum variant",
)),
}
});
quote! {
impl#impl_generics ::juniper::GraphQLValue<#scalar>
for #ident#ty_generics
#where_clause
{
type Context = #context;
type TypeInfo = ();
fn type_name<'__i>(&self, info: &'__i Self::TypeInfo) -> Option<&'__i str> {
<Self as ::juniper::GraphQLType<#scalar>>::name(info)
}
fn resolve(
&self,
_: &(),
_: Option<&[::juniper::Selection<#scalar>]>,
_: &::juniper::Executor<Self::Context, #scalar>,
) -> ::juniper::ExecutionResult<#scalar> {
match self {
#( #variants )*
#ignored
}
}
}
}
}
/// Returns generated code implementing [`GraphQLValueAsync`] trait for this
/// [GraphQL enum][0].
///
/// [`GraphQLValueAsync`]: juniper::GraphQLValueAsync
/// [0]: https://spec.graphql.org/October2021#sec-Enums
fn impl_graphql_value_async_tokens(&self) -> TokenStream {
let ident = &self.ident;
let scalar = &self.scalar;
let generics = self.impl_generics(true);
let (impl_generics, _, where_clause) = generics.split_for_impl();
let (_, ty_generics, _) = self.generics.split_for_impl();
quote! {
impl#impl_generics ::juniper::GraphQLValueAsync<#scalar>
for #ident#ty_generics
#where_clause
{
fn resolve_async<'__a>(
&'__a self,
info: &'__a Self::TypeInfo,
selection_set: Option<&'__a [::juniper::Selection<#scalar>]>,
executor: &'__a ::juniper::Executor<Self::Context, #scalar>,
) -> ::juniper::BoxFuture<'__a, ::juniper::ExecutionResult<#scalar>> {
let v = ::juniper::GraphQLValue::resolve(self, info, selection_set, executor);
Box::pin(::juniper::futures::future::ready(v))
}
}
}
}
/// Returns generated code implementing [`FromInputValue`] trait for this
/// [GraphQL enum][0].
///
/// [`FromInputValue`]: juniper::FromInputValue
/// [0]: https://spec.graphql.org/October2021#sec-Enums
fn impl_from_input_value_tokens(&self) -> TokenStream {
let ident = &self.ident;
let scalar = &self.scalar;
let generics = self.impl_generics(false);
let (impl_generics, _, where_clause) = generics.split_for_impl();
let (_, ty_generics, _) = self.generics.split_for_impl();
let variants = self.values.iter().map(|v| {
let ident = &v.ident;
let name = &v.name;
quote! {
Some(#name) => Ok(Self::#ident),
}
});
quote! {
impl#impl_generics ::juniper::FromInputValue<#scalar>
for #ident#ty_generics
#where_clause
{
type Error = ::std::string::String;
fn from_input_value(v: &::juniper::InputValue<#scalar>) -> Result<Self, Self::Error> {
match v.as_enum_value().or_else(|| v.as_string_value()) {
#( #variants )*
_ => Err(::std::format!("Unknown enum value: {}", v)),
}
}
}
}
}
/// Returns generated code implementing [`ToInputValue`] trait for this
/// [GraphQL enum][0].
///
/// [`ToInputValue`]: juniper::ToInputValue
/// [0]: https://spec.graphql.org/October2021#sec-Enums
fn impl_to_input_value_tokens(&self) -> TokenStream {
let ident = &self.ident;
let scalar = &self.scalar;
let generics = self.impl_generics(false);
let (impl_generics, _, where_clause) = generics.split_for_impl();
let (_, ty_generics, _) = self.generics.split_for_impl();
let variants = self.values.iter().map(|v| {
let var_ident = &v.ident;
let name = &v.name;
quote! {
#ident::#var_ident => ::juniper::InputValue::<#scalar>::scalar(
String::from(#name),
),
}
});
let ignored = self.has_ignored_variants.then(|| {
quote! {
_ => panic!("Cannot resolve ignored enum variant"),
}
});
quote! {
impl#impl_generics ::juniper::ToInputValue<#scalar>
for #ident#ty_generics
#where_clause
{
fn to_input_value(&self) -> ::juniper::InputValue<#scalar> {
match self {
#( #variants )*
#ignored
}
}
}
}
}
/// Returns generated code implementing [`BaseType`], [`BaseSubTypes`] and
/// [`WrappedType`] traits for this [GraphQL enum][0].
///
/// [`BaseSubTypes`]: juniper::macros::reflect::BaseSubTypes
/// [`BaseType`]: juniper::macros::reflect::BaseType
/// [`WrappedType`]: juniper::macros::reflect::WrappedType
/// [0]: https://spec.graphql.org/October2021#sec-Enums
fn impl_reflection_traits_tokens(&self) -> TokenStream {
let ident = &self.ident;
let name = &self.name;
let scalar = &self.scalar;
let generics = self.impl_generics(false);
let (impl_generics, _, where_clause) = generics.split_for_impl();
let (_, ty_generics, _) = self.generics.split_for_impl();
quote! {
impl#impl_generics ::juniper::macros::reflect::BaseType<#scalar>
for #ident#ty_generics
#where_clause
{
const NAME: ::juniper::macros::reflect::Type = #name;
}
impl#impl_generics ::juniper::macros::reflect::BaseSubTypes<#scalar>
for #ident#ty_generics
#where_clause
{
const NAMES: ::juniper::macros::reflect::Types =
&[<Self as ::juniper::macros::reflect::BaseType<#scalar>>::NAME];
}
impl#impl_generics ::juniper::macros::reflect::WrappedType<#scalar>
for #ident#ty_generics
#where_clause
{
const VALUE: ::juniper::macros::reflect::WrappedValue = 1;
}
}
}
/// Returns prepared [`syn::Generics`] for [`GraphQLType`] trait (and
/// similar) implementation of this enum.
///
/// If `for_async` is `true`, then additional predicates are added to suit
/// the [`GraphQLAsyncValue`] trait (and similar) requirements.
///
/// [`GraphQLAsyncValue`]: juniper::GraphQLAsyncValue
/// [`GraphQLType`]: juniper::GraphQLType
fn impl_generics(&self, for_async: bool) -> syn::Generics {
let mut generics = self.generics.clone();
let scalar = &self.scalar;
if scalar.is_implicit_generic() {
generics.params.push(parse_quote! { #scalar });
}
if scalar.is_generic() {
generics
.make_where_clause()
.predicates
.push(parse_quote! { #scalar: ::juniper::ScalarValue });
}
if let Some(bound) = scalar.bounds() {
generics.make_where_clause().predicates.push(bound);
}
if for_async {
let self_ty = if self.generics.lifetimes().next().is_some() {
// Modify lifetime names to omit "lifetime name `'a` shadows a
// lifetime name that is already in scope" error.
let mut generics = self.generics.clone();
for lt in generics.lifetimes_mut() {
let ident = lt.lifetime.ident.unraw();
lt.lifetime.ident = format_ident!("__fa__{}", ident);
}
let lifetimes = generics.lifetimes().map(|lt| &lt.lifetime);
let ident = &self.ident;
let (_, ty_generics, _) = generics.split_for_impl();
quote! { for<#( #lifetimes ),*> #ident#ty_generics }
} else {
quote! { Self }
};
generics
.make_where_clause()
.predicates
.push(parse_quote! { #self_ty: Sync });
if scalar.is_generic() {
generics
.make_where_clause()
.predicates
.push(parse_quote! { #scalar: Send + Sync });
}
}
generics
}
}

View file

@ -55,7 +55,8 @@ fn expand_on_trait(
.name .name
.clone() .clone()
.map(SpanContainer::into_inner) .map(SpanContainer::into_inner)
.unwrap_or_else(|| trait_ident.unraw().to_string()); .unwrap_or_else(|| trait_ident.unraw().to_string())
.into_boxed_str();
if !attr.is_internal && name.starts_with("__") { if !attr.is_internal && name.starts_with("__") {
ERR.no_double_underscore( ERR.no_double_underscore(
attr.name attr.name
@ -120,18 +121,23 @@ fn expand_on_trait(
enum_ident, enum_ident,
enum_alias_ident, enum_alias_ident,
name, name,
description: attr.description.as_deref().cloned(), description: attr.description.map(|d| d.into_inner().into_boxed_str()),
context, context,
scalar, scalar,
behavior: attr.behavior.map(|bh| bh.into_inner()).unwrap_or_default(), behavior: attr.behavior.map(|bh| bh.into_inner()).unwrap_or_default(),
fields, fields,
implemented_for: attr implemented_for: attr
.implemented_for .implemented_for
.iter() .into_iter()
.map(|c| c.inner().clone()) .map(SpanContainer::into_inner)
.collect(),
implements: attr
.implements
.into_iter()
.map(SpanContainer::into_inner)
.collect(), .collect(),
suppress_dead_code: None, suppress_dead_code: None,
src_intra_doc_link: format!("trait@{}", trait_ident), src_intra_doc_link: format!("trait@{}", trait_ident).into_boxed_str(),
}; };
Ok(quote! { Ok(quote! {
@ -244,7 +250,8 @@ fn expand_on_derive_input(
.name .name
.clone() .clone()
.map(SpanContainer::into_inner) .map(SpanContainer::into_inner)
.unwrap_or_else(|| struct_ident.unraw().to_string()); .unwrap_or_else(|| struct_ident.unraw().to_string())
.into_boxed_str();
if !attr.is_internal && name.starts_with("__") { if !attr.is_internal && name.starts_with("__") {
ERR.no_double_underscore( ERR.no_double_underscore(
attr.name attr.name
@ -303,18 +310,23 @@ fn expand_on_derive_input(
enum_ident, enum_ident,
enum_alias_ident, enum_alias_ident,
name, name,
description: attr.description.as_deref().cloned(), description: attr.description.map(|d| d.into_inner().into_boxed_str()),
context, context,
scalar, scalar,
behavior: attr.behavior.map(|bh| bh.into_inner()).unwrap_or_default(), behavior: attr.behavior.map(|bh| bh.into_inner()).unwrap_or_default(),
fields, fields,
implemented_for: attr implemented_for: attr
.implemented_for .implemented_for
.iter() .into_iter()
.map(|c| c.inner().clone()) .map(SpanContainer::into_inner)
.collect(),
implements: attr
.implements
.into_iter()
.map(SpanContainer::into_inner)
.collect(), .collect(),
suppress_dead_code: None, suppress_dead_code: None,
src_intra_doc_link: format!("struct@{}", struct_ident), src_intra_doc_link: format!("struct@{}", struct_ident).into_boxed_str(),
}; };
Ok(quote! { Ok(quote! {

View file

@ -33,7 +33,8 @@ pub fn expand(input: TokenStream) -> syn::Result<TokenStream> {
.name .name
.clone() .clone()
.map(SpanContainer::into_inner) .map(SpanContainer::into_inner)
.unwrap_or_else(|| struct_ident.unraw().to_string()); .unwrap_or_else(|| struct_ident.unraw().to_string())
.into_boxed_str();
if !attr.is_internal && name.starts_with("__") { if !attr.is_internal && name.starts_with("__") {
ERR.no_double_underscore( ERR.no_double_underscore(
attr.name attr.name
@ -93,18 +94,23 @@ pub fn expand(input: TokenStream) -> syn::Result<TokenStream> {
enum_ident, enum_ident,
enum_alias_ident, enum_alias_ident,
name, name,
description: attr.description.as_deref().cloned(), description: attr.description.map(|d| d.into_inner().into_boxed_str()),
context, context,
scalar, scalar,
behavior: attr.behavior.map(|bh| bh.into_inner()).unwrap_or_default(), behavior: attr.behavior.map(|bh| bh.into_inner()).unwrap_or_default(),
fields, fields,
implemented_for: attr implemented_for: attr
.implemented_for .implemented_for
.iter() .into_iter()
.map(|c| c.inner().clone()) .map(SpanContainer::into_inner)
.collect(),
implements: attr
.implements
.into_iter()
.map(SpanContainer::into_inner)
.collect(), .collect(),
suppress_dead_code: Some((ast.ident.clone(), data.fields.clone())), suppress_dead_code: Some((ast.ident.clone(), data.fields.clone())),
src_intra_doc_link: format!("struct@{}", struct_ident), src_intra_doc_link: format!("struct@{}", struct_ident).into_boxed_str(),
} }
.into_token_stream()) .into_token_stream())
} }

View file

@ -81,13 +81,20 @@ struct Attr {
/// [1]: https://spec.graphql.org/June2018/#sec-Interfaces /// [1]: https://spec.graphql.org/June2018/#sec-Interfaces
r#enum: Option<SpanContainer<syn::Ident>>, r#enum: Option<SpanContainer<syn::Ident>>,
/// Explicitly specified Rust types of [GraphQL objects][2] implementing /// Explicitly specified Rust types of [GraphQL objects][2] or
/// this [GraphQL interface][1] type. /// [interfaces][1] implementing this [GraphQL interface][1] type.
/// ///
/// [1]: https://spec.graphql.org/June2018/#sec-Interfaces /// [1]: https://spec.graphql.org/June2018/#sec-Interfaces
/// [2]: https://spec.graphql.org/June2018/#sec-Objects /// [2]: https://spec.graphql.org/June2018/#sec-Objects
implemented_for: HashSet<SpanContainer<syn::TypePath>>, implemented_for: HashSet<SpanContainer<syn::TypePath>>,
/// Explicitly specified [GraphQL interfaces, implemented][1] by this
/// [GraphQL interface][0].
///
/// [0]: https://spec.graphql.org/October2021#sec-Interfaces
/// [1]: https://spec.graphql.org/October2021#sel-GAHbhBDABAB_E-0b
implements: HashSet<SpanContainer<syn::TypePath>>,
/// Explicitly specified type of [`Context`] to use for resolving this /// Explicitly specified type of [`Context`] to use for resolving this
/// [GraphQL interface][1] type with. /// [GraphQL interface][1] type with.
/// ///
@ -203,6 +210,18 @@ impl Parse for Attr {
.none_or_else(|_| err::dup_arg(impler_span))?; .none_or_else(|_| err::dup_arg(impler_span))?;
} }
} }
"impl" | "implements" => {
input.parse::<token::Eq>()?;
for iface in input.parse_maybe_wrapped_and_punctuated::<
syn::TypePath, token::Bracket, token::Comma,
>()? {
let iface_span = iface.span();
out
.implements
.replace(SpanContainer::new(ident.span(), Some(iface_span), iface))
.none_or_else(|_| err::dup_arg(iface_span))?;
}
}
"enum" => { "enum" => {
input.parse::<token::Eq>()?; input.parse::<token::Eq>()?;
let alias = input.parse::<syn::Ident>()?; let alias = input.parse::<syn::Ident>()?;
@ -251,6 +270,7 @@ impl Attr {
scalar: try_merge_opt!(scalar: self, another), scalar: try_merge_opt!(scalar: self, another),
behavior: try_merge_opt!(behavior: self, another), behavior: try_merge_opt!(behavior: self, another),
implemented_for: try_merge_hashset!(implemented_for: self, another => span_joined), implemented_for: try_merge_hashset!(implemented_for: self, another => span_joined),
implements: try_merge_hashset!(implements: self, another => span_joined),
r#enum: try_merge_opt!(r#enum: self, another), r#enum: try_merge_opt!(r#enum: self, another),
asyncness: try_merge_opt!(asyncness: self, another), asyncness: try_merge_opt!(asyncness: self, another),
rename_fields: try_merge_opt!(rename_fields: self, another), rename_fields: try_merge_opt!(rename_fields: self, another),
@ -302,15 +322,15 @@ struct Definition {
/// [`implementers`]: Self::implementers /// [`implementers`]: Self::implementers
enum_alias_ident: syn::Ident, enum_alias_ident: syn::Ident,
/// Name of this [GraphQL interface][1] in GraphQL schema. /// Name of this [GraphQL interface][0] in GraphQL schema.
/// ///
/// [1]: https://spec.graphql.org/June2018/#sec-Interfaces /// [0]: https://spec.graphql.org/October2021#sec-Interfaces
name: String, name: Box<str>,
/// Description of this [GraphQL interface][1] to put into GraphQL schema. /// Description of this [GraphQL interface][0] to put into GraphQL schema.
/// ///
/// [1]: https://spec.graphql.org/June2018/#sec-Interfaces /// [0]: https://spec.graphql.org/October2021#sec-Interfaces
description: Option<String>, description: Option<Box<str>>,
/// Rust type of [`Context`] to generate [`GraphQLType`] implementation with /// Rust type of [`Context`] to generate [`GraphQLType`] implementation with
/// for this [GraphQL interface][1]. /// for this [GraphQL interface][1].
@ -346,6 +366,12 @@ struct Definition {
/// [1]: https://spec.graphql.org/June2018/#sec-Interfaces /// [1]: https://spec.graphql.org/June2018/#sec-Interfaces
implemented_for: Vec<syn::TypePath>, implemented_for: Vec<syn::TypePath>,
/// [GraphQL interfaces implemented][1] by this [GraphQL interface][0].
///
/// [0]: https://spec.graphql.org/October2021#sec-Interfaces
/// [1]: https://spec.graphql.org/October2021#sel-GAHbhBDABAB_E-0b
implements: Vec<syn::TypePath>,
/// Unlike `#[graphql_interface]` maro, `#[derive(GraphQLInterface)]` can't /// Unlike `#[graphql_interface]` maro, `#[derive(GraphQLInterface)]` can't
/// append `#[allow(dead_code)]` to the unused struct, representing /// append `#[allow(dead_code)]` to the unused struct, representing
/// [GraphQL interface][1]. We generate hacky `const` which doesn't actually /// [GraphQL interface][1]. We generate hacky `const` which doesn't actually
@ -355,10 +381,10 @@ struct Definition {
suppress_dead_code: Option<(syn::Ident, syn::Fields)>, suppress_dead_code: Option<(syn::Ident, syn::Fields)>,
/// Intra-doc link to the [`syn::Item`] defining this /// Intra-doc link to the [`syn::Item`] defining this
/// [GraphQL interface][1]. /// [GraphQL interface][0].
/// ///
/// [1]: https://spec.graphql.org/June2018/#sec-Interfaces /// [0]: https://spec.graphql.org/October2021#sec-Interfaces
src_intra_doc_link: String, src_intra_doc_link: Box<str>,
} }
impl ToTokens for Definition { impl ToTokens for Definition {
@ -524,11 +550,6 @@ impl Definition {
let (impl_generics, _, where_clause) = gens.split_for_impl(); let (impl_generics, _, where_clause) = gens.split_for_impl();
let (_, ty_generics, _) = self.generics.split_for_impl(); let (_, ty_generics, _) = self.generics.split_for_impl();
let implemented_for = &self.implemented_for;
let all_impled_for_unique = (implemented_for.len() > 1).then(|| {
quote! { ::juniper::sa::assert_type_ne_all!(#( #implemented_for ),*); }
});
let suppress_dead_code = self.suppress_dead_code.as_ref().map(|(ident, fields)| { let suppress_dead_code = self.suppress_dead_code.as_ref().map(|(ident, fields)| {
let const_gens = self.const_trait_generics(); let const_gens = self.const_trait_generics();
let fields = fields.iter().map(|f| &f.ident); let fields = fields.iter().map(|f| &f.ident);
@ -547,6 +568,49 @@ impl Definition {
}} }}
}); });
let implemented_for = &self.implemented_for;
let all_impled_for_unique = (implemented_for.len() > 1).then(|| {
quote! { ::juniper::sa::assert_type_ne_all!(#( #implemented_for ),*); }
});
let mark_object_or_interface = self.implemented_for.iter().map(|impl_for| {
quote_spanned! { impl_for.span() =>
trait GraphQLObjectOrInterface<S: ::juniper::ScalarValue, T> {
fn mark();
}
{
struct Object;
impl<S, T> GraphQLObjectOrInterface<S, Object> for T
where
S: ::juniper::ScalarValue,
T: ::juniper::marker::GraphQLObject<S>,
{
fn mark() {
<T as ::juniper::marker::GraphQLObject<S>>::mark()
}
}
}
{
struct Interface;
impl<S, T> GraphQLObjectOrInterface<S, Interface> for T
where
S: ::juniper::ScalarValue,
T: ::juniper::marker::GraphQLInterface<S>,
{
fn mark() {
<T as ::juniper::marker::GraphQLInterface<S>>::mark()
}
}
}
<#impl_for as GraphQLObjectOrInterface<#scalar, _>>::mark();
}
});
quote! { quote! {
#[automatically_derived] #[automatically_derived]
impl#impl_generics ::juniper::marker::GraphQLInterface<#scalar> impl#impl_generics ::juniper::marker::GraphQLInterface<#scalar>
@ -556,7 +620,7 @@ impl Definition {
fn mark() { fn mark() {
#suppress_dead_code #suppress_dead_code
#all_impled_for_unique #all_impled_for_unique
#( <#implemented_for as ::juniper::marker::GraphQLObject<#scalar>>::mark(); )* #( { #mark_object_or_interface } )*
} }
} }
} }
@ -593,6 +657,25 @@ impl Definition {
generics.replace_type_path_with_defaults(&mut ty); generics.replace_type_path_with_defaults(&mut ty);
ty ty
}); });
let const_implements = self
.implements
.iter()
.cloned()
.map(|mut ty| {
generics.replace_type_path_with_defaults(&mut ty);
ty
})
.collect::<Vec<_>>();
let transitive_checks = const_impl_for.clone().map(|const_impl_for| {
quote_spanned! { const_impl_for.span() =>
::juniper::assert_transitive_impls!(
#const_scalar,
#ty#ty_const_generics,
#const_impl_for,
#( #const_implements ),*
);
}
});
quote! { quote! {
#[automatically_derived] #[automatically_derived]
@ -608,6 +691,12 @@ impl Definition {
#ty#ty_const_generics, #ty#ty_const_generics,
#( #const_impl_for ),* #( #const_impl_for ),*
); );
::juniper::assert_implemented_for!(
#const_scalar,
#ty#ty_const_generics,
#( #const_implements ),*
);
#( #transitive_checks )*
} }
} }
} }
@ -640,6 +729,20 @@ impl Definition {
a.cmp(&b) a.cmp(&b)
}); });
// Sorting is required to preserve/guarantee the order of interfaces registered in schema.
let mut implements = self.implements.clone();
implements.sort_unstable_by(|a, b| {
let (a, b) = (quote!(#a).to_string(), quote!(#b).to_string());
a.cmp(&b)
});
let impl_interfaces = (!implements.is_empty()).then(|| {
quote! {
.interfaces(&[
#( registry.get_type::<#implements>(info), )*
])
}
});
let fields_meta = self.fields.iter().map(|f| f.method_meta_tokens(None)); let fields_meta = self.fields.iter().map(|f| f.method_meta_tokens(None));
quote! { quote! {
@ -666,6 +769,7 @@ impl Definition {
]; ];
registry.build_interface_type::<#ty#ty_generics>(info, &fields) registry.build_interface_type::<#ty#ty_generics>(info, &fields)
#description #description
#impl_interfaces
.into_meta() .into_meta()
} }
} }
@ -829,6 +933,7 @@ impl Definition {
fn impl_reflection_traits_tokens(&self) -> TokenStream { fn impl_reflection_traits_tokens(&self) -> TokenStream {
let ty = &self.enum_alias_ident; let ty = &self.enum_alias_ident;
let implemented_for = &self.implemented_for; let implemented_for = &self.implemented_for;
let implements = &self.implements;
let scalar = &self.scalar; let scalar = &self.scalar;
let name = &self.name; let name = &self.name;
let fields = self.fields.iter().map(|f| &f.name); let fields = self.fields.iter().map(|f| &f.name);
@ -857,6 +962,15 @@ impl Definition {
]; ];
} }
#[automatically_derived]
impl#impl_generics ::juniper::macros::reflect::Implements<#scalar>
for #ty#ty_generics
#where_clause
{
const NAMES: ::juniper::macros::reflect::Types =
&[#( <#implements as ::juniper::macros::reflect::BaseType<#scalar>>::NAME ),*];
}
#[automatically_derived] #[automatically_derived]
impl#impl_generics ::juniper::macros::reflect::WrappedType<#scalar> impl#impl_generics ::juniper::macros::reflect::WrappedType<#scalar>
for #ty#ty_generics for #ty#ty_generics
@ -891,6 +1005,7 @@ impl Definition {
let name = &self.name; let name = &self.name;
let implers = &self.implemented_for; let implers = &self.implemented_for;
let interfaces = &self.implements;
let fields = self.fields.iter().map(|f| &f.name); let fields = self.fields.iter().map(|f| &f.name);
quote! { quote! {
@ -911,6 +1026,15 @@ impl Definition {
]; ];
} }
#[automatically_derived]
impl#impl_gens ::juniper::reflect::Implements<#bh> for #ty
#where_clause
{
const NAMES: ::juniper::reflect::Types = &[#(
<#interfaces as ::juniper::reflect::BaseType<#bh>>::NAME
),*];
}
#[automatically_derived] #[automatically_derived]
impl#impl_gens ::juniper::reflect::WrappedType<#bh> for #ty impl#impl_gens ::juniper::reflect::WrappedType<#bh> for #ty
#where_clause #where_clause

View file

@ -100,10 +100,10 @@ macro_rules! try_merge_hashset {
}; };
} }
mod derive_enum;
mod derive_input_object; mod derive_input_object;
mod common; mod common;
mod graphql_enum;
mod graphql_interface; mod graphql_interface;
mod graphql_object; mod graphql_object;
mod graphql_scalar; mod graphql_scalar;
@ -115,17 +115,6 @@ use proc_macro::TokenStream;
use proc_macro_error::{proc_macro_error, ResultExt as _}; use proc_macro_error::{proc_macro_error, ResultExt as _};
use result::GraphQLScope; use result::GraphQLScope;
#[proc_macro_error]
#[proc_macro_derive(GraphQLEnum, attributes(graphql))]
pub fn derive_enum(input: TokenStream) -> TokenStream {
let ast = syn::parse::<syn::DeriveInput>(input).unwrap();
let gen = derive_enum::impl_enum(ast, GraphQLScope::DeriveEnum);
match gen {
Ok(gen) => gen.into(),
Err(err) => proc_macro_error::abort!(err),
}
}
#[proc_macro_error] #[proc_macro_error]
#[proc_macro_derive(GraphQLInputObject, attributes(graphql))] #[proc_macro_derive(GraphQLInputObject, attributes(graphql))]
pub fn derive_input_object(input: TokenStream) -> TokenStream { pub fn derive_input_object(input: TokenStream) -> TokenStream {
@ -137,6 +126,133 @@ pub fn derive_input_object(input: TokenStream) -> TokenStream {
} }
} }
/// `#[derive(GraphQLEnum)]` macro for deriving a [GraphQL enum][0]
/// implementation for Rust enums.
///
/// The `#[graphql]` helper attribute is used for configuring the derived
/// implementation. Specifying multiple `#[graphql]` attributes on the same
/// definition is totally okay. They all will be treated as a single attribute.
///
/// ```rust
/// use juniper::GraphQLEnum;
///
/// #[derive(GraphQLEnum)]
/// enum Episode {
/// NewHope,
/// Empire,
/// Jedi,
/// }
/// ```
///
/// # Custom name, description and deprecation
///
/// The name of a [GraphQL enum][0] or its [values][1] may be overridden with
/// the `name` attribute's argument. By default, a type name is used or a
/// variant name in `SCREAMING_SNAKE_CASE`.
///
/// The description of a [GraphQL enum][0] or its [values][1] may be specified
/// either with the `description`/`desc` attribute's argument, or with a regular
/// Rust doc comment.
///
/// [GraphQL enum value][1] may be deprecated by specifying the `deprecated`
/// attribute's argument, or with regular a Rust `#[deprecated]` attribute.
///
/// ```rust
/// # use juniper::GraphQLEnum;
/// #
/// #[derive(GraphQLEnum)]
/// #[graphql(
/// // Rename the type for GraphQL by specifying the name here.
/// name = "AvailableEpisodes",
/// // You may also specify a description here.
/// // If present, doc comments will be ignored.
/// desc = "Possible episodes.",
/// )]
/// enum Episode {
/// /// Doc comment, also acting as description.
/// #[deprecated(note = "Don't use it")]
/// NewHope,
///
/// #[graphql(name = "Jedi", desc = "Arguably the best one in the trilogy")]
/// #[graphql(deprecated = "Don't use it")]
/// Jedai,
///
/// Empire,
/// }
/// ```
///
/// # Renaming policy
///
/// By default, all [GraphQL enum values][1] are renamed in a
/// `SCREAMING_SNAKE_CASE` manner (so a `NewHope` Rust enum variant becomes a
/// `NEW_HOPE` [value][1] in GraphQL schema, and so on). This complies with
/// default GraphQL naming conventions as [demonstrated in spec][0].
///
/// However, if you need for some reason another naming convention, it's
/// possible to do so by using the `rename_all` attribute's argument. At the
/// moment, it supports the following policies only: `SCREAMING_SNAKE_CASE`,
/// `camelCase`, `none` (disables any renaming).
///
/// ```rust
/// # use juniper::GraphQLEnum;
/// #
/// #[derive(GraphQLEnum)]
/// #[graphql(rename_all = "none")] // disables renaming
/// enum Episode {
/// NewHope,
/// Empire,
/// Jedi,
/// }
/// ```
///
/// # Ignoring enum variants
///
/// To omit exposing a Rust enum variant in a GraphQL schema, use the `ignore`
/// attribute's argument directly on that variant. Only ignored Rust enum
/// variants are allowed to contain fields.
///
/// ```rust
/// # use juniper::GraphQLEnum;
/// #
/// #[derive(GraphQLEnum)]
/// enum Episode<T> {
/// NewHope,
/// Empire,
/// Jedi,
/// #[graphql(ignore)]
/// Legends(T),
/// }
/// ```
///
/// # Custom `ScalarValue`
///
/// By default, `#[derive(GraphQLEnum)]` macro generates code, which is generic
/// over a [`ScalarValue`] type. This can be changed with the `scalar`
/// attribute's argument.
///
/// ```rust
/// # use juniper::{DefaultScalarValue, GraphQLEnum};
/// #
/// #[derive(GraphQLEnum)]
/// #[graphql(scalar = DefaultScalarValue)]
/// enum Episode {
/// NewHope,
/// Empire,
/// Jedi,
/// }
/// ```
///
/// [`ScalarValue`]: juniper::ScalarValue
/// [0]: https://spec.graphql.org/October2021#sec-Enums
/// [1]: https://spec.graphql.org/October2021#sec-Enum-Value
#[proc_macro_error]
#[proc_macro_derive(GraphQLEnum, attributes(graphql))]
pub fn derive_enum(input: TokenStream) -> TokenStream {
graphql_enum::derive::expand(input.into())
.unwrap_or_abort()
.into()
}
/// `#[derive(GraphQLScalar)]` macro for deriving a [GraphQL scalar][0] /// `#[derive(GraphQLScalar)]` macro for deriving a [GraphQL scalar][0]
/// implementation. /// implementation.
/// ///
@ -757,6 +873,125 @@ pub fn derive_scalar_value(input: TokenStream) -> TokenStream {
/// } /// }
/// ``` /// ```
/// ///
/// # Interfaces implementing other interfaces
///
/// GraphQL allows implementing interfaces on other interfaces in addition to
/// objects.
///
/// > __NOTE:__ Every interface has to specify all other interfaces/objects it
/// > implements or is implemented for. Missing one of `for = ` or
/// > `impl = ` attributes is an understandable compile-time error.
///
/// ```rust
/// # extern crate juniper;
/// use juniper::{graphql_interface, graphql_object, ID};
///
/// #[graphql_interface(for = [HumanValue, Luke])]
/// struct Node {
/// id: ID,
/// }
///
/// #[graphql_interface(impl = NodeValue, for = Luke)]
/// struct Human {
/// id: ID,
/// home_planet: String,
/// }
///
/// struct Luke {
/// id: ID,
/// }
///
/// #[graphql_object(impl = [HumanValue, NodeValue])]
/// impl Luke {
/// fn id(&self) -> &ID {
/// &self.id
/// }
///
/// // As `String` and `&str` aren't distinguished by
/// // GraphQL spec, you can use them interchangeably.
/// // Same is applied for `Cow<'a, str>`.
/// // ⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄
/// fn home_planet() -> &'static str {
/// "Tatooine"
/// }
/// }
/// ```
///
/// # GraphQL subtyping and additional `null`able fields
///
/// GraphQL allows implementers (both objects and other interfaces) to return
/// "subtypes" instead of an original value. Basically, this allows you to
/// impose additional bounds on the implementation.
///
/// Valid "subtypes" are:
/// - interface implementer instead of an interface itself:
/// - `I implements T` in place of a `T`;
/// - `Vec<I implements T>` in place of a `Vec<T>`.
/// - non-`null` value in place of a `null`able:
/// - `T` in place of a `Option<T>`;
/// - `Vec<T>` in place of a `Vec<Option<T>>`.
///
/// These rules are recursively applied, so `Vec<Vec<I implements T>>` is a
/// valid "subtype" of a `Option<Vec<Option<Vec<Option<T>>>>>`.
///
/// Also, GraphQL allows implementers to add `null`able fields, which aren't
/// present on an original interface.
///
/// ```rust
/// # extern crate juniper;
/// use juniper::{graphql_interface, graphql_object, ID};
///
/// #[graphql_interface(for = [HumanValue, Luke])]
/// struct Node {
/// id: ID,
/// }
///
/// #[graphql_interface(for = HumanConnectionValue)]
/// struct Connection {
/// nodes: Vec<NodeValue>,
/// }
///
/// #[graphql_interface(impl = NodeValue, for = Luke)]
/// struct Human {
/// id: ID,
/// home_planet: String,
/// }
///
/// #[graphql_interface(impl = ConnectionValue)]
/// struct HumanConnection {
/// nodes: Vec<HumanValue>,
/// // ^^^^^^^^^^ notice not `NodeValue`
/// // This can happen, because every `Human` is a `Node` too, so we are
/// // just imposing additional bounds, which still can be resolved with
/// // `... on Connection { nodes }`.
/// }
///
/// struct Luke {
/// id: ID,
/// }
///
/// #[graphql_object(impl = [HumanValue, NodeValue])]
/// impl Luke {
/// fn id(&self) -> &ID {
/// &self.id
/// }
///
/// fn home_planet(language: Option<String>) -> &'static str {
/// // ^^^^^^^^^^^^^^
/// // Notice additional `null`able field, which is missing on `Human`.
/// // Resolving `...on Human { homePlanet }` will provide `None` for
/// // this argument.
/// match language.as_deref() {
/// None | Some("en") => "Tatooine",
/// Some("ko") => "타투인",
/// _ => todo!(),
/// }
/// }
/// }
/// #
/// # fn main() {}
/// ```
///
/// # Renaming policy /// # Renaming policy
/// ///
/// By default, all [GraphQL interface][1] fields and their arguments are renamed /// By default, all [GraphQL interface][1] fields and their arguments are renamed

View file

@ -9,6 +9,7 @@ use std::fmt;
pub const SPEC_URL: &str = "https://spec.graphql.org/June2018/"; pub const SPEC_URL: &str = "https://spec.graphql.org/June2018/";
pub enum GraphQLScope { pub enum GraphQLScope {
EnumDerive,
InterfaceAttr, InterfaceAttr,
InterfaceDerive, InterfaceDerive,
ObjectAttr, ObjectAttr,
@ -19,19 +20,18 @@ pub enum GraphQLScope {
UnionAttr, UnionAttr,
UnionDerive, UnionDerive,
DeriveInputObject, DeriveInputObject,
DeriveEnum,
} }
impl GraphQLScope { impl GraphQLScope {
pub fn spec_section(&self) -> &str { pub fn spec_section(&self) -> &str {
match self { match self {
Self::EnumDerive => "#sec-Enums",
Self::InterfaceAttr | Self::InterfaceDerive => "#sec-Interfaces", Self::InterfaceAttr | Self::InterfaceDerive => "#sec-Interfaces",
Self::ObjectAttr | Self::ObjectDerive => "#sec-Objects", Self::ObjectAttr | Self::ObjectDerive => "#sec-Objects",
Self::ScalarAttr | Self::ScalarDerive => "#sec-Scalars", Self::ScalarAttr | Self::ScalarDerive => "#sec-Scalars",
Self::ScalarValueDerive => "#sec-Scalars.Built-in-Scalars", Self::ScalarValueDerive => "#sec-Scalars.Built-in-Scalars",
Self::UnionAttr | Self::UnionDerive => "#sec-Unions", Self::UnionAttr | Self::UnionDerive => "#sec-Unions",
Self::DeriveInputObject => "#sec-Input-Objects", Self::DeriveInputObject => "#sec-Input-Objects",
Self::DeriveEnum => "#sec-Enums",
} }
} }
} }
@ -39,13 +39,13 @@ impl GraphQLScope {
impl fmt::Display for GraphQLScope { impl fmt::Display for GraphQLScope {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let name = match self { let name = match self {
Self::EnumDerive => "enum",
Self::InterfaceAttr | Self::InterfaceDerive => "interface", Self::InterfaceAttr | Self::InterfaceDerive => "interface",
Self::ObjectAttr | Self::ObjectDerive => "object", Self::ObjectAttr | Self::ObjectDerive => "object",
Self::ScalarAttr | Self::ScalarDerive => "scalar", Self::ScalarAttr | Self::ScalarDerive => "scalar",
Self::ScalarValueDerive => "built-in scalars", Self::ScalarValueDerive => "built-in scalars",
Self::UnionAttr | Self::UnionDerive => "union", Self::UnionAttr | Self::UnionDerive => "union",
Self::DeriveInputObject => "input object", Self::DeriveInputObject => "input object",
Self::DeriveEnum => "enum",
}; };
write!(f, "GraphQL {}", name) write!(f, "GraphQL {}", name)
} }
@ -56,9 +56,7 @@ impl fmt::Display for GraphQLScope {
pub enum UnsupportedAttribute { pub enum UnsupportedAttribute {
Skip, Skip,
Interface, Interface,
Scalar,
Deprecation, Deprecation,
Default,
} }
impl GraphQLScope { impl GraphQLScope {

View file

@ -683,232 +683,6 @@ impl GraphQLTypeDefiniton {
self.fields.iter().any(|field| field.is_async) self.fields.iter().any(|field| field.is_async)
} }
pub fn into_enum_tokens(self) -> TokenStream {
let name = &self.name;
let ty = &self._type;
let context = self
.context
.as_ref()
.map(|ctx| quote!( #ctx ))
.unwrap_or_else(|| quote!(()));
let scalar = self
.scalar
.as_ref()
.map(|s| quote!( #s ))
.unwrap_or_else(|| {
if self.generic_scalar {
// If generic_scalar is true, we always insert a generic scalar.
// See more comments below.
quote!(__S)
} else {
quote!(::juniper::DefaultScalarValue)
}
});
let description = self
.description
.as_ref()
.map(|description| quote!( .description(#description) ));
let values = self.fields.iter().map(|variant| {
let variant_name = &variant.name;
let descr = variant
.description
.as_ref()
.map(|description| quote!(Some(#description.to_string())))
.unwrap_or_else(|| quote!(None));
let depr = variant
.deprecation
.as_ref()
.map(|deprecation| match deprecation.reason.as_ref() {
Some(reason) => quote!( ::juniper::meta::DeprecationStatus::Deprecated(Some(#reason.to_string())) ),
None => quote!( ::juniper::meta::DeprecationStatus::Deprecated(None) ),
})
.unwrap_or_else(|| quote!(::juniper::meta::DeprecationStatus::Current));
quote!(
::juniper::meta::EnumValue {
name: #variant_name.to_string(),
description: #descr,
deprecation_status: #depr,
},
)
});
let resolves = self.fields.iter().map(|variant| {
let variant_name = &variant.name;
let resolver_code = &variant.resolver_code;
quote!(
&#resolver_code => ::juniper::Value::scalar(String::from(#variant_name)),
)
});
let from_inputs = self.fields.iter().map(|variant| {
let variant_name = &variant.name;
let resolver_code = &variant.resolver_code;
quote!(
Some(#variant_name) => Ok(#resolver_code),
)
});
let to_inputs = self.fields.iter().map(|variant| {
let variant_name = &variant.name;
let resolver_code = &variant.resolver_code;
quote!(
&#resolver_code =>
::juniper::InputValue::scalar(#variant_name.to_string()),
)
});
let mut generics = self.generics.clone();
if self.scalar.is_none() && self.generic_scalar {
// No custom scalar specified, but always generic specified.
// Therefore we inject the generic scalar.
generics.params.push(parse_quote!(__S));
let where_clause = generics.where_clause.get_or_insert(parse_quote!(where));
// Insert ScalarValue constraint.
where_clause
.predicates
.push(parse_quote!(__S: ::juniper::ScalarValue));
}
let (impl_generics, _, where_clause) = generics.split_for_impl();
let mut where_async = where_clause.cloned().unwrap_or_else(|| parse_quote!(where));
where_async
.predicates
.push(parse_quote!( #scalar: Send + Sync ));
where_async.predicates.push(parse_quote!(Self: Sync));
let _async = quote!(
impl#impl_generics ::juniper::GraphQLValueAsync<#scalar> for #ty
#where_async
{
fn resolve_async<'a>(
&'a self,
info: &'a Self::TypeInfo,
selection_set: Option<&'a [::juniper::Selection<#scalar>]>,
executor: &'a ::juniper::Executor<Self::Context, #scalar>,
) -> ::juniper::BoxFuture<'a, ::juniper::ExecutionResult<#scalar>> {
use ::juniper::futures::future;
let v = ::juniper::GraphQLValue::resolve(self, info, selection_set, executor);
Box::pin(future::ready(v))
}
}
);
let mut body = quote!(
impl#impl_generics ::juniper::marker::IsInputType<#scalar> for #ty
#where_clause { }
impl#impl_generics ::juniper::marker::IsOutputType<#scalar> for #ty
#where_clause { }
impl#impl_generics ::juniper::GraphQLType<#scalar> for #ty
#where_clause
{
fn name(_: &()) -> Option<&'static str> {
Some(#name)
}
fn meta<'r>(
_: &(),
registry: &mut ::juniper::Registry<'r, #scalar>
) -> ::juniper::meta::MetaType<'r, #scalar>
where #scalar: 'r,
{
registry.build_enum_type::<#ty>(&(), &[
#( #values )*
])
#description
.into_meta()
}
}
impl#impl_generics ::juniper::GraphQLValue<#scalar> for #ty
#where_clause
{
type Context = #context;
type TypeInfo = ();
fn type_name<'__i>(&self, info: &'__i Self::TypeInfo) -> Option<&'__i str> {
<Self as ::juniper::GraphQLType<#scalar>>::name(info)
}
fn resolve(
&self,
_: &(),
_: Option<&[::juniper::Selection<#scalar>]>,
_: &::juniper::Executor<Self::Context, #scalar>
) -> ::juniper::ExecutionResult<#scalar> {
let v = match self {
#( #resolves )*
};
Ok(v)
}
}
impl#impl_generics ::juniper::FromInputValue<#scalar> for #ty
#where_clause
{
type Error = ::std::string::String;
fn from_input_value(
v: &::juniper::InputValue<#scalar>
) -> Result<#ty, Self::Error> {
match v.as_enum_value().or_else(|| v.as_string_value()) {
#( #from_inputs )*
_ => Err(format!("Unknown enum value: {}", v)),
}
}
}
impl#impl_generics ::juniper::ToInputValue<#scalar> for #ty
#where_clause
{
fn to_input_value(&self) -> ::juniper::InputValue<#scalar> {
match self {
#( #to_inputs )*
}
}
}
impl#impl_generics ::juniper::macros::reflect::BaseType<#scalar> for #ty
#where_clause
{
const NAME: ::juniper::macros::reflect::Type = #name;
}
impl#impl_generics ::juniper::macros::reflect::BaseSubTypes<#scalar> for #ty
#where_clause
{
const NAMES: ::juniper::macros::reflect::Types =
&[<Self as ::juniper::macros::reflect::BaseType<#scalar>>::NAME];
}
impl#impl_generics ::juniper::macros::reflect::WrappedType<#scalar> for #ty
#where_clause
{
const VALUE: ::juniper::macros::reflect::WrappedValue = 1;
}
);
if !self.no_async {
body.extend(_async)
}
body
}
pub fn into_input_object_tokens(self) -> TokenStream { pub fn into_input_object_tokens(self) -> TokenStream {
let name = &self.name; let name = &self.name;
let ty = &self._type; let ty = &self._type;

View file

@ -45,10 +45,6 @@ impl<T> SpanContainer<T> {
self.val self.val
} }
pub fn inner(&self) -> &T {
&self.val
}
pub fn map<U, F: Fn(T) -> U>(self, f: F) -> SpanContainer<U> { pub fn map<U, F: Fn(T) -> U>(self, f: F) -> SpanContainer<U> {
SpanContainer { SpanContainer {
expr: self.expr, expr: self.expr,

View file

@ -9,6 +9,6 @@ futures = "0.3.1"
juniper = { path = "../../juniper" } juniper = { path = "../../juniper" }
[dev-dependencies] [dev-dependencies]
serde_json = { version = "1.0" } serde_json = "1.0"
tokio = { version = "1.0", features = ["rt", "time", "macros"] } tokio = { version = "1.0", features = ["rt", "time", "macros"] }
trybuild = "1.0.25" trybuild = "1.0.25"

View file

@ -0,0 +1,10 @@
use juniper::GraphQLEnum;
#[derive(GraphQLEnum)]
enum Test {
Test,
#[graphql(name = "TEST")]
Test1,
}
fn main() {}

View file

@ -0,0 +1,7 @@
error: GraphQL enum expected all GraphQL enum values to have unique names
--> fail/enum/derive_duplicated_value_names.rs:5:5
|
5 | / Test,
6 | | #[graphql(name = "TEST")]
7 | | Test1,
| |__________^

View file

@ -0,0 +1,8 @@
use juniper::GraphQLEnum;
#[derive(GraphQLEnum)]
enum __Test {
Test,
}
fn main() {}

View file

@ -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 GraphQLs introspection system.
--> fail/enum/derive_name_double_underscored.rs:4:6
|
4 | enum __Test {
| ^^^^^^
|
= note: https://spec.graphql.org/June2018/#sec-Schema

View file

@ -1,4 +0,0 @@
#[derive(juniper::GraphQLEnum)]
pub enum Test {}
fn main() { }

View file

@ -1,7 +0,0 @@
error: GraphQL enum expects at least one field
--> fail/enum/derive_no_fields.rs:2:1
|
2 | pub enum Test {}
| ^^^^^^^^^^^^^^^^
|
= note: https://spec.graphql.org/June2018/#sec-Enums

View file

@ -0,0 +1,6 @@
use juniper::GraphQLEnum;
#[derive(GraphQLEnum)]
enum Test {}
fn main() {}

View file

@ -0,0 +1,7 @@
error: GraphQL enum expected at least 1 non-ignored enum variant
--> fail/enum/derive_no_values.rs:3:10
|
3 | #[derive(GraphQLEnum)]
| ^^^^^^^^^^^
|
= note: this error originates in the derive macro `GraphQLEnum` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -0,0 +1,8 @@
use juniper::GraphQLEnum;
#[derive(GraphQLEnum)]
enum Test {
Variant(i32),
}
fn main() {}

View file

@ -0,0 +1,7 @@
error: GraphQL enum no fields allowed for non-ignored variants
--> fail/enum/derive_variant_with_field.rs:5:12
|
5 | Variant(i32),
| ^^^^^
|
= note: https://spec.graphql.org/June2018/#sec-Enums

View file

@ -0,0 +1,6 @@
use juniper::GraphQLEnum;
#[derive(GraphQLEnum)]
struct Test {}
fn main() {}

View file

@ -0,0 +1,5 @@
error: GraphQL enum can only be derived on enums
--> fail/enum/derive_wrong_item.rs:4:1
|
4 | struct Test {}
| ^^^^^^^^^^^^^^

View file

@ -60,7 +60,7 @@ error[E0599]: no method named `to_input_value` found for struct `ObjectA` in the
--> fail/input-object/derive_incompatible_object.rs:6:10 --> fail/input-object/derive_incompatible_object.rs:6:10
| |
2 | struct ObjectA { 2 | struct ObjectA {
| -------------- method `to_input_value` not found for this | ------- method `to_input_value` not found for this struct
... ...
6 | #[derive(juniper::GraphQLInputObject)] 6 | #[derive(juniper::GraphQLInputObject)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ method not found in `ObjectA` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ method not found in `ObjectA`

View file

@ -0,0 +1,13 @@
use juniper::graphql_interface;
#[graphql_interface(impl = Node2Value, for = Node2Value)]
struct Node1 {
id: String,
}
#[graphql_interface(impl = Node1Value, for = Node1Value)]
struct Node2 {
id: String,
}
fn main() {}

View file

@ -0,0 +1,26 @@
error[E0391]: cycle detected when expanding type alias `Node1Value`
--> fail/interface/struct/attr_cyclic_impl.rs:3:46
|
3 | #[graphql_interface(impl = Node2Value, for = Node2Value)]
| ^^^^^^^^^^
|
note: ...which requires expanding type alias `Node2Value`...
--> fail/interface/struct/attr_cyclic_impl.rs:8:46
|
8 | #[graphql_interface(impl = Node1Value, for = Node1Value)]
| ^^^^^^^^^^
= note: ...which again requires expanding type alias `Node1Value`, completing the cycle
= note: type aliases cannot be recursive
= help: consider using a struct, enum, or union instead to break the cycle
= help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information
note: cycle used when collecting item types in top-level module
--> fail/interface/struct/attr_cyclic_impl.rs:1:1
|
1 | / use juniper::graphql_interface;
2 | |
3 | | #[graphql_interface(impl = Node2Value, for = Node2Value)]
4 | | struct Node1 {
... |
12 | |
13 | | fn main() {}
| |____________^

View file

@ -9,3 +9,27 @@ error[E0412]: cannot find type `CharacterValue` in this scope
| |
4 | #[graphql(impl = CharacterValue)] 4 | #[graphql(impl = CharacterValue)]
| ^^^^^^^^^^^^^^ not found in this scope | ^^^^^^^^^^^^^^ not found in this scope
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_implementers_duplicate_pretty.rs:3:10
|
3 | #[derive(GraphQLObject)]
| ^^^^^^^^^^^^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_implementers_duplicate_pretty.rs:3:10
|
3 | #[derive(GraphQLObject)]
| ^^^^^^^^^^^^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_implementers_duplicate_pretty.rs:3:10
|
3 | #[derive(GraphQLObject)]
| ^^^^^^^^^^^^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -22,6 +22,315 @@ error[E0080]: erroneous constant used
| |
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: erroneous constant used
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: erroneous constant used
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^
| |
| referenced constant has errors
| inside `<CharacterValueEnum<ObjA> as juniper::macros::reflect::Field<__S, id>>::call::_::check` at $WORKSPACE/juniper/src/macros/reflect.rs:751:36
| inside `<CharacterValueEnum<ObjA> as juniper::macros::reflect::Field<__S, id>>::call::_::RES` at $WORKSPACE/juniper/src/macros/reflect.rs:814:59
|
= note: `#[deny(const_err)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5 --> fail/interface/struct/attr_missing_field.rs:11:5
| |
@ -30,6 +339,158 @@ error[E0080]: evaluation of constant value failed
| |
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_subtype` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_subtype` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_subtype` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5 --> fail/interface/struct/attr_missing_field.rs:11:5
| |
@ -54,6 +515,314 @@ error[E0080]: erroneous constant used
| |
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: erroneous constant used
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: erroneous constant used
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^
| |
| referenced constant has errors
| inside `<CharacterValueEnum<ObjA> as AsyncField<__S, id>>::call::_::check` at $WORKSPACE/juniper/src/macros/reflect.rs:751:36
| inside `<CharacterValueEnum<ObjA> as AsyncField<__S, id>>::call::_::RES` at $WORKSPACE/juniper/src/macros/reflect.rs:814:59
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5 --> fail/interface/struct/attr_missing_field.rs:11:5
| |
@ -61,3 +830,155 @@ error[E0080]: evaluation of constant value failed
| ^^ 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 | ^^ 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) = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_subtype` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_subtype` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_subtype` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_field.rs:11:5
|
11 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -0,0 +1,18 @@
use juniper::graphql_interface;
#[graphql_interface(for = Node2Value)]
struct Node1 {
id: String,
}
#[graphql_interface(impl = Node1Value, for = Node3Value)]
struct Node2 {
id: String,
}
#[graphql_interface(impl = Node2Value)]
struct Node3 {
id: String,
}
fn main() {}

View file

@ -0,0 +1,7 @@
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/attr_missing_transitive_impl.rs:8:46
|
8 | #[graphql_interface(impl = Node1Value, for = Node3Value)]
| ^^^^^^^^^^ the evaluated program panicked at 'Failed to implement interface `Node2` on `Node3`: missing `impl = ` for transitive interface `Node1` on `Node3`.', $DIR/fail/interface/struct/attr_missing_transitive_impl.rs:8:46
|
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -0,0 +1,15 @@
use juniper::GraphQLInterface;
#[derive(GraphQLInterface)]
#[graphql(impl = Node2Value, for = Node2Value)]
struct Node1 {
id: String,
}
#[derive(GraphQLInterface)]
#[graphql(impl = Node1Value, for = Node1Value)]
struct Node2 {
id: String,
}
fn main() {}

View file

@ -0,0 +1,26 @@
error[E0391]: cycle detected when expanding type alias `Node1Value`
--> fail/interface/struct/derive_cyclic_impl.rs:4:36
|
4 | #[graphql(impl = Node2Value, for = Node2Value)]
| ^^^^^^^^^^
|
note: ...which requires expanding type alias `Node2Value`...
--> fail/interface/struct/derive_cyclic_impl.rs:10:36
|
10 | #[graphql(impl = Node1Value, for = Node1Value)]
| ^^^^^^^^^^
= note: ...which again requires expanding type alias `Node1Value`, completing the cycle
= note: type aliases cannot be recursive
= help: consider using a struct, enum, or union instead to break the cycle
= help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information
note: cycle used when collecting item types in top-level module
--> fail/interface/struct/derive_cyclic_impl.rs:1:1
|
1 | / use juniper::GraphQLInterface;
2 | |
3 | | #[derive(GraphQLInterface)]
4 | | #[graphql(impl = Node2Value, for = Node2Value)]
... |
14 | |
15 | | fn main() {}
| |____________^

View file

@ -9,3 +9,27 @@ error[E0412]: cannot find type `CharacterValue` in this scope
| |
4 | #[graphql(impl = CharacterValue)] 4 | #[graphql(impl = CharacterValue)]
| ^^^^^^^^^^^^^^ not found in this scope | ^^^^^^^^^^^^^^ not found in this scope
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_implementers_duplicate_pretty.rs:3:10
|
3 | #[derive(GraphQLObject)]
| ^^^^^^^^^^^^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_implementers_duplicate_pretty.rs:3:10
|
3 | #[derive(GraphQLObject)]
| ^^^^^^^^^^^^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_implementers_duplicate_pretty.rs:3:10
|
3 | #[derive(GraphQLObject)]
| ^^^^^^^^^^^^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -22,6 +22,315 @@ error[E0080]: erroneous constant used
| |
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: erroneous constant used
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: erroneous constant used
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^
| |
| referenced constant has errors
| inside `<CharacterValueEnum<ObjA> as juniper::macros::reflect::Field<__S, id>>::call::_::check` at $WORKSPACE/juniper/src/macros/reflect.rs:751:36
| inside `<CharacterValueEnum<ObjA> as juniper::macros::reflect::Field<__S, id>>::call::_::RES` at $WORKSPACE/juniper/src/macros/reflect.rs:814:59
|
= note: `#[deny(const_err)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5 --> fail/interface/struct/derive_missing_field.rs:12:5
| |
@ -30,6 +339,158 @@ error[E0080]: evaluation of constant value failed
| |
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_subtype` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_subtype` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_subtype` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5 --> fail/interface/struct/derive_missing_field.rs:12:5
| |
@ -54,6 +515,314 @@ error[E0080]: erroneous constant used
| |
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: erroneous constant used
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: erroneous constant used
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^
| |
| referenced constant has errors
| inside `<CharacterValueEnum<ObjA> as AsyncField<__S, id>>::call::_::check` at $WORKSPACE/juniper/src/macros/reflect.rs:751:36
| inside `<CharacterValueEnum<ObjA> as AsyncField<__S, id>>::call::_::RES` at $WORKSPACE/juniper/src/macros/reflect.rs:814:59
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5 --> fail/interface/struct/derive_missing_field.rs:12:5
| |
@ -61,3 +830,155 @@ error[E0080]: evaluation of constant value failed
| ^^ the evaluated program panicked at 'Failed to implement interface `Character` on `ObjA`: Field `id` isn't implemented on `ObjA`.', $DIR/fail/interface/struct/derive_missing_field.rs:12:5 | ^^ the evaluated program panicked at 'Failed to implement interface `Character` on `ObjA`: Field `id` isn't implemented on `ObjA`.', $DIR/fail/interface/struct/derive_missing_field.rs:12:5
| |
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_subtype` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_subtype` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_subtype` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_field.rs:12:5
|
12 | id: String,
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -0,0 +1,21 @@
use juniper::GraphQLInterface;
#[derive(GraphQLInterface)]
#[graphql(for = Node2Value)]
struct Node1 {
id: String,
}
#[derive(GraphQLInterface)]
#[graphql(impl = Node1Value, for = Node3Value)]
struct Node2 {
id: String,
}
#[derive(GraphQLInterface)]
#[graphql(impl = Node2Value)]
struct Node3 {
id: String,
}
fn main() {}

View file

@ -0,0 +1,7 @@
error[E0080]: evaluation of constant value failed
--> fail/interface/struct/derive_missing_transitive_impl.rs:10:36
|
10 | #[graphql(impl = Node1Value, for = Node3Value)]
| ^^^^^^^^^^ the evaluated program panicked at 'Failed to implement interface `Node2` on `Node3`: missing `impl = ` for transitive interface `Node1` on `Node3`.', $DIR/fail/interface/struct/derive_missing_transitive_impl.rs:10:36
|
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -0,0 +1,13 @@
use juniper::graphql_interface;
#[graphql_interface(impl = Node2Value, for = Node2Value)]
trait Node1 {
fn id(&self) -> &str;
}
#[graphql_interface(impl = Node1Value, for = Node1Value)]
trait Node2 {
fn id() -> String;
}
fn main() {}

View file

@ -0,0 +1,26 @@
error[E0391]: cycle detected when expanding type alias `Node1Value`
--> fail/interface/trait/cyclic_impl.rs:3:46
|
3 | #[graphql_interface(impl = Node2Value, for = Node2Value)]
| ^^^^^^^^^^
|
note: ...which requires expanding type alias `Node2Value`...
--> fail/interface/trait/cyclic_impl.rs:8:46
|
8 | #[graphql_interface(impl = Node1Value, for = Node1Value)]
| ^^^^^^^^^^
= note: ...which again requires expanding type alias `Node1Value`, completing the cycle
= note: type aliases cannot be recursive
= help: consider using a struct, enum, or union instead to break the cycle
= help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information
note: cycle used when collecting item types in top-level module
--> fail/interface/trait/cyclic_impl.rs:1:1
|
1 | / use juniper::graphql_interface;
2 | |
3 | | #[graphql_interface(impl = Node2Value, for = Node2Value)]
4 | | trait Node1 {
... |
12 | |
13 | | fn main() {}
| |____________^

View file

@ -9,3 +9,27 @@ error[E0412]: cannot find type `CharacterValue` in this scope
| |
4 | #[graphql(impl = CharacterValue)] 4 | #[graphql(impl = CharacterValue)]
| ^^^^^^^^^^^^^^ not found in this scope | ^^^^^^^^^^^^^^ not found in this scope
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/implementers_duplicate_pretty.rs:3:10
|
3 | #[derive(GraphQLObject)]
| ^^^^^^^^^^^^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/implementers_duplicate_pretty.rs:3:10
|
3 | #[derive(GraphQLObject)]
| ^^^^^^^^^^^^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/implementers_duplicate_pretty.rs:3:10
|
3 | #[derive(GraphQLObject)]
| ^^^^^^^^^^^^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -22,6 +22,315 @@ error[E0080]: erroneous constant used
| |
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: erroneous constant used
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: erroneous constant used
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^
| |
| referenced constant has errors
| inside `<CharacterValueEnum<ObjA> as juniper::macros::reflect::Field<__S, id>>::call::_::check` at $WORKSPACE/juniper/src/macros/reflect.rs:751:36
| inside `<CharacterValueEnum<ObjA> as juniper::macros::reflect::Field<__S, id>>::call::_::RES` at $WORKSPACE/juniper/src/macros/reflect.rs:814:59
|
= note: `#[deny(const_err)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8 --> fail/interface/trait/missing_field.rs:11:8
| |
@ -30,6 +339,158 @@ error[E0080]: evaluation of constant value failed
| |
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_subtype` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_subtype` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_subtype` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8 --> fail/interface/trait/missing_field.rs:11:8
| |
@ -54,6 +515,314 @@ error[E0080]: erroneous constant used
| |
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: erroneous constant used
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: erroneous constant used
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^
| |
| referenced constant has errors
| inside `<CharacterValueEnum<ObjA> as AsyncField<__S, id>>::call::_::check` at $WORKSPACE/juniper/src/macros/reflect.rs:751:36
| inside `<CharacterValueEnum<ObjA> as AsyncField<__S, id>>::call::_::RES` at $WORKSPACE/juniper/src/macros/reflect.rs:814:59
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_field_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8 --> fail/interface/trait/missing_field.rs:11:8
| |
@ -61,3 +830,155 @@ error[E0080]: evaluation of constant value failed
| ^^ the evaluated program panicked at 'Failed to implement interface `Character` on `ObjA`: Field `id` isn't implemented on `ObjA`.', $DIR/fail/interface/trait/missing_field.rs:11:8 | ^^ the evaluated program panicked at 'Failed to implement interface `Character` on `ObjA`: Field `id` isn't implemented on `ObjA`.', $DIR/fail/interface/trait/missing_field.rs:11:8
| |
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_subtype` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_subtype` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::const_concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::assert_subtype` (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_field.rs:11:8
|
11 | fn id(&self) -> &str;
| ^^ referenced constant has errors
|
= note: this error originates in the macro `$crate::format_type` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -0,0 +1,18 @@
use juniper::graphql_interface;
#[graphql_interface(for = Node2Value)]
trait Node1 {
fn id() -> String;
}
#[graphql_interface(impl = Node1Value, for = Node3Value)]
trait Node2 {
fn id(&self) -> &str;
}
#[graphql_interface(impl = Node2Value)]
trait Node3 {
fn id() -> &'static str;
}
fn main() {}

View file

@ -0,0 +1,7 @@
error[E0080]: evaluation of constant value failed
--> fail/interface/trait/missing_transitive_impl.rs:8:46
|
8 | #[graphql_interface(impl = Node1Value, for = Node3Value)]
| ^^^^^^^^^^ the evaluated program panicked at 'Failed to implement interface `Node2` on `Node3`: missing `impl = ` for transitive interface `Node1` on `Node3`.', $DIR/fail/interface/trait/missing_transitive_impl.rs:8:46
|
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -1,133 +0,0 @@
use fnv::FnvHashMap;
use juniper::{
graphql_input_value, DefaultScalarValue, FromInputValue, GraphQLEnum, GraphQLType, Registry,
ToInputValue,
};
pub struct CustomContext {}
impl juniper::Context for CustomContext {}
#[derive(GraphQLEnum, Debug, PartialEq)]
#[graphql(name = "Some", description = "enum descr")]
enum SomeEnum {
Regular,
#[graphql(name = "FULL", description = "field descr", deprecated = "depr")]
Full,
}
#[derive(juniper::GraphQLEnum, Debug, PartialEq)]
#[graphql(rename = "none")]
enum NoRenameEnum {
OneVariant,
AnotherVariant,
}
/// Enum doc.
#[derive(GraphQLEnum)]
enum DocEnum {
/// Variant doc.
Foo,
}
/// Doc 1.\
/// Doc 2.
///
/// Doc 4.
#[derive(GraphQLEnum, Debug, PartialEq)]
enum MultiDocEnum {
/// Variant 1.
/// Variant 2.
Foo,
}
/// This is not used as the description.
#[derive(GraphQLEnum, Debug, PartialEq)]
#[graphql(description = "enum override")]
enum OverrideDocEnum {
/// This is not used as the description.
#[graphql(description = "variant override")]
Foo,
}
#[derive(GraphQLEnum)]
#[graphql(context = CustomContext, noasync)]
enum ContextEnum {
A,
}
#[test]
fn test_derived_enum() {
// Ensure that rename works.
assert_eq!(
<SomeEnum as GraphQLType<DefaultScalarValue>>::name(&()),
Some("Some")
);
// Ensure validity of meta info.
let mut registry: Registry<'_> = Registry::new(FnvHashMap::default());
let meta = SomeEnum::meta(&(), &mut registry);
assert_eq!(meta.name(), Some("Some"));
assert_eq!(meta.description(), Some("enum descr"));
// Test no rename variant.
assert_eq!(
<_ as ToInputValue>::to_input_value(&NoRenameEnum::AnotherVariant),
graphql_input_value!("AnotherVariant"),
);
// Test Regular variant.
assert_eq!(
<_ as ToInputValue>::to_input_value(&SomeEnum::Regular),
graphql_input_value!("REGULAR"),
);
assert_eq!(
FromInputValue::<DefaultScalarValue>::from_input_value(&graphql_input_value!(REGULAR)),
Ok(SomeEnum::Regular),
);
// Test FULL variant.
assert_eq!(
<_ as ToInputValue>::to_input_value(&SomeEnum::Full),
graphql_input_value!("FULL"),
);
assert_eq!(
FromInputValue::<DefaultScalarValue>::from_input_value(&graphql_input_value!(FULL)),
Ok(SomeEnum::Full)
);
}
#[test]
fn test_doc_comment() {
let mut registry: Registry<'_> = Registry::new(FnvHashMap::default());
let meta = DocEnum::meta(&(), &mut registry);
assert_eq!(meta.description(), Some("Enum doc."));
}
#[test]
fn test_multi_doc_comment() {
let mut registry: Registry<'_> = Registry::new(FnvHashMap::default());
let meta = MultiDocEnum::meta(&(), &mut registry);
assert_eq!(meta.description(), Some("Doc 1. Doc 2.\n\nDoc 4."));
}
#[test]
fn test_doc_comment_override() {
let mut registry: Registry<'_> = Registry::new(FnvHashMap::default());
let meta = OverrideDocEnum::meta(&(), &mut registry);
assert_eq!(meta.description(), Some("enum override"));
}
fn test_context<T>(_t: T)
where
T: GraphQLType<DefaultScalarValue, Context = CustomContext>,
{
// empty
}
#[test]
fn test_doc_custom_context() {
test_context(ContextEnum::A);
// test_context(OverrideDocEnum::Foo); does not work
}

View file

@ -0,0 +1,932 @@
//! Tests for `#[derive(GraphQLEnum)]` macro.
use juniper::{
execute, graphql_object, graphql_value, graphql_vars, parser::SourcePosition,
DefaultScalarValue, ExecutionError, FieldError, GraphQLEnum, ScalarValue,
};
use crate::util::{schema, schema_with_scalar};
mod trivial {
use super::*;
#[derive(GraphQLEnum)]
enum Character {
Human,
Droid,
}
struct QueryRoot;
#[graphql_object]
impl QueryRoot {
fn pass_as_is(character: Character) -> Character {
character
}
}
#[tokio::test]
async fn resolves() {
const DOC: &str = r#"{
passAsIs(character: HUMAN)
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"passAsIs": "HUMAN"}), vec![])),
);
}
#[tokio::test]
async fn is_graphql_enum() {
const DOC: &str = r#"{
__type(name: "Character") {
kind
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"__type": {"kind": "ENUM"}}), vec![])),
);
}
#[tokio::test]
async fn uses_type_name() {
const DOC: &str = r#"{
__type(name: "Character") {
name
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"__type": {"name": "Character"}}), vec![])),
);
}
#[tokio::test]
async fn has_no_description() {
const DOC: &str = r#"{
__type(name: "Character") {
description
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"__type": {"description": null}}), vec![])),
);
}
#[tokio::test]
async fn has_enum_values() {
const DOC: &str = r#"{
__type(name: "Character") {
enumValues {
name
description
}
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"__type": {"enumValues": [
{"name": "HUMAN", "description": null},
{"name": "DROID", "description": null},
]}}),
vec![],
)),
);
}
}
mod ignored_variant {
use super::*;
#[derive(GraphQLEnum)]
enum Character {
Human,
#[allow(dead_code)]
#[graphql(ignore)]
Droid,
}
struct QueryRoot;
#[graphql_object]
impl QueryRoot {
fn pass_as_is(character: Character) -> Character {
character
}
fn droid() -> Character {
Character::Droid
}
}
#[tokio::test]
async fn resolves() {
const DOC: &str = r#"{
passAsIs(character: HUMAN)
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"passAsIs": "HUMAN"}), vec![])),
);
}
#[tokio::test]
async fn err_on_droid() {
const DOC: &str = r#"{
droid
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!(null),
vec![ExecutionError::new(
SourcePosition::new(14, 1, 12),
&["droid"],
FieldError::from("Cannot resolve ignored enum variant"),
)],
)),
);
}
#[tokio::test]
async fn has_enum_values() {
const DOC: &str = r#"{
__type(name: "Character") {
enumValues {
name
description
}
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"__type": {"enumValues": [
{"name": "HUMAN", "description": null},
]}}),
vec![],
)),
);
}
}
mod ignored_generic_variant {
use super::*;
#[derive(GraphQLEnum)]
enum Character<T> {
Human,
Droid,
#[allow(dead_code)]
#[graphql(ignore)]
Ignored(T),
}
struct QueryRoot;
#[graphql_object]
impl QueryRoot {
fn pass_as_is(character: Character<()>) -> Character<()> {
character
}
}
#[tokio::test]
async fn resolves() {
const DOC: &str = r#"{
passAsIs(character: HUMAN)
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"passAsIs": "HUMAN"}), vec![])),
);
}
#[tokio::test]
async fn has_enum_values() {
const DOC: &str = r#"{
__type(name: "Character") {
enumValues {
name
description
}
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"__type": {"enumValues": [
{"name": "HUMAN", "description": null},
{"name": "DROID", "description": null},
]}}),
vec![],
)),
);
}
}
mod description_from_doc_comment {
use super::*;
/// Character doc.
#[derive(GraphQLEnum)]
enum Character {
/// Human doc.
Human,
/// Droid doc.
Droid,
}
struct QueryRoot;
#[graphql_object]
impl QueryRoot {
fn pass_as_is(character: Character) -> Character {
character
}
}
#[tokio::test]
async fn resolves() {
const DOC: &str = r#"{
passAsIs(character: HUMAN)
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"passAsIs": "HUMAN"}), vec![])),
);
}
#[tokio::test]
async fn is_graphql_enum() {
const DOC: &str = r#"{
__type(name: "Character") {
kind
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"__type": {"kind": "ENUM"}}), vec![])),
);
}
#[tokio::test]
async fn uses_type_name() {
const DOC: &str = r#"{
__type(name: "Character") {
name
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"__type": {"name": "Character"}}), vec![])),
);
}
#[tokio::test]
async fn has_description() {
const DOC: &str = r#"{
__type(name: "Character") {
description
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"__type": {"description": "Character doc."}}),
vec![],
)),
);
}
#[tokio::test]
async fn has_enum_values() {
const DOC: &str = r#"{
__type(name: "Character") {
enumValues {
name
description
isDeprecated
deprecationReason
}
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"__type": {"enumValues": [
{
"name": "HUMAN",
"description": "Human doc.",
"isDeprecated": false,
"deprecationReason": null,
},
{
"name": "DROID",
"description": "Droid doc.",
"isDeprecated": false,
"deprecationReason": null,
},
]}}),
vec![],
)),
);
}
}
mod deprecation_from_attr {
#![allow(deprecated)]
use super::*;
/// Character doc.
#[derive(GraphQLEnum)]
enum Character {
/// Human doc.
#[deprecated]
Human,
/// Droid doc.
#[deprecated(note = "Reason")]
Droid,
}
struct QueryRoot;
#[graphql_object]
impl QueryRoot {
fn pass_as_is(character: Character) -> Character {
character
}
}
#[tokio::test]
async fn has_description() {
const DOC: &str = r#"{
__type(name: "Character") {
description
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"__type": {"description": "Character doc."}}),
vec![],
)),
);
}
#[tokio::test]
async fn has_enum_values() {
const DOC: &str = r#"{
__type(name: "Character") {
enumValues {
name
description
}
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"__type": {"enumValues": []}}), vec![])),
);
}
#[tokio::test]
async fn has_enum_values_with_deprecated() {
const DOC: &str = r#"{
__type(name: "Character") {
enumValues(includeDeprecated: true) {
name
description
isDeprecated
deprecationReason
}
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"__type": {"enumValues": [
{
"name": "HUMAN",
"description": "Human doc.",
"isDeprecated": true,
"deprecationReason": null,
},
{
"name": "DROID",
"description": "Droid doc.",
"isDeprecated": true,
"deprecationReason": "Reason",
},
]}}),
vec![],
)),
);
}
}
mod deprecation_from_graphql_attr {
#![allow(deprecated)]
use super::*;
/// Character doc.
#[derive(GraphQLEnum)]
enum Character {
/// Human doc.
#[graphql(deprecated)]
Human,
/// Droid doc.
#[graphql(deprecated = "Reason")]
Droid,
}
struct QueryRoot;
#[graphql_object]
impl QueryRoot {
fn pass_as_is(character: Character) -> Character {
character
}
}
#[tokio::test]
async fn has_description() {
const DOC: &str = r#"{
__type(name: "Character") {
description
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"__type": {"description": "Character doc."}}),
vec![],
)),
);
}
#[tokio::test]
async fn has_enum_values() {
const DOC: &str = r#"{
__type(name: "Character") {
enumValues {
name
description
}
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"__type": {"enumValues": []}}), vec![])),
);
}
#[tokio::test]
async fn has_enum_values_with_deprecated() {
const DOC: &str = r#"{
__type(name: "Character") {
enumValues(includeDeprecated: true) {
name
description
isDeprecated
deprecationReason
}
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"__type": {"enumValues": [
{
"name": "HUMAN",
"description": "Human doc.",
"isDeprecated": true,
"deprecationReason": null,
},
{
"name": "DROID",
"description": "Droid doc.",
"isDeprecated": true,
"deprecationReason": "Reason",
},
]}}),
vec![],
)),
);
}
}
mod explicit_name_description_and_deprecation {
#![allow(deprecated)]
use super::*;
/// Doc comment.
#[derive(GraphQLEnum)]
#[graphql(name = "MyCharacter", desc = "Character doc.")]
enum Character {
/// Human doc.
#[graphql(name = "MY_HUMAN", desc = "My human doc.", deprecated = "Not used.")]
#[deprecated(note = "Should be omitted.")]
Human,
/// Droid doc.
#[graphql(deprecated = "Reason")]
Droid,
}
struct QueryRoot;
#[graphql_object]
impl QueryRoot {
fn pass_as_is(character: Character) -> Character {
character
}
}
#[tokio::test]
async fn has_no_description() {
const DOC: &str = r#"{
__type(name: "MyCharacter") {
description
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"__type": {"description": "Character doc."}}),
vec![],
)),
);
}
#[tokio::test]
async fn has_enum_values() {
const DOC: &str = r#"{
__type(name: "MyCharacter") {
enumValues {
name
description
}
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"__type": {"enumValues": []}}), vec![])),
);
}
#[tokio::test]
async fn has_enum_values_with_deprecated() {
const DOC: &str = r#"{
__type(name: "MyCharacter") {
enumValues(includeDeprecated: true) {
name
description
isDeprecated
deprecationReason
}
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"__type": {"enumValues": [
{
"name": "MY_HUMAN",
"description": "My human doc.",
"isDeprecated": true,
"deprecationReason": "Not used.",
},
{
"name": "DROID",
"description": "Droid doc.",
"isDeprecated": true,
"deprecationReason": "Reason",
},
]}}),
vec![],
)),
);
}
}
mod renamed_all_fields {
use super::*;
#[derive(GraphQLEnum)]
#[graphql(rename_all = "none")]
enum Character {
Human,
Droid,
}
struct QueryRoot;
#[graphql_object]
impl QueryRoot {
fn pass_as_is(character: Character) -> Character {
character
}
}
#[tokio::test]
async fn resolves() {
const DOC: &str = r#"{
passAsIs(character: Human)
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"passAsIs": "Human"}), vec![])),
);
}
#[tokio::test]
async fn has_enum_values() {
const DOC: &str = r#"{
__type(name: "Character") {
enumValues {
name
description
}
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"__type": {"enumValues": [
{"name": "Human", "description": null},
{"name": "Droid", "description": null},
]}}),
vec![],
)),
);
}
}
mod explicit_scalar {
use super::*;
#[derive(GraphQLEnum)]
#[graphql(scalar = DefaultScalarValue)]
enum Character {
Human,
Droid,
}
struct QueryRoot;
#[graphql_object(scalar = DefaultScalarValue)]
impl QueryRoot {
fn pass_as_is(character: Character) -> Character {
character
}
}
#[tokio::test]
async fn resolves() {
const DOC: &str = r#"{
passAsIs(character: HUMAN)
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"passAsIs": "HUMAN"}), vec![])),
);
}
}
mod custom_scalar {
use crate::custom_scalar::MyScalarValue;
use super::*;
#[derive(GraphQLEnum)]
#[graphql(scalar = MyScalarValue)]
enum Character {
Human,
Droid,
}
struct QueryRoot;
#[graphql_object(scalar = MyScalarValue)]
impl QueryRoot {
fn pass_as_is(character: Character) -> Character {
character
}
}
#[tokio::test]
async fn resolves() {
const DOC: &str = r#"{
passAsIs(character: HUMAN)
}"#;
let schema = schema_with_scalar::<MyScalarValue, _, _>(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"passAsIs": "HUMAN"}), vec![])),
);
}
}
mod explicit_generic_scalar {
use super::*;
#[derive(GraphQLEnum)]
#[graphql(scalar = S)]
enum Character<S: ScalarValue> {
Human,
Droid,
#[allow(dead_code)]
#[graphql(ignore)]
Scalar(S),
}
struct QueryRoot;
#[graphql_object(scalar = S: ScalarValue)]
impl QueryRoot {
fn pass_as_is<S: ScalarValue>(character: Character<S>) -> Character<S> {
character
}
}
#[tokio::test]
async fn resolves() {
const DOC: &str = r#"{
passAsIs(character: HUMAN)
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"passAsIs": "HUMAN"}), vec![])),
);
}
}
mod bounded_generic_scalar {
use super::*;
#[derive(GraphQLEnum)]
#[graphql(scalar = S: ScalarValue + Clone)]
enum Character {
Human,
Droid,
}
struct QueryRoot;
#[graphql_object]
impl QueryRoot {
fn pass_as_is(character: Character) -> Character {
character
}
}
#[tokio::test]
async fn resolves() {
const DOC: &str = r#"{
passAsIs(character: HUMAN)
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"passAsIs": "HUMAN"}), vec![])),
);
}
}
mod explicit_custom_context {
use super::*;
struct CustomContext(String);
impl juniper::Context for CustomContext {}
#[derive(GraphQLEnum)]
#[graphql(context = CustomContext)]
enum Character {
Human,
Droid,
}
struct QueryRoot;
#[graphql_object(context = CustomContext)]
impl QueryRoot {
fn pass_as_is(character: Character, _ctx: &CustomContext) -> Character {
character
}
}
#[tokio::test]
async fn resolves() {
const DOC: &str = r#"{
passAsIs(character: HUMAN)
}"#;
let schema = schema(QueryRoot);
let ctx = CustomContext("ctx".into());
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &ctx).await,
Ok((graphql_value!({"passAsIs": "HUMAN"}), vec![])),
);
}
}

View file

@ -4,7 +4,7 @@ use std::marker::PhantomData;
use juniper::{ use juniper::{
execute, graphql_interface, graphql_object, graphql_value, graphql_vars, DefaultScalarValue, execute, graphql_interface, graphql_object, graphql_value, graphql_vars, DefaultScalarValue,
FieldError, FieldResult, GraphQLObject, GraphQLUnion, IntoFieldError, ScalarValue, FieldError, FieldResult, GraphQLObject, GraphQLUnion, IntoFieldError, ScalarValue, ID,
}; };
use crate::util::{schema, schema_with_scalar}; use crate::util::{schema, schema_with_scalar};
@ -2539,6 +2539,537 @@ mod nullable_argument_subtyping {
} }
} }
mod simple_subtyping {
use super::*;
#[graphql_interface(for = [ResourceValue, Endpoint])]
struct Node {
id: Option<ID>,
}
#[graphql_interface(impl = NodeValue, for = Endpoint)]
struct Resource {
id: ID,
url: Option<String>,
}
#[derive(GraphQLObject)]
#[graphql(impl = [ResourceValue, NodeValue])]
struct Endpoint {
id: ID,
url: String,
}
struct QueryRoot;
#[graphql_object]
impl QueryRoot {
fn node() -> NodeValue {
Endpoint {
id: ID::from("1".to_owned()),
url: "2".to_owned(),
}
.into()
}
fn resource() -> ResourceValue {
Endpoint {
id: ID::from("3".to_owned()),
url: "4".to_owned(),
}
.into()
}
}
#[tokio::test]
async fn is_graphql_interface() {
for name in ["Node", "Resource"] {
let doc = format!(
r#"{{
__type(name: "{}") {{
kind
}}
}}"#,
name,
);
let schema = schema(QueryRoot);
assert_eq!(
execute(&doc, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"__type": {"kind": "INTERFACE"}}), vec![])),
);
}
}
#[tokio::test]
async fn resolves_node() {
const DOC: &str = r#"{
node {
id
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"node": {"id": "1"}}), vec![])),
);
}
#[tokio::test]
async fn resolves_node_on_resource() {
const DOC: &str = r#"{
node {
... on Resource {
id
url
}
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"node": {
"id": "1",
"url": "2",
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_node_on_endpoint() {
const DOC: &str = r#"{
node {
... on Endpoint {
id
url
}
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"node": {
"id": "1",
"url": "2",
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_resource() {
const DOC: &str = r#"{
resource {
id
url
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"resource": {
"id": "3",
"url": "4",
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_resource_on_endpoint() {
const DOC: &str = r#"{
resource {
... on Endpoint {
id
url
}
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"resource": {
"id": "3",
"url": "4",
}}),
vec![],
)),
);
}
#[tokio::test]
async fn registers_possible_types() {
for name in ["Node", "Resource"] {
let doc = format!(
r#"{{
__type(name: "{}") {{
possibleTypes {{
kind
name
}}
}}
}}"#,
name,
);
let schema = schema(QueryRoot);
assert_eq!(
execute(&doc, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"__type": {"possibleTypes": [
{"kind": "OBJECT", "name": "Endpoint"},
]}}),
vec![],
)),
);
}
}
#[tokio::test]
async fn registers_interfaces() {
let schema = schema(QueryRoot);
for (name, interfaces) in [
("Node", graphql_value!([])),
(
"Resource",
graphql_value!([{"kind": "INTERFACE", "name": "Node"}]),
),
(
"Endpoint",
graphql_value!([
{"kind": "INTERFACE", "name": "Node"},
{"kind": "INTERFACE", "name": "Resource"},
]),
),
] {
let doc = format!(
r#"{{
__type(name: "{}") {{
interfaces {{
kind
name
}}
}}
}}"#,
name,
);
assert_eq!(
execute(&doc, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"__type": {"interfaces": interfaces}}),
vec![],
)),
);
}
}
}
mod branching_subtyping {
use super::*;
#[graphql_interface(for = [HumanValue, DroidValue, Luke, R2D2])]
struct Node {
id: ID,
}
#[graphql_interface(for = [HumanConnection, DroidConnection])]
struct Connection {
nodes: Vec<NodeValue>,
}
#[graphql_interface(impl = NodeValue, for = Luke)]
struct Human {
id: ID,
home_planet: String,
}
#[derive(GraphQLObject)]
#[graphql(impl = ConnectionValue)]
struct HumanConnection {
nodes: Vec<HumanValue>,
}
#[graphql_interface(impl = NodeValue, for = R2D2)]
struct Droid {
id: ID,
primary_function: String,
}
#[derive(GraphQLObject)]
#[graphql(impl = ConnectionValue)]
struct DroidConnection {
nodes: Vec<DroidValue>,
}
#[derive(GraphQLObject)]
#[graphql(impl = [HumanValue, NodeValue])]
struct Luke {
id: ID,
home_planet: String,
father: String,
}
#[derive(GraphQLObject)]
#[graphql(impl = [DroidValue, NodeValue])]
struct R2D2 {
id: ID,
primary_function: String,
charge: f64,
}
enum QueryRoot {
Luke,
R2D2,
}
#[graphql_object]
impl QueryRoot {
fn crew(&self) -> ConnectionValue {
match self {
Self::Luke => HumanConnection {
nodes: vec![Luke {
id: ID::new("1"),
home_planet: "earth".to_owned(),
father: "SPOILER".to_owned(),
}
.into()],
}
.into(),
Self::R2D2 => DroidConnection {
nodes: vec![R2D2 {
id: ID::new("2"),
primary_function: "roll".to_owned(),
charge: 146.0,
}
.into()],
}
.into(),
}
}
}
#[tokio::test]
async fn is_graphql_interface() {
for name in ["Node", "Connection", "Human", "Droid"] {
let doc = format!(
r#"{{
__type(name: "{}") {{
kind
}}
}}"#,
name,
);
let schema = schema(QueryRoot::Luke);
assert_eq!(
execute(&doc, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"__type": {"kind": "INTERFACE"}}), vec![])),
);
}
}
#[tokio::test]
async fn resolves_human_connection() {
const DOC: &str = r#"{
crew {
... on HumanConnection {
nodes {
id
homePlanet
}
}
}
}"#;
let schema = schema(QueryRoot::Luke);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"crew": {
"nodes": [{
"id": "1",
"homePlanet": "earth",
}],
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_human() {
const DOC: &str = r#"{
crew {
nodes {
... on Human {
id
homePlanet
}
}
}
}"#;
let schema = schema(QueryRoot::Luke);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"crew": {
"nodes": [{
"id": "1",
"homePlanet": "earth",
}],
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_luke() {
const DOC: &str = r#"{
crew {
nodes {
... on Luke {
id
homePlanet
father
}
}
}
}"#;
let schema = schema(QueryRoot::Luke);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"crew": {
"nodes": [{
"id": "1",
"homePlanet": "earth",
"father": "SPOILER",
}],
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_droid_connection() {
const DOC: &str = r#"{
crew {
... on DroidConnection {
nodes {
id
primaryFunction
}
}
}
}"#;
let schema = schema(QueryRoot::R2D2);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"crew": {
"nodes": [{
"id": "2",
"primaryFunction": "roll",
}],
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_droid() {
const DOC: &str = r#"{
crew {
nodes {
... on Droid {
id
primaryFunction
}
}
}
}"#;
let schema = schema(QueryRoot::R2D2);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"crew": {
"nodes": [{
"id": "2",
"primaryFunction": "roll",
}],
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_r2d2() {
const DOC: &str = r#"{
crew {
nodes {
... on R2D2 {
id
primaryFunction
charge
}
}
}
}"#;
let schema = schema(QueryRoot::R2D2);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"crew": {
"nodes": [{
"id": "2",
"primaryFunction": "roll",
"charge": 146.0,
}],
}}),
vec![],
)),
);
}
}
mod preserves_visibility { mod preserves_visibility {
use super::*; use super::*;

View file

@ -3,7 +3,7 @@
use juniper::{ use juniper::{
execute, graphql_interface, graphql_object, graphql_value, graphql_vars, DefaultScalarValue, execute, graphql_interface, graphql_object, graphql_value, graphql_vars, DefaultScalarValue,
Executor, FieldError, FieldResult, GraphQLInputObject, GraphQLObject, GraphQLUnion, Executor, FieldError, FieldResult, GraphQLInputObject, GraphQLObject, GraphQLUnion,
IntoFieldError, ScalarValue, IntoFieldError, ScalarValue, ID,
}; };
use crate::util::{schema, schema_with_scalar}; use crate::util::{schema, schema_with_scalar};
@ -3378,6 +3378,537 @@ mod nullable_argument_subtyping {
} }
} }
mod simple_subtyping {
use super::*;
#[graphql_interface(for = [ResourceValue, Endpoint])]
trait Node {
fn id() -> Option<ID>;
}
#[graphql_interface(impl = NodeValue, for = Endpoint)]
trait Resource {
fn id(&self) -> &ID;
fn url(&self) -> Option<&str>;
}
#[derive(GraphQLObject)]
#[graphql(impl = [ResourceValue, NodeValue])]
struct Endpoint {
id: ID,
url: String,
}
struct QueryRoot;
#[graphql_object]
impl QueryRoot {
fn node() -> NodeValue {
Endpoint {
id: ID::from("1".to_owned()),
url: "2".to_owned(),
}
.into()
}
fn resource() -> ResourceValue {
Endpoint {
id: ID::from("3".to_owned()),
url: "4".to_owned(),
}
.into()
}
}
#[tokio::test]
async fn is_graphql_interface() {
for name in ["Node", "Resource"] {
let doc = format!(
r#"{{
__type(name: "{}") {{
kind
}}
}}"#,
name,
);
let schema = schema(QueryRoot);
assert_eq!(
execute(&doc, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"__type": {"kind": "INTERFACE"}}), vec![])),
);
}
}
#[tokio::test]
async fn resolves_node() {
const DOC: &str = r#"{
node {
id
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"node": {"id": "1"}}), vec![])),
);
}
#[tokio::test]
async fn resolves_node_on_resource() {
const DOC: &str = r#"{
node {
... on Resource {
id
url
}
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"node": {
"id": "1",
"url": "2",
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_node_on_endpoint() {
const DOC: &str = r#"{
node {
... on Endpoint {
id
url
}
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"node": {
"id": "1",
"url": "2",
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_resource() {
const DOC: &str = r#"{
resource {
id
url
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"resource": {
"id": "3",
"url": "4",
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_resource_on_endpoint() {
const DOC: &str = r#"{
resource {
... on Endpoint {
id
url
}
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"resource": {
"id": "3",
"url": "4",
}}),
vec![],
)),
);
}
#[tokio::test]
async fn registers_possible_types() {
for name in ["Node", "Resource"] {
let doc = format!(
r#"{{
__type(name: "{}") {{
possibleTypes {{
kind
name
}}
}}
}}"#,
name,
);
let schema = schema(QueryRoot);
assert_eq!(
execute(&doc, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"__type": {"possibleTypes": [
{"kind": "OBJECT", "name": "Endpoint"},
]}}),
vec![],
)),
);
}
}
#[tokio::test]
async fn registers_interfaces() {
let schema = schema(QueryRoot);
for (name, interfaces) in [
("Node", graphql_value!([])),
(
"Resource",
graphql_value!([{"kind": "INTERFACE", "name": "Node"}]),
),
(
"Endpoint",
graphql_value!([
{"kind": "INTERFACE", "name": "Node"},
{"kind": "INTERFACE", "name": "Resource"},
]),
),
] {
let doc = format!(
r#"{{
__type(name: "{}") {{
interfaces {{
kind
name
}}
}}
}}"#,
name,
);
assert_eq!(
execute(&doc, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"__type": {"interfaces": interfaces}}),
vec![],
)),
);
}
}
}
mod branching_subtyping {
use super::*;
#[graphql_interface(for = [HumanValue, DroidValue, Luke, R2D2])]
trait Node {
fn id() -> ID;
}
#[graphql_interface(for = [HumanConnection, DroidConnection])]
trait Connection {
fn nodes(&self) -> &[NodeValue];
}
#[graphql_interface(impl = NodeValue, for = Luke)]
trait Human {
fn id(&self) -> &ID;
fn home_planet(&self) -> &str;
}
#[derive(GraphQLObject)]
#[graphql(impl = ConnectionValue)]
struct HumanConnection {
nodes: Vec<HumanValue>,
}
#[graphql_interface(impl = NodeValue, for = R2D2)]
trait Droid {
fn id() -> ID;
fn primary_function() -> String;
}
#[derive(GraphQLObject)]
#[graphql(impl = ConnectionValue)]
struct DroidConnection {
nodes: Vec<DroidValue>,
}
#[derive(GraphQLObject)]
#[graphql(impl = [HumanValue, NodeValue])]
struct Luke {
id: ID,
home_planet: String,
father: String,
}
#[derive(GraphQLObject)]
#[graphql(impl = [DroidValue, NodeValue])]
struct R2D2 {
id: ID,
primary_function: String,
charge: f64,
}
enum QueryRoot {
Luke,
R2D2,
}
#[graphql_object]
impl QueryRoot {
fn crew(&self) -> ConnectionValue {
match self {
Self::Luke => HumanConnection {
nodes: vec![Luke {
id: ID::new("1"),
home_planet: "earth".to_owned(),
father: "SPOILER".to_owned(),
}
.into()],
}
.into(),
Self::R2D2 => DroidConnection {
nodes: vec![R2D2 {
id: ID::new("2"),
primary_function: "roll".to_owned(),
charge: 146.0,
}
.into()],
}
.into(),
}
}
}
#[tokio::test]
async fn is_graphql_interface() {
for name in ["Node", "Connection", "Human", "Droid"] {
let doc = format!(
r#"{{
__type(name: "{}") {{
kind
}}
}}"#,
name,
);
let schema = schema(QueryRoot::Luke);
assert_eq!(
execute(&doc, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"__type": {"kind": "INTERFACE"}}), vec![])),
);
}
}
#[tokio::test]
async fn resolves_human_connection() {
const DOC: &str = r#"{
crew {
... on HumanConnection {
nodes {
id
homePlanet
}
}
}
}"#;
let schema = schema(QueryRoot::Luke);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"crew": {
"nodes": [{
"id": "1",
"homePlanet": "earth",
}],
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_human() {
const DOC: &str = r#"{
crew {
nodes {
... on Human {
id
homePlanet
}
}
}
}"#;
let schema = schema(QueryRoot::Luke);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"crew": {
"nodes": [{
"id": "1",
"homePlanet": "earth",
}],
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_luke() {
const DOC: &str = r#"{
crew {
nodes {
... on Luke {
id
homePlanet
father
}
}
}
}"#;
let schema = schema(QueryRoot::Luke);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"crew": {
"nodes": [{
"id": "1",
"homePlanet": "earth",
"father": "SPOILER",
}],
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_droid_connection() {
const DOC: &str = r#"{
crew {
... on DroidConnection {
nodes {
id
primaryFunction
}
}
}
}"#;
let schema = schema(QueryRoot::R2D2);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"crew": {
"nodes": [{
"id": "2",
"primaryFunction": "roll",
}],
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_droid() {
const DOC: &str = r#"{
crew {
nodes {
... on Droid {
id
primaryFunction
}
}
}
}"#;
let schema = schema(QueryRoot::R2D2);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"crew": {
"nodes": [{
"id": "2",
"primaryFunction": "roll",
}],
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_r2d2() {
const DOC: &str = r#"{
crew {
nodes {
... on R2D2 {
id
primaryFunction
charge
}
}
}
}"#;
let schema = schema(QueryRoot::R2D2);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"crew": {
"nodes": [{
"id": "2",
"primaryFunction": "roll",
"charge": 146.0,
}],
}}),
vec![],
)),
);
}
}
mod preserves_visibility { mod preserves_visibility {
use super::*; use super::*;

View file

@ -4,7 +4,7 @@ use std::marker::PhantomData;
use juniper::{ use juniper::{
execute, graphql_object, graphql_value, graphql_vars, DefaultScalarValue, FieldError, execute, graphql_object, graphql_value, graphql_vars, DefaultScalarValue, FieldError,
FieldResult, GraphQLInterface, GraphQLObject, GraphQLUnion, IntoFieldError, ScalarValue, FieldResult, GraphQLInterface, GraphQLObject, GraphQLUnion, IntoFieldError, ScalarValue, ID,
}; };
use crate::util::{schema, schema_with_scalar}; use crate::util::{schema, schema_with_scalar};
@ -2559,6 +2559,543 @@ mod nullable_argument_subtyping {
} }
} }
mod simple_subtyping {
use super::*;
#[derive(GraphQLInterface)]
#[graphql(for = [ResourceValue, Endpoint])]
struct Node {
id: Option<ID>,
}
#[derive(GraphQLInterface)]
#[graphql(impl = NodeValue, for = Endpoint)]
struct Resource {
id: ID,
url: Option<String>,
}
#[derive(GraphQLObject)]
#[graphql(impl = [ResourceValue, NodeValue])]
struct Endpoint {
id: ID,
url: String,
}
struct QueryRoot;
#[graphql_object]
impl QueryRoot {
fn node() -> NodeValue {
Endpoint {
id: ID::from("1".to_owned()),
url: "2".to_owned(),
}
.into()
}
fn resource() -> ResourceValue {
Endpoint {
id: ID::from("3".to_owned()),
url: "4".to_owned(),
}
.into()
}
}
#[tokio::test]
async fn is_graphql_interface() {
for name in ["Node", "Resource"] {
let doc = format!(
r#"{{
__type(name: "{}") {{
kind
}}
}}"#,
name,
);
let schema = schema(QueryRoot);
assert_eq!(
execute(&doc, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"__type": {"kind": "INTERFACE"}}), vec![])),
);
}
}
#[tokio::test]
async fn resolves_node() {
const DOC: &str = r#"{
node {
id
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"node": {"id": "1"}}), vec![])),
);
}
#[tokio::test]
async fn resolves_node_on_resource() {
const DOC: &str = r#"{
node {
... on Resource {
id
url
}
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"node": {
"id": "1",
"url": "2",
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_node_on_endpoint() {
const DOC: &str = r#"{
node {
... on Endpoint {
id
url
}
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"node": {
"id": "1",
"url": "2",
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_resource() {
const DOC: &str = r#"{
resource {
id
url
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"resource": {
"id": "3",
"url": "4",
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_resource_on_endpoint() {
const DOC: &str = r#"{
resource {
... on Endpoint {
id
url
}
}
}"#;
let schema = schema(QueryRoot);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"resource": {
"id": "3",
"url": "4",
}}),
vec![],
)),
);
}
#[tokio::test]
async fn registers_possible_types() {
for name in ["Node", "Resource"] {
let doc = format!(
r#"{{
__type(name: "{}") {{
possibleTypes {{
kind
name
}}
}}
}}"#,
name,
);
let schema = schema(QueryRoot);
assert_eq!(
execute(&doc, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"__type": {"possibleTypes": [
{"kind": "OBJECT", "name": "Endpoint"},
]}}),
vec![],
)),
);
}
}
#[tokio::test]
async fn registers_interfaces() {
let schema = schema(QueryRoot);
for (name, interfaces) in [
("Node", graphql_value!([])),
(
"Resource",
graphql_value!([{"kind": "INTERFACE", "name": "Node"}]),
),
(
"Endpoint",
graphql_value!([
{"kind": "INTERFACE", "name": "Node"},
{"kind": "INTERFACE", "name": "Resource"},
]),
),
] {
let doc = format!(
r#"{{
__type(name: "{}") {{
interfaces {{
kind
name
}}
}}
}}"#,
name,
);
assert_eq!(
execute(&doc, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"__type": {"interfaces": interfaces}}),
vec![],
)),
);
}
}
}
mod branching_subtyping {
use super::*;
#[derive(GraphQLInterface)]
#[graphql(for = [HumanValue, DroidValue, Luke, R2D2])]
struct Node {
id: ID,
}
#[derive(GraphQLInterface)]
#[graphql(for = [HumanConnection, DroidConnection])]
struct Connection {
nodes: Vec<NodeValue>,
}
#[derive(GraphQLInterface)]
#[graphql(impl = NodeValue, for = Luke)]
struct Human {
id: ID,
home_planet: String,
}
#[derive(GraphQLObject)]
#[graphql(impl = ConnectionValue)]
struct HumanConnection {
nodes: Vec<HumanValue>,
}
#[derive(GraphQLInterface)]
#[graphql(impl = NodeValue, for = R2D2)]
struct Droid {
id: ID,
primary_function: String,
}
#[derive(GraphQLObject)]
#[graphql(impl = ConnectionValue)]
struct DroidConnection {
nodes: Vec<DroidValue>,
}
#[derive(GraphQLObject)]
#[graphql(impl = [HumanValue, NodeValue])]
struct Luke {
id: ID,
home_planet: String,
father: String,
}
#[derive(GraphQLObject)]
#[graphql(impl = [DroidValue, NodeValue])]
struct R2D2 {
id: ID,
primary_function: String,
charge: f64,
}
enum QueryRoot {
Luke,
R2D2,
}
#[graphql_object]
impl QueryRoot {
fn crew(&self) -> ConnectionValue {
match self {
Self::Luke => HumanConnection {
nodes: vec![Luke {
id: ID::new("1"),
home_planet: "earth".to_owned(),
father: "SPOILER".to_owned(),
}
.into()],
}
.into(),
Self::R2D2 => DroidConnection {
nodes: vec![R2D2 {
id: ID::new("2"),
primary_function: "roll".to_owned(),
charge: 146.0,
}
.into()],
}
.into(),
}
}
}
#[tokio::test]
async fn is_graphql_interface() {
for name in ["Node", "Connection", "Human", "Droid"] {
let doc = format!(
r#"{{
__type(name: "{}") {{
kind
}}
}}"#,
name,
);
let schema = schema(QueryRoot::Luke);
assert_eq!(
execute(&doc, None, &schema, &graphql_vars! {}, &()).await,
Ok((graphql_value!({"__type": {"kind": "INTERFACE"}}), vec![])),
);
}
}
#[tokio::test]
async fn resolves_human_connection() {
const DOC: &str = r#"{
crew {
... on HumanConnection {
nodes {
id
homePlanet
}
}
}
}"#;
let schema = schema(QueryRoot::Luke);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"crew": {
"nodes": [{
"id": "1",
"homePlanet": "earth",
}],
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_human() {
const DOC: &str = r#"{
crew {
nodes {
... on Human {
id
homePlanet
}
}
}
}"#;
let schema = schema(QueryRoot::Luke);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"crew": {
"nodes": [{
"id": "1",
"homePlanet": "earth",
}],
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_luke() {
const DOC: &str = r#"{
crew {
nodes {
... on Luke {
id
homePlanet
father
}
}
}
}"#;
let schema = schema(QueryRoot::Luke);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"crew": {
"nodes": [{
"id": "1",
"homePlanet": "earth",
"father": "SPOILER",
}],
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_droid_connection() {
const DOC: &str = r#"{
crew {
... on DroidConnection {
nodes {
id
primaryFunction
}
}
}
}"#;
let schema = schema(QueryRoot::R2D2);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"crew": {
"nodes": [{
"id": "2",
"primaryFunction": "roll",
}],
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_droid() {
const DOC: &str = r#"{
crew {
nodes {
... on Droid {
id
primaryFunction
}
}
}
}"#;
let schema = schema(QueryRoot::R2D2);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"crew": {
"nodes": [{
"id": "2",
"primaryFunction": "roll",
}],
}}),
vec![],
)),
);
}
#[tokio::test]
async fn resolves_r2d2() {
const DOC: &str = r#"{
crew {
nodes {
... on R2D2 {
id
primaryFunction
charge
}
}
}
}"#;
let schema = schema(QueryRoot::R2D2);
assert_eq!(
execute(DOC, None, &schema, &graphql_vars! {}, &()).await,
Ok((
graphql_value!({"crew": {
"nodes": [{
"id": "2",
"primaryFunction": "roll",
"charge": 146.0,
}],
}}),
vec![],
)),
);
}
}
mod preserves_visibility { mod preserves_visibility {
use super::*; use super::*;

View file

@ -1,6 +1,6 @@
mod derive_enum;
mod derive_input_object; mod derive_input_object;
mod derive_object_with_raw_idents; mod derive_object_with_raw_idents;
mod enum_derive;
mod interface_attr_struct; mod interface_attr_struct;
mod interface_attr_trait; mod interface_attr_trait;
mod interface_derive; mod interface_derive;