Skip to content

Commit a487188

Browse files
tyranronLegNeato
andauthored
Default to generic ScalarValue in #[graphql_object] macro (#779)
* Change codegen ScalarValue defaults for #[graphql_object] macro * Fix integration tests * Fix codegen failure tests * Fix 'juniper' crate tests * Fix integration crates tests * Fix 'juniper_benchmarks' crate * Fix examples * Fix Book * Fix * Add CHANGELOG entry * Some Book corrections * Fix * Bootstrap coercion machinery * Reimpl coercion * Correct tests, vol.1 * Correct tests, vol.2 * Correct tests, vol.3 * Correct tests, vol.4 * Correct tests, vol.5 * Fix coercion for subscriptions * README fixes Co-authored-by: Christian Legnitto <[email protected]> Co-authored-by: Christian Legnitto <[email protected]>
1 parent 4c40826 commit a487188

File tree

52 files changed

+817
-646
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+817
-646
lines changed

docs/book/content/advanced/introspection.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,14 @@ result can then be converted to JSON for use with tools and libraries such as
3333
# #![allow(unused_variables)]
3434
# extern crate juniper;
3535
# extern crate serde_json;
36-
use juniper::{EmptyMutation, EmptySubscription, FieldResult, IntrospectionFormat};
36+
use juniper::{
37+
graphql_object, EmptyMutation, EmptySubscription, FieldResult,
38+
GraphQLObject, IntrospectionFormat,
39+
};
3740

3841
// Define our schema.
3942

40-
#[derive(juniper::GraphQLObject)]
43+
#[derive(GraphQLObject)]
4144
struct Example {
4245
id: String,
4346
}
@@ -47,9 +50,7 @@ impl juniper::Context for Context {}
4750

4851
struct Query;
4952

50-
#[juniper::graphql_object(
51-
Context = Context,
52-
)]
53+
#[graphql_object(context = Context)]
5354
impl Query {
5455
fn example(id: String) -> FieldResult<Example> {
5556
unimplemented!()

docs/book/content/advanced/non_struct_objects.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ errors from a mutation:
1010

1111
```rust
1212
# extern crate juniper;
13+
# use juniper::{graphql_object, GraphQLObject};
1314
# #[derive(juniper::GraphQLObject)] struct User { name: String }
14-
15-
#[derive(juniper::GraphQLObject)]
15+
#
16+
#[derive(GraphQLObject)]
1617
struct ValidationError {
1718
field: String,
1819
message: String,
@@ -24,7 +25,7 @@ enum SignUpResult {
2425
Error(Vec<ValidationError>),
2526
}
2627

27-
#[juniper::graphql_object]
28+
#[graphql_object]
2829
impl SignUpResult {
2930
fn user(&self) -> Option<&User> {
3031
match *self {
@@ -40,7 +41,7 @@ impl SignUpResult {
4041
}
4142
}
4243
}
43-
44+
#
4445
# fn main() {}
4546
```
4647

docs/book/content/advanced/subscriptions.md

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ sequentially:
2929
# extern crate juniper;
3030
# extern crate juniper_subscriptions;
3131
# extern crate tokio;
32-
# use juniper::FieldError;
32+
# use juniper::{graphql_object, graphql_subscription, FieldError};
3333
# use futures::Stream;
3434
# use std::pin::Pin;
3535
#
@@ -38,7 +38,7 @@ sequentially:
3838
# impl juniper::Context for Database {}
3939

4040
# pub struct Query;
41-
# #[juniper::graphql_object(Context = Database)]
41+
# #[graphql_object(context = Database)]
4242
# impl Query {
4343
# fn hello_world() -> &str {
4444
# "Hello World!"
@@ -48,7 +48,7 @@ pub struct Subscription;
4848

4949
type StringStream = Pin<Box<dyn Stream<Item = Result<String, FieldError>> + Send>>;
5050

51-
#[juniper::graphql_subscription(Context = Database)]
51+
#[graphql_subscription(context = Database)]
5252
impl Subscription {
5353
async fn hello_world() -> StringStream {
5454
let stream = tokio::stream::iter(vec![
@@ -58,8 +58,9 @@ impl Subscription {
5858
Box::pin(stream)
5959
}
6060
}
61+
#
6162
# fn main () {}
62-
```
63+
```
6364

6465

6566

@@ -84,8 +85,12 @@ where [`Connection`][Connection] is a `Stream` of values returned by the operati
8485
# extern crate juniper_subscriptions;
8586
# extern crate serde_json;
8687
# extern crate tokio;
87-
# use juniper::http::GraphQLRequest;
88-
# use juniper::{DefaultScalarValue, EmptyMutation, FieldError, RootNode, SubscriptionCoordinator};
88+
# use juniper::{
89+
# http::GraphQLRequest,
90+
# graphql_object, graphql_subscription,
91+
# DefaultScalarValue, EmptyMutation, FieldError,
92+
# RootNode, SubscriptionCoordinator,
93+
# };
8994
# use juniper_subscriptions::Coordinator;
9095
# use futures::{Stream, StreamExt};
9196
# use std::pin::Pin;
@@ -103,7 +108,7 @@ where [`Connection`][Connection] is a `Stream` of values returned by the operati
103108
#
104109
# pub struct Query;
105110
#
106-
# #[juniper::graphql_object(Context = Database)]
111+
# #[graphql_object(context = Database)]
107112
# impl Query {
108113
# fn hello_world() -> &str {
109114
# "Hello World!"
@@ -114,7 +119,7 @@ where [`Connection`][Connection] is a `Stream` of values returned by the operati
114119
#
115120
# type StringStream = Pin<Box<dyn Stream<Item = Result<String, FieldError>> + Send>>;
116121
#
117-
# #[juniper::graphql_subscription(Context = Database)]
122+
# #[graphql_subscription(context = Database)]
118123
# impl Subscription {
119124
# async fn hello_world() -> StringStream {
120125
# let stream =
@@ -132,11 +137,9 @@ async fn run_subscription() {
132137
let schema = schema();
133138
let coordinator = Coordinator::new(schema);
134139
let req: GraphQLRequest<DefaultScalarValue> = serde_json::from_str(
135-
r#"
136-
{
140+
r#"{
137141
"query": "subscription { helloWorld }"
138-
}
139-
"#,
142+
}"#,
140143
)
141144
.unwrap();
142145
let ctx = Database::new();
@@ -145,7 +148,7 @@ async fn run_subscription() {
145148
println!("{}", serde_json::to_string(&result).unwrap());
146149
}
147150
}
148-
151+
#
149152
# fn main() { }
150153
```
151154

docs/book/content/quickstart.md

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -28,24 +28,28 @@ resolvers, which you will use for the `Query` and `Mutation` roots.
2828
```rust
2929
# #![allow(unused_variables)]
3030
# extern crate juniper;
31-
use juniper::{FieldResult, EmptySubscription};
32-
31+
# use std::fmt::Display;
32+
use juniper::{
33+
graphql_object, EmptySubscription, FieldResult, GraphQLEnum,
34+
GraphQLInputObject, GraphQLObject, ScalarValue,
35+
};
36+
#
3337
# struct DatabasePool;
3438
# impl DatabasePool {
3539
# fn get_connection(&self) -> FieldResult<DatabasePool> { Ok(DatabasePool) }
3640
# fn find_human(&self, _id: &str) -> FieldResult<Human> { Err("")? }
3741
# fn insert_human(&self, _human: &NewHuman) -> FieldResult<Human> { Err("")? }
3842
# }
3943

40-
#[derive(juniper::GraphQLEnum)]
44+
#[derive(GraphQLEnum)]
4145
enum Episode {
4246
NewHope,
4347
Empire,
4448
Jedi,
4549
}
4650

47-
#[derive(juniper::GraphQLObject)]
48-
#[graphql(description="A humanoid creature in the Star Wars universe")]
51+
#[derive(GraphQLObject)]
52+
#[graphql(description = "A humanoid creature in the Star Wars universe")]
4953
struct Human {
5054
id: String,
5155
name: String,
@@ -55,8 +59,8 @@ struct Human {
5559

5660
// There is also a custom derive for mapping GraphQL input objects.
5761

58-
#[derive(juniper::GraphQLInputObject)]
59-
#[graphql(description="A humanoid creature in the Star Wars universe")]
62+
#[derive(GraphQLInputObject)]
63+
#[graphql(description = "A humanoid creature in the Star Wars universe")]
6064
struct NewHuman {
6165
name: String,
6266
appears_in: Vec<Episode>,
@@ -78,14 +82,13 @@ impl juniper::Context for Context {}
7882

7983
struct Query;
8084

81-
#[juniper::graphql_object(
85+
#[graphql_object(
8286
// Here we specify the context type for the object.
8387
// We need to do this in every type that
8488
// needs access to the context.
85-
Context = Context,
89+
context = Context,
8690
)]
8791
impl Query {
88-
8992
fn apiVersion() -> &str {
9093
"1.0"
9194
}
@@ -109,22 +112,26 @@ impl Query {
109112

110113
struct Mutation;
111114

112-
#[juniper::graphql_object(
113-
Context = Context,
114-
)]
115-
impl Mutation {
115+
#[graphql_object(
116+
context = Context,
116117

117-
fn createHuman(context: &Context, new_human: NewHuman) -> FieldResult<Human> {
118-
let db = context.pool.get_connection()?;
119-
let human: Human = db.insert_human(&new_human)?;
118+
// If we need to use `ScalarValue` parametrization explicitly somewhere
119+
// in the object definition (like here in `FieldResult`), we should
120+
// declare an explicit type parameter for that, and specify it.
121+
scalar = S,
122+
)]
123+
impl<S: ScalarValue + Display> Mutation {
124+
fn createHuman(context: &Context, new_human: NewHuman) -> FieldResult<Human, S> {
125+
let db = context.pool.get_connection().map_err(|e| e.map_scalar_value())?;
126+
let human: Human = db.insert_human(&new_human).map_err(|e| e.map_scalar_value())?;
120127
Ok(human)
121128
}
122129
}
123130

124131
// A root schema consists of a query, a mutation, and a subscription.
125132
// Request queries can be executed against a RootNode.
126133
type Schema = juniper::RootNode<'static, Query, Mutation, EmptySubscription<Context>>;
127-
134+
#
128135
# fn main() {
129136
# let _ = Schema::new(Query, Mutation{}, EmptySubscription::new());
130137
# }
@@ -143,10 +150,12 @@ You can invoke `juniper::execute` directly to run a GraphQL query:
143150
```rust
144151
# // Only needed due to 2018 edition because the macro is not accessible.
145152
# #[macro_use] extern crate juniper;
146-
use juniper::{FieldResult, Variables, EmptyMutation, EmptySubscription};
147-
153+
use juniper::{
154+
graphql_object, EmptyMutation, EmptySubscription, FieldResult,
155+
GraphQLEnum, Variables,
156+
};
148157

149-
#[derive(juniper::GraphQLEnum, Clone, Copy)]
158+
#[derive(GraphQLEnum, Clone, Copy)]
150159
enum Episode {
151160
NewHope,
152161
Empire,
@@ -160,16 +169,13 @@ impl juniper::Context for Ctx {}
160169

161170
struct Query;
162171

163-
#[juniper::graphql_object(
164-
Context = Ctx,
165-
)]
172+
#[graphql_object(context = Ctx)]
166173
impl Query {
167174
fn favoriteEpisode(context: &Ctx) -> FieldResult<Episode> {
168175
Ok(context.0)
169176
}
170177
}
171178

172-
173179
// A root schema consists of a query, a mutation, and a subscription.
174180
// Request queries can be executed against a RootNode.
175181
type Schema = juniper::RootNode<'static, Query, EmptyMutation<Ctx>, EmptySubscription<Ctx>>;

docs/book/content/schema/schemas_and_mutations.md

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,18 @@ object in Juniper, most commonly using the `graphql_object` proc macro:
2424
```rust
2525
# #![allow(unused_variables)]
2626
# extern crate juniper;
27-
# use juniper::FieldResult;
28-
# #[derive(juniper::GraphQLObject)] struct User { name: String }
27+
# use juniper::{graphql_object, FieldResult, GraphQLObject};
28+
# #[derive(GraphQLObject)] struct User { name: String }
2929
struct Root;
3030

31-
#[juniper::graphql_object]
31+
#[graphql_object]
3232
impl Root {
3333
fn userWithUsername(username: String) -> FieldResult<Option<User>> {
3434
// Look up user in database...
35-
# unimplemented!()
35+
# unimplemented!()
3636
}
3737
}
38-
38+
#
3939
# fn main() { }
4040
```
4141

@@ -47,18 +47,18 @@ that performs some mutating side-effect such as updating a database.
4747
```rust
4848
# #![allow(unused_variables)]
4949
# extern crate juniper;
50-
# use juniper::FieldResult;
51-
# #[derive(juniper::GraphQLObject)] struct User { name: String }
50+
# use juniper::{graphql_object, FieldResult, GraphQLObject};
51+
# #[derive(GraphQLObject)] struct User { name: String }
5252
struct Mutations;
5353

54-
#[juniper::graphql_object]
54+
#[graphql_object]
5555
impl Mutations {
5656
fn signUpUser(name: String, email: String) -> FieldResult<User> {
5757
// Validate inputs and save user in database...
58-
# unimplemented!()
58+
# unimplemented!()
5959
}
6060
}
61-
61+
#
6262
# fn main() { }
6363
```
6464

@@ -68,11 +68,13 @@ Many tools in the GraphQL ecosystem require the schema to be defined in the [Gra
6868

6969
```rust
7070
# extern crate juniper;
71-
use juniper::{FieldResult, EmptyMutation, EmptySubscription, RootNode};
71+
use juniper::{
72+
graphql_object, EmptyMutation, EmptySubscription, FieldResult, RootNode,
73+
};
7274

7375
struct Query;
7476

75-
#[juniper::graphql_object]
77+
#[graphql_object]
7678
impl Query {
7779
fn hello(&self) -> FieldResult<&str> {
7880
Ok("hello world")

0 commit comments

Comments
 (0)