Skip to content

Commit b2cdc14

Browse files
committed
Upd Book
1 parent 6a50f8e commit b2cdc14

File tree

5 files changed

+119
-62
lines changed

5 files changed

+119
-62
lines changed

book/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ publish = false
77

88
[dependencies]
99
dataloader = "0.18" # for Book only
10+
derive_more = { version = "2.0", features = ["display", "from", "try_into"] }
11+
juniper = { path = "../juniper", features = ["jiff"] }
1012

1113
[lints.clippy]
1214
allow_attributes = "warn"

book/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
//! Crate keeping dependencies for running Book tests.
22
33
use dataloader as _;
4+
use juniper as _;

book/src/types/scalars.md

Lines changed: 60 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,49 @@ pub struct UserId(String);
8585
In case we need to customize [resolving][7] of a [custom GraphQL scalar][2] value (change the way it gets executed), the `#[graphql(to_output_with = <fn path>)]` attribute is the way to do so:
8686
```rust
8787
# extern crate juniper;
88-
# use juniper::{GraphQLScalar, IntoValue as _, ScalarValue, Value};
88+
# use juniper::GraphQLScalar;
8989
#
9090
#[derive(GraphQLScalar)]
9191
#[graphql(to_output_with = to_output, transparent)]
9292
struct Incremented(i32);
9393

94-
/// Increments [`Incremented`] before converting into a [`Value`].
95-
fn to_output<S: ScalarValue>(v: &Incremented) -> Value<S> {
96-
(v.0 + 1).into_value()
94+
fn to_output(v: &Incremented) -> i32 {
95+
// ^^^ any concrete type having `ToScalarValue` implementation
96+
// could be used
97+
v.0 + 1
98+
}
99+
#
100+
# fn main() {}
101+
```
102+
103+
The provided function is polymorphic by its output type:
104+
```rust
105+
# extern crate jiff;
106+
# extern crate juniper;
107+
# use std::fmt::Display;
108+
# use juniper::{GraphQLScalar, ScalarValue};
109+
#
110+
#[derive(GraphQLScalar)]
111+
#[graphql(to_output_with = Self::to_output, transparent)]
112+
struct Incremented(i32);
113+
114+
impl Incremented {
115+
fn to_output<S: ScalarValue>(v: &Incremented) -> S {
116+
// ^^^^^^^^^^^^^^ returning generic or concrete `ScalarValue` is also OK
117+
(v.0 + 1).into()
118+
}
119+
}
120+
121+
#[derive(GraphQLScalar)]
122+
#[graphql(to_output_with = Self::to_output, transparent)]
123+
struct CustomDateTime(jiff::Timestamp);
124+
125+
impl CustomDateTime {
126+
fn to_output(&self) -> impl Display {
127+
// ^^^^^^^^^^^^ in this case macro expansion uses the
128+
// `ScalarValue::from_displayable_non_static()` conversion
129+
self.0.strftime("%Y-%m-%d %H:%M:%S%.fZ")
130+
}
97131
}
98132
#
99133
# fn main() {}
@@ -117,7 +151,7 @@ impl UserId {
117151
input: &str,
118152
// ^^^^ any concrete type having `FromScalarValue` implementation could be used
119153
) -> Result<Self, Box<str>> {
120-
// ^^^^^^^^ must implement `IntoFieldError`
154+
// ^^^^^^^^ must implement `IntoFieldError`
121155
input
122156
.strip_prefix("id: ")
123157
.ok_or_else(|| {
@@ -130,7 +164,7 @@ impl UserId {
130164
# fn main() {}
131165
```
132166

133-
The provided function is polymorphic by input and output types:
167+
The provided function is polymorphic by its input and output types:
134168
```rust
135169
# extern crate juniper;
136170
# use juniper::{GraphQLScalar, Scalar, ScalarValue};
@@ -169,7 +203,7 @@ Customization of which tokens a [custom GraphQL scalar][0] type should be parsed
169203
```rust
170204
# extern crate juniper;
171205
# use juniper::{
172-
# GraphQLScalar, ParseScalarResult, ParseScalarValue, Scalar, ScalarToken, ScalarValue, Value,
206+
# GraphQLScalar, ParseScalarResult, ParseScalarValue, Scalar, ScalarToken, ScalarValue,
173207
# };
174208
#
175209
#[derive(GraphQLScalar)]
@@ -186,10 +220,12 @@ enum StringOrInt {
186220
Int(i32),
187221
}
188222

189-
fn to_output<S: ScalarValue>(v: &StringOrInt) -> Value<S> {
223+
fn to_output<S: ScalarValue>(v: &StringOrInt) -> S {
190224
match v {
191-
StringOrInt::String(s) => Value::scalar(s.to_owned()),
192-
StringOrInt::Int(i) => Value::scalar(*i),
225+
StringOrInt::String(s) => S::from_displayable(s),
226+
// ^^^^^^^^^^^^^^^^^^^ preferable conversion for types
227+
// represented by string token
228+
StringOrInt::Int(i) => (*i).into(),
193229
}
194230
}
195231

@@ -216,7 +252,7 @@ Instead of providing all custom functions separately, it's possible to provide a
216252
```rust
217253
# extern crate juniper;
218254
# use juniper::{
219-
# GraphQLScalar, ParseScalarResult, ParseScalarValue, Scalar, ScalarToken, ScalarValue, Value,
255+
# GraphQLScalar, ParseScalarResult, ParseScalarValue, Scalar, ScalarToken, ScalarValue,
220256
# };
221257
#
222258
#[derive(GraphQLScalar)]
@@ -229,10 +265,10 @@ enum StringOrInt {
229265
mod string_or_int {
230266
use super::*;
231267

232-
pub(super) fn to_output<S: ScalarValue>(v: &StringOrInt) -> Value<S> {
268+
pub(super) fn to_output<S: ScalarValue>(v: &StringOrInt) -> S {
233269
match v {
234-
StringOrInt::String(s) => Value::scalar(s.to_owned()),
235-
StringOrInt::Int(i) => Value::scalar(*i),
270+
StringOrInt::String(s) => S::from_displayable(s),
271+
StringOrInt::Int(i) => (*i).into(),
236272
}
237273
}
238274

@@ -256,7 +292,7 @@ A regular `impl` block is also suitable for that:
256292
```rust
257293
# extern crate juniper;
258294
# use juniper::{
259-
# GraphQLScalar, ParseScalarResult, ParseScalarValue, Scalar, ScalarToken, ScalarValue, Value,
295+
# GraphQLScalar, ParseScalarResult, ParseScalarValue, Scalar, ScalarToken, ScalarValue,
260296
# };
261297
#
262298
#[derive(GraphQLScalar)]
@@ -267,10 +303,10 @@ enum StringOrInt {
267303
}
268304

269305
impl StringOrInt {
270-
fn to_output<S: ScalarValue>(&self) -> Value<S> {
306+
fn to_output<S: ScalarValue>(&self) -> S {
271307
match self {
272-
Self::String(s) => Value::scalar(s.to_owned()),
273-
Self::Int(i) => Value::scalar(*i),
308+
Self::String(s) => S::from_displayable(s),
309+
Self::Int(i) => (*i).into(),
274310
}
275311
}
276312

@@ -297,7 +333,7 @@ At the same time, any custom function still may be specified separately, if requ
297333
```rust
298334
# extern crate juniper;
299335
# use juniper::{
300-
# GraphQLScalar, ParseScalarResult, Scalar, ScalarToken, ScalarValue, Value,
336+
# GraphQLScalar, ParseScalarResult, Scalar, ScalarToken, ScalarValue,
301337
# };
302338
#
303339
#[derive(GraphQLScalar)]
@@ -313,13 +349,10 @@ enum StringOrInt {
313349
mod string_or_int {
314350
use super::*;
315351

316-
pub(super) fn to_output<S>(v: &StringOrInt) -> Value<S>
317-
where
318-
S: ScalarValue,
319-
{
352+
pub(super) fn to_output<S: ScalarValue>(v: &StringOrInt) -> S {
320353
match v {
321-
StringOrInt::String(s) => Value::scalar(s.to_owned()),
322-
StringOrInt::Int(i) => Value::scalar(*i),
354+
StringOrInt::String(s) => S::from_displayable(s),
355+
StringOrInt::Int(i) => (*i).into(),
323356
}
324357
}
325358

@@ -367,11 +400,12 @@ For implementing [custom scalars][2] on foreign types there is [`#[graphql_scala
367400
# }
368401
#
369402
# use juniper::DefaultScalarValue as CustomScalarValue;
370-
use juniper::{ScalarValue, Value, graphql_scalar};
403+
use juniper::{ScalarValue, graphql_scalar};
371404

372405
#[graphql_scalar]
373406
#[graphql(
374407
with = date_scalar,
408+
to_output_with = ScalarValue::from_displayable, // use `Display` representation
375409
parse_token(String),
376410
scalar = CustomScalarValue,
377411
)]
@@ -381,10 +415,6 @@ type Date = date::Date;
381415

382416
mod date_scalar {
383417
use super::*;
384-
385-
pub(super) fn to_output(v: &Date) -> Value<CustomScalarValue> {
386-
Value::scalar(v.to_string())
387-
}
388418

389419
pub(super) fn from_input(s: &str) -> Result<Date, Box<str>> {
390420
s.parse().map_err(|e| format!("Failed to parse `Date`: {e}").into())

juniper_codegen/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ url = "2.0"
3131
[dev-dependencies]
3232
derive_more = { version = "2.0", features = ["from", "try_into"] }
3333
futures = "0.3.22"
34-
juniper = { path = "../juniper" }
34+
jiff = { version = "0.2", features = ["std"], default-features = false }
35+
juniper = { path = "../juniper", features = ["jiff"] }
3536
serde = "1.0.122"
3637

3738
[lints.clippy]

0 commit comments

Comments
 (0)