This commit is contained in:
parent
8a69e14c8b
commit
f363b0d79e
29 changed files with 211 additions and 63 deletions
juniper_codegen
tests/codegen/fail
interface
object
attr_field_double_underscored.rsattr_field_double_underscored.stderrattr_fields_duplicate.stderrattr_wrong_syntax.rsattr_wrong_syntax.stderr
subscription
argument_double_underscored.rsargument_double_underscored.stderrargument_non_input_type.rsargument_non_input_type.stderrargument_wrong_default_array.rsfield_double_underscored.rsfield_double_underscored.stderrfield_non_output_return_type.rsfield_not_async.rsfield_not_async.stderrfields_duplicate.rsfields_duplicate.stderrname_double_underscored.rsname_double_underscored.stderrwrong_syntax.rswrong_syntax.stderr
union
|
@ -10,7 +10,7 @@ All user visible changes to `juniper_codegen` crate will be documented in this f
|
||||||
|
|
||||||
### BC Breaks
|
### BC Breaks
|
||||||
|
|
||||||
- `#[graphql_object]` and `#[graphql_subscription]` expansions now preserve defined `impl` blocks "as is" and reuse defined methods in opaque way. ([#971])
|
- `#[graphql_object]` and `#[graphql_subscription]` expansions now preserve defined `impl` blocks "as is" and reuse defined methods in opaque way. ([#971], [#1245])
|
||||||
- Renamed `rename = "<policy>"` attribute argument to `rename_all = "<policy>"` (following `serde` style). ([#971])
|
- Renamed `rename = "<policy>"` attribute argument to `rename_all = "<policy>"` (following `serde` style). ([#971])
|
||||||
- Redesigned `#[graphql_interface]` macro: ([#1009])
|
- Redesigned `#[graphql_interface]` macro: ([#1009])
|
||||||
- Removed support for `dyn` attribute argument (interface values as trait objects).
|
- Removed support for `dyn` attribute argument (interface values as trait objects).
|
||||||
|
@ -61,6 +61,7 @@ All user visible changes to `juniper_codegen` crate will be documented in this f
|
||||||
[#1051]: /../../issues/1051
|
[#1051]: /../../issues/1051
|
||||||
[#1054]: /../../pull/1054
|
[#1054]: /../../pull/1054
|
||||||
[#1157]: /../../pull/1157
|
[#1157]: /../../pull/1157
|
||||||
|
[#1245]: /../../pull/1245
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,9 @@ use std::fmt;
|
||||||
|
|
||||||
use proc_macro2::Span;
|
use proc_macro2::Span;
|
||||||
|
|
||||||
pub(crate) use self::polyfill::{abort_if_dirty, emit_error, entry_point, Diagnostic, ResultExt};
|
pub(crate) use self::polyfill::{
|
||||||
|
abort_if_dirty, emit_error, entry_point, entry_point_with_preserved_body, Diagnostic, ResultExt,
|
||||||
|
};
|
||||||
|
|
||||||
/// URL of the GraphQL specification (October 2021 Edition).
|
/// URL of the GraphQL specification (October 2021 Edition).
|
||||||
pub(crate) const SPEC_URL: &str = "https://spec.graphql.org/October2021";
|
pub(crate) const SPEC_URL: &str = "https://spec.graphql.org/October2021";
|
||||||
|
@ -258,6 +260,18 @@ mod polyfill {
|
||||||
|
|
||||||
/// This is the entry point for a macro to support [`Diagnostic`]s.
|
/// This is the entry point for a macro to support [`Diagnostic`]s.
|
||||||
pub(crate) fn entry_point<F>(f: F) -> proc_macro::TokenStream
|
pub(crate) fn entry_point<F>(f: F) -> proc_macro::TokenStream
|
||||||
|
where
|
||||||
|
F: FnOnce() -> proc_macro::TokenStream + UnwindSafe,
|
||||||
|
{
|
||||||
|
entry_point_with_preserved_body(TokenStream::new(), f)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This is the entry point for an attribute macro to support [`Diagnostic`]s, while preserving
|
||||||
|
/// the `body` input [`proc_macro::TokenStream`] on errors.
|
||||||
|
pub(crate) fn entry_point_with_preserved_body<F>(
|
||||||
|
body: impl Into<TokenStream>,
|
||||||
|
f: F,
|
||||||
|
) -> proc_macro::TokenStream
|
||||||
where
|
where
|
||||||
F: FnOnce() -> proc_macro::TokenStream + UnwindSafe,
|
F: FnOnce() -> proc_macro::TokenStream + UnwindSafe,
|
||||||
{
|
{
|
||||||
|
@ -267,7 +281,9 @@ mod polyfill {
|
||||||
ENTERED_ENTRY_POINT.with(|flag| flag.set(flag.get() - 1));
|
ENTERED_ENTRY_POINT.with(|flag| flag.set(flag.get() - 1));
|
||||||
|
|
||||||
let gen_error = || {
|
let gen_error = || {
|
||||||
quote! { #( #err_storage )* }
|
let body = body.into();
|
||||||
|
|
||||||
|
quote! { #body #( #err_storage )* }
|
||||||
};
|
};
|
||||||
|
|
||||||
match caught {
|
match caught {
|
||||||
|
|
|
@ -756,7 +756,7 @@ pub fn derive_scalar(input: TokenStream) -> TokenStream {
|
||||||
/// [`ScalarValue`]: juniper::ScalarValue
|
/// [`ScalarValue`]: juniper::ScalarValue
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
pub fn graphql_scalar(attr: TokenStream, body: TokenStream) -> TokenStream {
|
pub fn graphql_scalar(attr: TokenStream, body: TokenStream) -> TokenStream {
|
||||||
diagnostic::entry_point(|| {
|
diagnostic::entry_point_with_preserved_body(body.clone(), || {
|
||||||
graphql_scalar::attr::expand(attr.into(), body.into())
|
graphql_scalar::attr::expand(attr.into(), body.into())
|
||||||
.unwrap_or_abort()
|
.unwrap_or_abort()
|
||||||
.into()
|
.into()
|
||||||
|
@ -1318,7 +1318,7 @@ pub fn derive_scalar_value(input: TokenStream) -> TokenStream {
|
||||||
/// [4]: https://doc.rust-lang.org/stable/std/primitive.unit.html
|
/// [4]: https://doc.rust-lang.org/stable/std/primitive.unit.html
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
pub fn graphql_interface(attr: TokenStream, body: TokenStream) -> TokenStream {
|
pub fn graphql_interface(attr: TokenStream, body: TokenStream) -> TokenStream {
|
||||||
diagnostic::entry_point(|| {
|
diagnostic::entry_point_with_preserved_body(body.clone(), || {
|
||||||
self::graphql_interface::attr::expand(attr.into(), body.into())
|
self::graphql_interface::attr::expand(attr.into(), body.into())
|
||||||
.unwrap_or_abort()
|
.unwrap_or_abort()
|
||||||
.into()
|
.into()
|
||||||
|
@ -1825,7 +1825,7 @@ pub fn derive_object(body: TokenStream) -> TokenStream {
|
||||||
/// [1]: https://spec.graphql.org/October2021#sec-Objects
|
/// [1]: https://spec.graphql.org/October2021#sec-Objects
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
pub fn graphql_object(attr: TokenStream, body: TokenStream) -> TokenStream {
|
pub fn graphql_object(attr: TokenStream, body: TokenStream) -> TokenStream {
|
||||||
diagnostic::entry_point(|| {
|
diagnostic::entry_point_with_preserved_body(body.clone(), || {
|
||||||
self::graphql_object::attr::expand(attr.into(), body.into())
|
self::graphql_object::attr::expand(attr.into(), body.into())
|
||||||
.unwrap_or_abort()
|
.unwrap_or_abort()
|
||||||
.into()
|
.into()
|
||||||
|
@ -1879,7 +1879,7 @@ pub fn graphql_object(attr: TokenStream, body: TokenStream) -> TokenStream {
|
||||||
/// [1]: https://spec.graphql.org/October2021#sec-Subscription
|
/// [1]: https://spec.graphql.org/October2021#sec-Subscription
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
pub fn graphql_subscription(attr: TokenStream, body: TokenStream) -> TokenStream {
|
pub fn graphql_subscription(attr: TokenStream, body: TokenStream) -> TokenStream {
|
||||||
diagnostic::entry_point(|| {
|
diagnostic::entry_point_with_preserved_body(body.clone(), || {
|
||||||
self::graphql_subscription::attr::expand(attr.into(), body.into())
|
self::graphql_subscription::attr::expand(attr.into(), body.into())
|
||||||
.unwrap_or_abort()
|
.unwrap_or_abort()
|
||||||
.into()
|
.into()
|
||||||
|
@ -2486,7 +2486,7 @@ pub fn derive_union(body: TokenStream) -> TokenStream {
|
||||||
/// [4]: https://doc.rust-lang.org/stable/std/primitive.unit.html
|
/// [4]: https://doc.rust-lang.org/stable/std/primitive.unit.html
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
pub fn graphql_union(attr: TokenStream, body: TokenStream) -> TokenStream {
|
pub fn graphql_union(attr: TokenStream, body: TokenStream) -> TokenStream {
|
||||||
diagnostic::entry_point(|| {
|
diagnostic::entry_point_with_preserved_body(body.clone(), || {
|
||||||
self::graphql_union::attr::expand(attr.into(), body.into())
|
self::graphql_union::attr::expand(attr.into(), body.into())
|
||||||
.unwrap_or_abort()
|
.unwrap_or_abort()
|
||||||
.into()
|
.into()
|
||||||
|
|
|
@ -4,3 +4,9 @@ error: GraphQL interface must have a different name for each field
|
||||||
|
|
|
|
||||||
4 | struct Character {
|
4 | struct Character {
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
|
error: cannot find attribute `graphql` in this scope
|
||||||
|
--> fail/interface/struct/attr_fields_duplicate.rs:7:7
|
||||||
|
|
|
||||||
|
7 | #[graphql(name = "id")]
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
@ -4,3 +4,9 @@ error: GraphQL interface must have a different name for each field
|
||||||
|
|
|
|
||||||
4 | trait Character {
|
4 | trait Character {
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
|
error: cannot find attribute `graphql` in this scope
|
||||||
|
--> fail/interface/trait/fields_duplicate.rs:7:7
|
||||||
|
|
|
||||||
|
7 | #[graphql(name = "id")]
|
||||||
|
| ^^^^^^^
|
||||||
|
|
13
tests/codegen/fail/interface/trait/wrong_syntax.rs
Normal file
13
tests/codegen/fail/interface/trait/wrong_syntax.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
use juniper::graphql_interface;
|
||||||
|
|
||||||
|
#[graphql_interface]
|
||||||
|
trait Character {
|
||||||
|
fn id(&self) -> &str;
|
||||||
|
|
||||||
|
#[graphql(ignore)]
|
||||||
|
fn id2(&self) -> &str {
|
||||||
|
self.self.id()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
22
tests/codegen/fail/interface/trait/wrong_syntax.stderr
Normal file
22
tests/codegen/fail/interface/trait/wrong_syntax.stderr
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
error: #[graphql_interface] attribute is applicable to trait and struct definitions only
|
||||||
|
--> fail/interface/trait/wrong_syntax.rs:3:1
|
||||||
|
|
|
||||||
|
3 | #[graphql_interface]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in the attribute macro `graphql_interface` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: cannot find attribute `graphql` in this scope
|
||||||
|
--> fail/interface/trait/wrong_syntax.rs:7:7
|
||||||
|
|
|
||||||
|
7 | #[graphql(ignore)]
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
|
error[E0609]: no field `self` on type `&Self`
|
||||||
|
--> fail/interface/trait/wrong_syntax.rs:9:14
|
||||||
|
|
|
||||||
|
4 | trait Character {
|
||||||
|
| --------------- type parameter 'Self' declared here
|
||||||
|
...
|
||||||
|
9 | self.self.id()
|
||||||
|
| ^^^^
|
|
@ -3,7 +3,7 @@ use juniper::graphql_object;
|
||||||
struct ObjA;
|
struct ObjA;
|
||||||
|
|
||||||
#[graphql_object]
|
#[graphql_object]
|
||||||
impl Character for ObjA {
|
impl ObjA {
|
||||||
fn __id(&self) -> &str {
|
fn __id(&self) -> &str {
|
||||||
"funA"
|
"funA"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
error: #[graphql_object] attribute is applicable to non-trait `impl` blocks only
|
error: All types and directives defined within a schema must not have a name which begins with `__` (two underscores), as this is used exclusively by GraphQL’s introspection system.
|
||||||
--> fail/object/attr_field_double_underscored.rs:5:1
|
· note: https://spec.graphql.org/October2021#sec-Schema
|
||||||
|
--> fail/object/attr_field_double_underscored.rs:7:8
|
||||||
|
|
|
|
||||||
5 | #[graphql_object]
|
7 | fn __id(&self) -> &str {
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^
|
||||||
|
|
|
||||||
= note: this error originates in the attribute macro `graphql_object` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
|
@ -4,3 +4,9 @@ error: GraphQL object must have a different name for each field
|
||||||
|
|
|
|
||||||
6 | impl ObjA {
|
6 | impl ObjA {
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
|
error: cannot find attribute `graphql` in this scope
|
||||||
|
--> fail/object/attr_fields_duplicate.rs:11:7
|
||||||
|
|
|
||||||
|
11 | #[graphql(name = "id")]
|
||||||
|
| ^^^^^^^
|
||||||
|
|
14
tests/codegen/fail/object/attr_wrong_syntax.rs
Normal file
14
tests/codegen/fail/object/attr_wrong_syntax.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
use juniper::graphql_object;
|
||||||
|
|
||||||
|
struct MyObject {
|
||||||
|
my_field: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[graphql_object]
|
||||||
|
impl MyObject {
|
||||||
|
fn my_field(&self) -> i32 {
|
||||||
|
self.self.my_field
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
15
tests/codegen/fail/object/attr_wrong_syntax.stderr
Normal file
15
tests/codegen/fail/object/attr_wrong_syntax.stderr
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
error: #[graphql_object] attribute is applicable to non-trait `impl` blocks only
|
||||||
|
--> fail/object/attr_wrong_syntax.rs:7:1
|
||||||
|
|
|
||||||
|
7 | #[graphql_object]
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in the attribute macro `graphql_object` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error[E0609]: no field `self` on type `&MyObject`
|
||||||
|
--> fail/object/attr_wrong_syntax.rs:10:14
|
||||||
|
|
|
||||||
|
10 | self.self.my_field
|
||||||
|
| ^^^^ unknown field
|
||||||
|
|
|
||||||
|
= note: available fields are: `my_field`
|
|
@ -1,14 +1,15 @@
|
||||||
use std::pin::Pin;
|
use std::{future, pin::Pin};
|
||||||
|
|
||||||
|
use futures::{stream, Stream};
|
||||||
use juniper::graphql_subscription;
|
use juniper::graphql_subscription;
|
||||||
|
|
||||||
type Stream<'a, I> = Pin<Box<dyn futures::Stream<Item = I> + Send + 'a>>;
|
type BoxStream<'a, I> = Pin<Box<dyn Stream<Item = I> + Send + 'a>>;
|
||||||
|
|
||||||
struct Obj;
|
struct Obj;
|
||||||
|
|
||||||
#[graphql_subscription]
|
#[graphql_subscription]
|
||||||
impl Obj {
|
impl Obj {
|
||||||
async fn id(&self, __num: i32) -> Stream<'static, &'static str> {
|
async fn id(&self, __num: i32) -> BoxStream<'static, &'static str> {
|
||||||
Box::pin(stream::once(future::ready("funA")))
|
Box::pin(stream::once(future::ready("funA")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
error: All types and directives defined within a schema must not have a name which begins with `__` (two underscores), as this is used exclusively by GraphQL’s introspection system.
|
error: All types and directives defined within a schema must not have a name which begins with `__` (two underscores), as this is used exclusively by GraphQL’s introspection system.
|
||||||
· note: https://spec.graphql.org/October2021#sec-Schema
|
· note: https://spec.graphql.org/October2021#sec-Schema
|
||||||
--> fail/subscription/argument_double_underscored.rs:11:24
|
--> fail/subscription/argument_double_underscored.rs:12:24
|
||||||
|
|
|
|
||||||
11 | async fn id(&self, __num: i32) -> Stream<'static, &'static str> {
|
12 | async fn id(&self, __num: i32) -> BoxStream<'static, &'static str> {
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use std::pin::Pin;
|
use std::{future, pin::Pin};
|
||||||
|
|
||||||
use futures::{future, stream};
|
use futures::{stream, Stream};
|
||||||
use juniper::{graphql_subscription, GraphQLObject};
|
use juniper::{graphql_subscription, GraphQLObject};
|
||||||
|
|
||||||
type Stream<'a, I> = Pin<Box<dyn futures::Stream<Item = I> + Send + 'a>>;
|
type BoxStream<'a, I> = Pin<Box<dyn Stream<Item = I> + Send + 'a>>;
|
||||||
|
|
||||||
#[derive(GraphQLObject)]
|
#[derive(GraphQLObject)]
|
||||||
struct ObjA {
|
struct ObjA {
|
||||||
|
@ -14,7 +14,7 @@ struct ObjB;
|
||||||
|
|
||||||
#[graphql_subscription]
|
#[graphql_subscription]
|
||||||
impl ObjB {
|
impl ObjB {
|
||||||
async fn id(&self, obj: ObjA) -> Stream<'static, &'static str> {
|
async fn id(&self, obj: ObjA) -> BoxStream<'static, &'static str> {
|
||||||
Box::pin(stream::once(future::ready("funA")))
|
Box::pin(stream::once(future::ready("funA")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
warning: unused variable: `obj`
|
warning: unused variable: `obj`
|
||||||
--> fail/subscription/argument_non_input_type.rs:17:24
|
--> fail/subscription/argument_non_input_type.rs:17:24
|
||||||
|
|
|
|
||||||
17 | async fn id(&self, obj: ObjA) -> Stream<'static, &'static str> {
|
17 | async fn id(&self, obj: ObjA) -> BoxStream<'static, &'static str> {
|
||||||
| ^^^ help: if this is intentional, prefix it with an underscore: `_obj`
|
| ^^^ help: if this is intentional, prefix it with an underscore: `_obj`
|
||||||
|
|
|
|
||||||
= note: `#[warn(unused_variables)]` on by default
|
= note: `#[warn(unused_variables)]` on by default
|
||||||
|
@ -9,7 +9,7 @@ warning: unused variable: `obj`
|
||||||
error[E0277]: the trait bound `ObjA: IsInputType<__S>` is not satisfied
|
error[E0277]: the trait bound `ObjA: IsInputType<__S>` is not satisfied
|
||||||
--> fail/subscription/argument_non_input_type.rs:17:29
|
--> fail/subscription/argument_non_input_type.rs:17:29
|
||||||
|
|
|
|
||||||
17 | async fn id(&self, obj: ObjA) -> Stream<'static, &'static str> {
|
17 | async fn id(&self, obj: ObjA) -> BoxStream<'static, &'static str> {
|
||||||
| ^^^^ the trait `IsInputType<__S>` is not implemented for `ObjA`
|
| ^^^^ the trait `IsInputType<__S>` is not implemented for `ObjA`
|
||||||
|
|
|
|
||||||
= help: the following other types implement trait `IsInputType<S>`:
|
= help: the following other types implement trait `IsInputType<S>`:
|
||||||
|
@ -29,7 +29,7 @@ error[E0277]: the trait bound `ObjA: FromInputValue<__S>` is not satisfied
|
||||||
15 | #[graphql_subscription]
|
15 | #[graphql_subscription]
|
||||||
| ----------------------- required by a bound introduced by this call
|
| ----------------------- required by a bound introduced by this call
|
||||||
16 | impl ObjB {
|
16 | impl ObjB {
|
||||||
17 | async fn id(&self, obj: ObjA) -> Stream<'static, &'static str> {
|
17 | async fn id(&self, obj: ObjA) -> BoxStream<'static, &'static str> {
|
||||||
| ^^^^ the trait `FromInputValue<__S>` is not implemented for `ObjA`
|
| ^^^^ the trait `FromInputValue<__S>` is not implemented for `ObjA`
|
||||||
|
|
|
|
||||||
= help: the following other types implement trait `FromInputValue<S>`:
|
= help: the following other types implement trait `FromInputValue<S>`:
|
||||||
|
@ -72,7 +72,7 @@ error[E0277]: the trait bound `ObjA: FromInputValue<__S>` is not satisfied
|
||||||
error[E0277]: the trait bound `ObjA: FromInputValue<__S>` is not satisfied
|
error[E0277]: the trait bound `ObjA: FromInputValue<__S>` is not satisfied
|
||||||
--> fail/subscription/argument_non_input_type.rs:17:29
|
--> fail/subscription/argument_non_input_type.rs:17:29
|
||||||
|
|
|
|
||||||
17 | async fn id(&self, obj: ObjA) -> Stream<'static, &'static str> {
|
17 | async fn id(&self, obj: ObjA) -> BoxStream<'static, &'static str> {
|
||||||
| ^^^^ the trait `FromInputValue<__S>` is not implemented for `ObjA`
|
| ^^^^ the trait `FromInputValue<__S>` is not implemented for `ObjA`
|
||||||
|
|
|
|
||||||
= help: the following other types implement trait `FromInputValue<S>`:
|
= help: the following other types implement trait `FromInputValue<S>`:
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use std::pin::Pin;
|
use std::{future, pin::Pin};
|
||||||
|
|
||||||
use futures::{future, stream};
|
use futures::{stream, Stream};
|
||||||
use juniper::graphql_subscription;
|
use juniper::graphql_subscription;
|
||||||
|
|
||||||
type Stream<'a, I> = Pin<Box<dyn futures::Stream<Item = I> + Send + 'a>>;
|
type BoxStream<'a, I> = Pin<Box<dyn Stream<Item = I> + Send + 'a>>;
|
||||||
|
|
||||||
struct ObjA;
|
struct ObjA;
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ impl ObjA {
|
||||||
async fn wrong(
|
async fn wrong(
|
||||||
&self,
|
&self,
|
||||||
#[graphql(default = [true, false, false])] input: [bool; 2],
|
#[graphql(default = [true, false, false])] input: [bool; 2],
|
||||||
) -> Stream<'static, bool> {
|
) -> BoxStream<'static, bool> {
|
||||||
Box::pin(stream::once(future::ready(input[0])))
|
Box::pin(stream::once(future::ready(input[0])))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
use std::pin::Pin;
|
use std::{future, pin::Pin};
|
||||||
|
|
||||||
|
use futures::{stream, Stream};
|
||||||
use juniper::graphql_subscription;
|
use juniper::graphql_subscription;
|
||||||
|
|
||||||
type Stream<'a, I> = Pin<Box<dyn futures::Stream<Item = I> + Send + 'a>>;
|
type BoxStream<'a, I> = Pin<Box<dyn Stream<Item = I> + Send + 'a>>;
|
||||||
|
|
||||||
struct ObjA;
|
struct ObjA;
|
||||||
|
|
||||||
#[graphql_subscription]
|
#[graphql_subscription]
|
||||||
impl Character for ObjA {
|
impl ObjA {
|
||||||
async fn __id() -> Stream<'static, &'static str> {
|
async fn __id() -> BoxStream<'static, &'static str> {
|
||||||
Box::pin(stream::once(future::ready("funA")))
|
Box::pin(stream::once(future::ready("funA")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
error: #[graphql_subscription] attribute is applicable to non-trait `impl` blocks only
|
error: All types and directives defined within a schema must not have a name which begins with `__` (two underscores), as this is used exclusively by GraphQL’s introspection system.
|
||||||
--> fail/subscription/field_double_underscored.rs:9:1
|
· note: https://spec.graphql.org/October2021#sec-Schema
|
||||||
|
|
--> fail/subscription/field_double_underscored.rs:12:14
|
||||||
9 | #[graphql_subscription]
|
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
12 | async fn __id() -> BoxStream<'static, &'static str> {
|
||||||
|
|
| ^^^^
|
||||||
= note: this error originates in the attribute macro `graphql_subscription` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use std::pin::Pin;
|
use std::{future, pin::Pin};
|
||||||
|
|
||||||
use futures::{future, stream};
|
use futures::{stream, Stream};
|
||||||
use juniper::{graphql_subscription, GraphQLInputObject};
|
use juniper::{graphql_subscription, GraphQLInputObject};
|
||||||
|
|
||||||
type Stream<'a, I> = Pin<Box<dyn futures::Stream<Item = I> + Send + 'a>>;
|
type BoxStream<'a, I> = Pin<Box<dyn Stream<Item = I> + Send + 'a>>;
|
||||||
|
|
||||||
#[derive(GraphQLInputObject)]
|
#[derive(GraphQLInputObject)]
|
||||||
struct ObjB {
|
struct ObjB {
|
||||||
|
@ -14,7 +14,7 @@ struct ObjA;
|
||||||
|
|
||||||
#[graphql_subscription]
|
#[graphql_subscription]
|
||||||
impl ObjA {
|
impl ObjA {
|
||||||
async fn id(&self) -> Stream<'static, ObjB> {
|
async fn id(&self) -> BoxStream<'static, ObjB> {
|
||||||
Box::pin(stream::once(future::ready(ObjB { id: 34 })))
|
Box::pin(stream::once(future::ready(ObjB { id: 34 })))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
use std::pin::Pin;
|
use std::{future, pin::Pin};
|
||||||
|
|
||||||
|
use futures::{stream, Stream};
|
||||||
use juniper::graphql_subscription;
|
use juniper::graphql_subscription;
|
||||||
|
|
||||||
type Stream<'a, I> = Pin<Box<dyn futures::Stream<Item = I> + Send + 'a>>;
|
type BoxStream<'a, I> = Pin<Box<dyn Stream<Item = I> + Send + 'a>>;
|
||||||
|
|
||||||
struct ObjA;
|
struct ObjA;
|
||||||
|
|
||||||
#[graphql_subscription]
|
#[graphql_subscription]
|
||||||
impl ObjA {
|
impl ObjA {
|
||||||
fn id(&self) -> Stream<'static, bool> {
|
fn id(&self) -> BoxStream<'static, bool> {
|
||||||
Box::pin(stream::once(future::ready(true)))
|
Box::pin(stream::once(future::ready(true)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
error: GraphQL object synchronous resolvers are not supported
|
error: GraphQL object synchronous resolvers are not supported
|
||||||
· note: https://spec.graphql.org/October2021#sec-Objects
|
· note: https://spec.graphql.org/October2021#sec-Objects
|
||||||
· note: Specify that this function is async: `async fn foo()`
|
· note: Specify that this function is async: `async fn foo()`
|
||||||
--> fail/subscription/field_not_async.rs:11:5
|
--> fail/subscription/field_not_async.rs:12:5
|
||||||
|
|
|
|
||||||
11 | fn id(&self) -> Stream<'static, bool> {
|
12 | fn id(&self) -> BoxStream<'static, bool> {
|
||||||
| ^^
|
| ^^
|
||||||
|
|
|
@ -1,19 +1,20 @@
|
||||||
use std::pin::Pin;
|
use std::{future, pin::Pin};
|
||||||
|
|
||||||
|
use futures::{stream, Stream};
|
||||||
use juniper::graphql_subscription;
|
use juniper::graphql_subscription;
|
||||||
|
|
||||||
type Stream<'a, I> = Pin<Box<dyn futures::Stream<Item = I> + Send + 'a>>;
|
type BoxStream<'a, I> = Pin<Box<dyn Stream<Item = I> + Send + 'a>>;
|
||||||
|
|
||||||
struct ObjA;
|
struct ObjA;
|
||||||
|
|
||||||
#[graphql_subscription]
|
#[graphql_subscription]
|
||||||
impl ObjA {
|
impl ObjA {
|
||||||
async fn id(&self) -> Stream<'static, &'static str> {
|
async fn id(&self) -> BoxStream<'static, &'static str> {
|
||||||
Box::pin(stream::once(future::ready("funA")))
|
Box::pin(stream::once(future::ready("funA")))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[graphql(name = "id")]
|
#[graphql(name = "id")]
|
||||||
async fn id2(&self) -> Stream<'static, &'static str> {
|
async fn id2(&self) -> BoxStream<'static, &'static str> {
|
||||||
Box::pin(stream::once(future::ready("funB")))
|
Box::pin(stream::once(future::ready("funB")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
error: GraphQL object must have a different name for each field
|
error: GraphQL object must have a different name for each field
|
||||||
· note: https://spec.graphql.org/October2021#sec-Objects
|
· note: https://spec.graphql.org/October2021#sec-Objects
|
||||||
--> fail/subscription/fields_duplicate.rs:10:6
|
--> fail/subscription/fields_duplicate.rs:11:6
|
||||||
|
|
|
|
||||||
10 | impl ObjA {
|
11 | impl ObjA {
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
|
error: cannot find attribute `graphql` in this scope
|
||||||
|
--> fail/subscription/fields_duplicate.rs:16:7
|
||||||
|
|
|
||||||
|
16 | #[graphql(name = "id")]
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
use std::pin::Pin;
|
use std::{future, pin::Pin};
|
||||||
|
|
||||||
|
use futures::{stream, Stream};
|
||||||
use juniper::graphql_subscription;
|
use juniper::graphql_subscription;
|
||||||
|
|
||||||
type Stream<'a, I> = Pin<Box<dyn futures::Stream<Item = I> + Send + 'a>>;
|
type BoxStream<'a, I> = Pin<Box<dyn Stream<Item = I> + Send + 'a>>;
|
||||||
|
|
||||||
struct __Obj;
|
struct __Obj;
|
||||||
|
|
||||||
#[graphql_subscription]
|
#[graphql_subscription]
|
||||||
impl __Obj {
|
impl __Obj {
|
||||||
fn id(&self) -> Stream<'static, &'static str> {
|
fn id(&self) -> BoxStream<'static, &'static str> {
|
||||||
Box::pin(stream::once(future::ready("funA")))
|
Box::pin(stream::once(future::ready("funA")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
error: All types and directives defined within a schema must not have a name which begins with `__` (two underscores), as this is used exclusively by GraphQL’s introspection system.
|
error: All types and directives defined within a schema must not have a name which begins with `__` (two underscores), as this is used exclusively by GraphQL’s introspection system.
|
||||||
· note: https://spec.graphql.org/October2021#sec-Schema
|
· note: https://spec.graphql.org/October2021#sec-Schema
|
||||||
--> fail/subscription/name_double_underscored.rs:10:6
|
--> fail/subscription/name_double_underscored.rs:11:6
|
||||||
|
|
|
|
||||||
10 | impl __Obj {
|
11 | impl __Obj {
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
19
tests/codegen/fail/subscription/wrong_syntax.rs
Normal file
19
tests/codegen/fail/subscription/wrong_syntax.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
use std::{future, pin::Pin};
|
||||||
|
|
||||||
|
use futures::{stream, Stream};
|
||||||
|
use juniper::graphql_subscription;
|
||||||
|
|
||||||
|
type BoxStream<'a, I> = Pin<Box<dyn Stream<Item = I> + Send + 'a>>;
|
||||||
|
|
||||||
|
struct ObjA {
|
||||||
|
field: bool
|
||||||
|
}
|
||||||
|
|
||||||
|
#[graphql_subscription]
|
||||||
|
impl ObjA {
|
||||||
|
fn id(&self) -> BoxStream<'static, bool> {
|
||||||
|
Box::pin(stream::once(future::ready(self.self.field)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
15
tests/codegen/fail/subscription/wrong_syntax.stderr
Normal file
15
tests/codegen/fail/subscription/wrong_syntax.stderr
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
error: #[graphql_subscription] attribute is applicable to non-trait `impl` blocks only
|
||||||
|
--> fail/subscription/wrong_syntax.rs:12:1
|
||||||
|
|
|
||||||
|
12 | #[graphql_subscription]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in the attribute macro `graphql_subscription` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error[E0609]: no field `self` on type `&ObjA`
|
||||||
|
--> fail/subscription/wrong_syntax.rs:15:50
|
||||||
|
|
|
||||||
|
15 | Box::pin(stream::once(future::ready(self.self.field)))
|
||||||
|
| ^^^^ unknown field
|
||||||
|
|
|
||||||
|
= note: available fields are: `field`
|
|
@ -5,3 +5,9 @@ error: GraphQL union cannot use #[graphql(with = ...)] attribute on a trait meth
|
||||||
|
|
|
|
||||||
5 | #[graphql(with = something)]
|
5 | #[graphql(with = something)]
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
|
error: cannot find attribute `graphql` in this scope
|
||||||
|
--> fail/union/trait_with_attr_on_method.rs:5:7
|
||||||
|
|
|
||||||
|
5 | #[graphql(with = something)]
|
||||||
|
| ^^^^^^^
|
||||||
|
|
Loading…
Add table
Reference in a new issue