Skip to content

Commit 976dbb1

Browse files
committed
Implement custom deserialization for custom scalars
Users of the library now have to provide type aliases for the scalars defined in the schema in the parent scope (the scope of the struct under derive).
1 parent defbbe1 commit 976dbb1

File tree

9 files changed

+87
-2
lines changed

9 files changed

+87
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
99

1010
### Added
1111

12-
- Support for multi-operations documents. You can select a particular operation by naming the struct under derive after it.
12+
- (breaking) Control over which types custom scalars deserialize to is given to the user: you now have to provide type aliases for the custom scalars in the scope of the struct under derive.
13+
- (breaking) Support for multi-operations documents. You can select a particular operation by naming the struct under derive after it. In case there is no match, we revert to the current behaviour: select the first operation.
1314

1415
## [0.3.0] - 2018-07-24
1516

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//! We define the custom scalars present in the GitHub schema. More precise types could be provided here (see tests), as long as they are deserializable.
2+
3+
pub type X509Certificate = String;
4+
pub type URI = String;
5+
pub type HTML = String;
6+
pub type GitTimestamp = String;
7+
pub type GitSSHRemote = String;
8+
pub type GitObjectID = String;
9+
pub type Date = String;
10+
pub type DateTime = String;

examples/example_module/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ extern crate serde_derive;
44
#[macro_use]
55
extern crate graphql_client;
66

7+
pub mod custom_scalars;
8+
9+
use custom_scalars::*;
10+
711
#[derive(GraphQLQuery)]
812
#[graphql(
913
schema_path = "../github/src/schema.graphql",

examples/github/src/main.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,15 @@ extern crate prettytable;
2020
use graphql_client::*;
2121
use structopt::StructOpt;
2222

23+
type X509Certificate = String;
24+
type URI = String;
25+
type HTML = String;
26+
type GitTimestamp = String;
27+
type GitSSHRemote = String;
28+
type GitObjectID = String;
29+
type Date = String;
30+
type DateTime = String;
31+
2332
#[derive(GraphQLQuery)]
2433
#[graphql(
2534
schema_path = "src/schema.graphql",

graphql_query_derive/src/scalars.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ impl Scalar {
1515
Some(d) => quote!(#[doc = #d]),
1616
None => quote!(),
1717
};
18-
quote!(#description type #ident = String;)
18+
quote!(#description type #ident = super::#ident;)
1919
}
2020
}

tests/custom_scalars.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#[macro_use]
2+
extern crate graphql_client;
3+
extern crate serde;
4+
#[macro_use]
5+
extern crate serde_derive;
6+
#[macro_use]
7+
extern crate serde_json;
8+
9+
use std::net::Ipv4Addr;
10+
11+
// Important! The NetworkAddress scalar should deserialize to an Ipv4Addr from the Rust std library.
12+
type NetworkAddress = Ipv4Addr;
13+
14+
#[derive(GraphQLQuery)]
15+
#[graphql(
16+
query_path = "tests/custom_scalars/query.graphql",
17+
schema_path = "tests/custom_scalars/schema.graphql"
18+
)]
19+
#[allow(dead_code)]
20+
struct CustomScalarsQuery;
21+
22+
#[test]
23+
fn custom_scalars() {
24+
let valid_response = json!({
25+
"address": "127.0.1.2",
26+
});
27+
28+
let valid_addr =
29+
serde_json::from_value::<custom_scalars_query::ResponseData>(valid_response).unwrap();
30+
31+
assert_eq!(
32+
valid_addr.address.unwrap(),
33+
"127.0.1.2".parse::<Ipv4Addr>().unwrap()
34+
);
35+
36+
let invalid_response = json!({
37+
"address": "localhost",
38+
});
39+
40+
assert!(
41+
serde_json::from_value::<custom_scalars_query::ResponseData>(invalid_response).is_err()
42+
);
43+
}

tests/custom_scalars/query.graphql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
query CustomScalarQuery {
2+
address
3+
}

tests/custom_scalars/schema.graphql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
schema {
2+
query: QueryRoot
3+
}
4+
5+
"""
6+
An IPv4 address
7+
"""
8+
scalar NetworkAddress
9+
10+
type QueryRoot {
11+
address: NetworkAddress
12+
}

tests/input_object_variables.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ fn input_object_variables_query_variables_struct() {
2727
};
2828
}
2929

30+
// Custom scalars
31+
type Email = String;
32+
3033
#[derive(GraphQLQuery)]
3134
#[graphql(
3235
query_path = "tests/input_object_variables/input_object_variables_query_defaults.graphql",

0 commit comments

Comments
 (0)