Skip to content

Commit 6f7ad1e

Browse files
authored
Merge pull request #74 from tomhoule/custom-scalars
Implement custom deserialization for custom scalars
2 parents 4e8d486 + 976dbb1 commit 6f7ad1e

File tree

12 files changed

+88
-8
lines changed

12 files changed

+88
-8
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/operations.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use constants::*;
2-
use graphql_parser;
32
use graphql_parser::query::OperationDefinition;
43
use heck::SnakeCase;
54
use proc_macro2::{Span, TokenStream};

graphql_query_derive/src/query.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
use failure;
22
use fragments::GqlFragment;
3-
use graphql_parser;
4-
use heck::SnakeCase;
53
use operations::Operation;
6-
use proc_macro2::{Ident, Span, TokenStream};
4+
use proc_macro2::TokenStream;
75
use schema::Schema;
86
use selection::Selection;
97
use std::collections::BTreeMap;

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
}

src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use std::collections::HashMap;
2424
///
2525
/// Example:
2626
///
27-
///
2827
/// ```
2928
/// extern crate failure;
3029
/// #[macro_use]
@@ -65,7 +64,6 @@ use std::collections::HashMap;
6564
/// Ok(())
6665
/// }
6766
/// ```
68-
/// ```
6967
pub trait GraphQLQuery<'de> {
7068
/// The shape of the variables expected by the query. This should be a generated struct most of the time.
7169
type Variables: serde::Serialize;

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)