Skip to content

Commit d95cf06

Browse files
committed
Implement variables of primitive types
Missing features: - Input types - Default values
1 parent 40df869 commit d95cf06

File tree

8 files changed

+99
-7
lines changed

8 files changed

+99
-7
lines changed

graphql_query_derive/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ mod schema;
2929
mod selection;
3030
mod shared;
3131
mod unions;
32+
mod variables;
3233

3334
#[cfg(test)]
3435
mod tests;

graphql_query_derive/src/query.rs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
use failure;
2-
use field_type::FieldType;
32
use fragments::GqlFragment;
4-
use proc_macro2::TokenStream;
3+
use graphql_parser;
4+
use proc_macro2::{Ident, Span, TokenStream};
55
use schema::Schema;
66
use selection::Selection;
77
use std::collections::BTreeMap;
8+
use variables::Variable;
89

910
pub struct QueryContext {
1011
pub _subscription_root: Option<Vec<TokenStream>>,
1112
pub fragments: BTreeMap<String, GqlFragment>,
1213
pub mutation_root: Option<Vec<TokenStream>>,
1314
pub query_root: Option<Vec<TokenStream>>,
1415
pub schema: Schema,
15-
pub variables: BTreeMap<String, FieldType>,
16+
pub variables: Vec<Variable>,
1617
}
1718

1819
impl QueryContext {
@@ -23,7 +24,34 @@ impl QueryContext {
2324
mutation_root: None,
2425
query_root: None,
2526
schema,
26-
variables: BTreeMap::new(),
27+
variables: Vec::new(),
28+
}
29+
}
30+
31+
pub fn register_variables(&mut self, variables: &[graphql_parser::query::VariableDefinition]) {
32+
variables.iter().for_each(|variable| {
33+
self.variables.push(variable.clone().into());
34+
});
35+
}
36+
37+
pub fn expand_variables(&self) -> TokenStream {
38+
if self.variables.is_empty() {
39+
return quote!(#[derive(Serialize)]
40+
pub struct Variables;);
41+
}
42+
43+
let fields = self.variables.iter().map(|variable| {
44+
let name = &variable.name;
45+
let ty = variable.ty.to_rust(self, name);
46+
let name = Ident::new(name, Span::call_site());
47+
quote!(pub #name: #ty)
48+
});
49+
50+
quote! {
51+
#[derive(Serialize)]
52+
pub struct Variables {
53+
#(#fields,)*
54+
}
2755
}
2856
}
2957

@@ -36,7 +64,7 @@ impl QueryContext {
3664
mutation_root: None,
3765
query_root: None,
3866
schema: Schema::new(),
39-
variables: BTreeMap::new(),
67+
variables: Vec::new(),
4068
}
4169
}
4270

graphql_query_derive/src/schema.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ impl Schema {
6767
definition.response_fields_for_selection(&context, &selection, &prefix),
6868
)
6969
};
70+
71+
context.register_variables(&q.variable_definitions);
7072
}
7173
query::Definition::Operation(query::OperationDefinition::Mutation(q)) => {
7274
context.mutation_root = {
@@ -87,6 +89,8 @@ impl Schema {
8789
definition.response_fields_for_selection(&context, &selection, &prefix),
8890
)
8991
};
92+
93+
context.register_variables(&q.variable_definitions);
9094
}
9195
query::Definition::Operation(query::OperationDefinition::Subscription(q)) => {
9296
context._subscription_root = {
@@ -109,6 +113,8 @@ impl Schema {
109113
definition.response_fields_for_selection(&context, &selection, &prefix),
110114
)
111115
};
116+
117+
context.register_variables(&q.variable_definitions);
112118
}
113119
query::Definition::Operation(query::OperationDefinition::SelectionSet(_)) => {
114120
unimplemented!()
@@ -132,8 +138,7 @@ impl Schema {
132138
.fragments
133139
.values()
134140
.map(|fragment| fragment.to_rust(&context));
135-
let variables_struct = quote!(#[derive(Serialize)]
136-
pub struct Variables;);
141+
let variables_struct = context.expand_variables();
137142
let response_data_fields = context
138143
.query_root
139144
.as_ref()

graphql_query_derive/src/variables.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
use field_type::FieldType;
2+
use graphql_parser;
3+
4+
#[derive(Debug)]
5+
pub struct Variable {
6+
pub name: String,
7+
pub ty: FieldType,
8+
pub default: Option<graphql_parser::query::Value>,
9+
}
10+
11+
impl ::std::convert::From<graphql_parser::query::VariableDefinition> for Variable {
12+
fn from(def: graphql_parser::query::VariableDefinition) -> Variable {
13+
Variable {
14+
name: def.name,
15+
ty: FieldType::from(def.var_type),
16+
default: def.default_value,
17+
}
18+
}
19+
}

tests/introspection.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ extern crate serde;
99
query_path = "tests/introspection_query.graphql",
1010
schema_path = "tests/introspection_schema.graphql"
1111
)]
12+
#[allow(dead_code)]
1213
struct IntrospectionQuery;
1314

1415
#[test]

tests/scalar_variables.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#[macro_use]
2+
extern crate graphql_client;
3+
#[macro_use]
4+
extern crate serde_derive;
5+
extern crate serde;
6+
7+
#[derive(GraphQLQuery)]
8+
#[GraphQLQuery(
9+
query_path = "tests/scalar_variables_query.graphql",
10+
schema_path = "tests/scalar_variables_schema.graphql"
11+
)]
12+
#[allow(dead_code)]
13+
struct ScalarVariablesQuery;
14+
15+
#[test]
16+
fn scalar_variables_query_variables_struct() {
17+
scalar_variables_query::Variables {
18+
msg: "hello".to_string(),
19+
reps: Some(32),
20+
};
21+
}

tests/scalar_variables_query.graphql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
query VariablesQuery($msg: String!, $reps: Int) {
2+
echo(message: $msg, repetitions: $reps) {
3+
result
4+
}
5+
}

tests/scalar_variables_schema.graphql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
schema {
3+
query: ScalarVariablesQuery
4+
}
5+
6+
type ScalarVariablesQuery {
7+
echo(message: String!, repetitions: Int): EchoResult
8+
}
9+
10+
type EchoResult {
11+
result: String!
12+
}

0 commit comments

Comments
 (0)