Skip to content

Commit ebe527f

Browse files
authored
Merge pull request #2 from tomhoule/cli
Compile on stable
2 parents 1b0630e + 5ece0fc commit ebe527f

File tree

15 files changed

+395
-73
lines changed

15 files changed

+395
-73
lines changed

.travis.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ rust:
66
cache: cargo
77
script:
88
- cargo test --verbose
9-
- cd graphql_query_derive && cargo test --verbose
10-
- cd ../examples/github && cargo build
9+
- cargo test --verbose --manifest-path=./graphql_query_derive/Cargo.toml
10+
- cargo build --manifest-path=./examples/github/Cargo.toml
11+
- cargo build --manifest-path=./graphql_client_cli/Cargo.toml

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ members = [
1616
".",
1717
"examples/github",
1818
"graphql_query_derive",
19+
"graphql_client_cli",
1920
]

graphql_client_cli/Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "graphql_client_cli"
3+
version = "0.1.0"
4+
authors = ["Tom Houlé <[email protected]>"]
5+
6+
[dependencies]
7+
failure = "*"
8+
reqwest = "*"
9+
graphql_client = { path = ".." }
10+
structopt = "*"
11+
serde = "1.0"
12+
serde_derive = "1.0"
13+
serde_json = "1.0"

graphql_client_cli/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
https://developer.deutschebahn.com/free1bahnql/graphql
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
query IntrospectionQuery {
2+
__schema {
3+
queryType {
4+
name
5+
}
6+
mutationType {
7+
name
8+
}
9+
subscriptionType {
10+
name
11+
}
12+
types {
13+
...FullType
14+
}
15+
directives {
16+
name
17+
description
18+
locations
19+
args {
20+
...InputValue
21+
}
22+
}
23+
}
24+
}
25+
26+
fragment FullType on __Type {
27+
kind
28+
name
29+
description
30+
fields(includeDeprecated: true) {
31+
name
32+
description
33+
args {
34+
...InputValue
35+
}
36+
type {
37+
...TypeRef
38+
}
39+
isDeprecated
40+
deprecationReason
41+
}
42+
inputFields {
43+
...InputValue
44+
}
45+
interfaces {
46+
...TypeRef
47+
}
48+
enumValues(includeDeprecated: true) {
49+
name
50+
description
51+
isDeprecated
52+
deprecationReason
53+
}
54+
possibleTypes {
55+
...TypeRef
56+
}
57+
}
58+
59+
fragment InputValue on __InputValue {
60+
name
61+
description
62+
type {
63+
...TypeRef
64+
}
65+
defaultValue
66+
}
67+
68+
fragment TypeRef on __Type {
69+
kind
70+
name
71+
ofType {
72+
kind
73+
name
74+
ofType {
75+
kind
76+
name
77+
ofType {
78+
kind
79+
name
80+
ofType {
81+
kind
82+
name
83+
ofType {
84+
kind
85+
name
86+
ofType {
87+
kind
88+
name
89+
ofType {
90+
kind
91+
name
92+
}
93+
}
94+
}
95+
}
96+
}
97+
}
98+
}
99+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
schema {
2+
query: Query
3+
}
4+
5+
type Query {
6+
__schema: __Schema
7+
}
8+
9+
type __Schema {
10+
types: [__Type!]!
11+
queryType: __Type!
12+
mutationType: __Type
13+
subscriptionType: __Type
14+
directives: [__Directive!]!
15+
}
16+
17+
type __Type {
18+
kind: __TypeKind!
19+
name: String
20+
description: String
21+
22+
# OBJECT and INTERFACE only
23+
fields(includeDeprecated: Boolean = false): [__Field!]
24+
25+
# OBJECT only
26+
interfaces: [__Type!]
27+
28+
# INTERFACE and UNION only
29+
possibleTypes: [__Type!]
30+
31+
# ENUM only
32+
enumValues(includeDeprecated: Boolean = false): [__EnumValue!]
33+
34+
# INPUT_OBJECT only
35+
inputFields: [__InputValue!]
36+
37+
# NON_NULL and LIST only
38+
ofType: __Type
39+
}
40+
41+
type __Field {
42+
name: String!
43+
description: String
44+
args: [__InputValue!]!
45+
type: __Type!
46+
isDeprecated: Boolean!
47+
deprecationReason: String
48+
}
49+
50+
type __InputValue {
51+
name: String!
52+
description: String
53+
type: __Type!
54+
defaultValue: String
55+
}
56+
57+
type __EnumValue {
58+
name: String!
59+
description: String
60+
isDeprecated: Boolean!
61+
deprecationReason: String
62+
}
63+
64+
enum __TypeKind {
65+
SCALAR
66+
OBJECT
67+
INTERFACE
68+
UNION
69+
ENUM
70+
INPUT_OBJECT
71+
LIST
72+
NON_NULL
73+
}
74+
75+
type __Directive {
76+
name: String!
77+
description: String
78+
locations: [__DirectiveLocation!]!
79+
args: [__InputValue!]!
80+
}
81+
82+
enum __DirectiveLocation {
83+
QUERY
84+
MUTATION
85+
SUBSCRIPTION
86+
FIELD
87+
FRAGMENT_DEFINITION
88+
FRAGMENT_SPREAD
89+
INLINE_FRAGMENT
90+
SCHEMA
91+
SCALAR
92+
OBJECT
93+
FIELD_DEFINITION
94+
ARGUMENT_DEFINITION
95+
INTERFACE
96+
UNION
97+
ENUM
98+
ENUM_VALUE
99+
INPUT_OBJECT
100+
INPUT_FIELD_DEFINITION
101+
}

graphql_client_cli/src/main.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
extern crate failure;
2+
extern crate reqwest;
3+
#[macro_use]
4+
extern crate structopt;
5+
#[macro_use]
6+
extern crate graphql_client;
7+
#[macro_use]
8+
extern crate serde_derive;
9+
extern crate serde;
10+
extern crate serde_json;
11+
12+
use std::path::PathBuf;
13+
use structopt::StructOpt;
14+
15+
const INTROSPECTION_QUERY: &'static str = include_str!("introspection_query.graphql");
16+
17+
#[derive(GraphQLQuery)]
18+
#[GraphQLQuery(
19+
schema_path = "src/introspection_schema.graphql", query_path = "src/introspection_query.graphql"
20+
)]
21+
struct IntrospectionQuery;
22+
23+
#[derive(StructOpt)]
24+
enum Cli {
25+
#[structopt(name = "introspect-schema")]
26+
IntrospectSchema {
27+
/// The URL of a GraphQL endpoint to introspect.
28+
schema_location: String,
29+
/// Where to write the JSON for the introspected schema.
30+
#[structopt(parse(from_os_str))]
31+
#[structopt(long = "output")]
32+
output: Option<PathBuf>,
33+
},
34+
#[structopt(name = "generate")]
35+
Generate {
36+
// should be a glob
37+
paths: String,
38+
#[structopt(parse(from_os_str))]
39+
schema: PathBuf,
40+
#[structopt(parse(from_os_str))]
41+
output: PathBuf,
42+
},
43+
}
44+
45+
fn main() -> Result<(), failure::Error> {
46+
let cli = Cli::from_args();
47+
match cli {
48+
Cli::IntrospectSchema {
49+
schema_location,
50+
output,
51+
} => introspect_schema(schema_location, output),
52+
Cli::Generate {
53+
paths: _,
54+
schema: _,
55+
output: _,
56+
} => unimplemented!(),
57+
}
58+
}
59+
60+
fn introspect_schema(location: String, output: Option<PathBuf>) -> Result<(), failure::Error> {
61+
use reqwest::header::*;
62+
use reqwest::mime;
63+
use std::io::Write;
64+
65+
let mut out: Box<Write> = match output {
66+
Some(path) => Box::new(::std::fs::File::create(path)?),
67+
None => Box::new(::std::io::stdout()),
68+
};
69+
70+
let request_body: graphql_client::GraphQLQueryBody<()> = graphql_client::GraphQLQueryBody {
71+
variables: (),
72+
query: INTROSPECTION_QUERY,
73+
};
74+
75+
let client = reqwest::Client::new();
76+
let mut res = client
77+
.post(&location)
78+
.header(Accept(vec![qitem(mime::APPLICATION_JSON)]))
79+
.json(&request_body)
80+
.send()?;
81+
82+
if res.status().is_success() {
83+
} else if res.status().is_server_error() {
84+
println!("server error!");
85+
} else {
86+
println!("Something else happened. Status: {:?}", res.status());
87+
}
88+
89+
let json: graphql_client::GraphQLResponse<introspection_query::ResponseData> = res.json()?;
90+
let json = serde_json::to_string(&json)?;
91+
92+
write!(out, "{}", json)?;
93+
94+
Ok(())
95+
}

graphql_query_derive/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ proc-macro = true
1010
failure = "*"
1111
quote = "^0.6"
1212
syn = "*"
13-
proc-macro2 = { version = "*", features = ["nightly"] }
13+
proc-macro2 = { version = "*" }
1414
serde = "1.0"
1515
serde_derive = "1.0"
1616
serde_json = "1.0"

graphql_query_derive/src/enums.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,18 @@ impl GqlEnum {
3434
fn serialize<S: serde::Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
3535
ser.serialize_str(match *self {
3636
#(#constructors => #variant_str,)*
37-
#name::Other(ref s) => s.as_str(),
37+
#name::Other(ref s) => &s,
3838
})
3939
}
4040
}
4141

4242
impl<'de> ::serde::Deserialize<'de> for #name {
4343
fn deserialize<D: ::serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
44-
let s = <&'de str>::deserialize(deserializer)?;
44+
let s = <String>::deserialize(deserializer)?;
4545

46-
match s {
46+
match s.as_str() {
4747
#(#variant_str => Ok(#constructors),)*
48-
_ => Ok(#name::Other(s.to_string())),
48+
_ => Ok(#name::Other(s)),
4949
}
5050
}
5151
}

graphql_query_derive/src/field_type.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,10 @@ fn from_json_type_inner(inner: &introspection_response::TypeRef, non_null: bool)
9797
Some(__TypeKind::NON_NULL) => {
9898
from_json_type_inner(&inner.of_type.expect("inner type is missing"), true)
9999
}
100-
Some(__TypeKind::LIST) => {
101-
FieldType::Vector(Box::new(from_json_type_inner(&inner.of_type.expect("inner type is missing"), false)))
102-
}
100+
Some(__TypeKind::LIST) => FieldType::Vector(Box::new(from_json_type_inner(
101+
&inner.of_type.expect("inner type is missing"),
102+
false,
103+
))),
103104
Some(_) => FieldType::Named(Ident::new(
104105
&inner.name.expect("type name"),
105106
Span::call_site(),

0 commit comments

Comments
 (0)