Skip to content

Commit 7263172

Browse files
committed
WIP - Schema from JSON
1 parent c32adbf commit 7263172

File tree

5 files changed

+133
-56
lines changed

5 files changed

+133
-56
lines changed

graphql_query_derive/src/field_type.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use graphql_parser::schema;
33
use proc_macro2::{Ident, Span, TokenStream};
44
use query::QueryContext;
55
use schema::DEFAULT_SCALARS;
6+
use introspection_response;
67

78
#[derive(Debug, PartialEq)]
89
pub enum FieldType {
@@ -87,3 +88,36 @@ fn from_schema_type_inner(inner: schema::Type, non_null: bool) -> FieldType {
8788
FieldType::Optional(Box::new(inner_field_type))
8889
}
8990
}
91+
92+
fn from_json_type_inner(inner: &introspection_response::TypeRef, non_null: bool) -> FieldType {
93+
use introspection_response::*;
94+
let inner = inner.clone();
95+
96+
let inner_field_type = match inner.kind {
97+
Some(__TypeKind::NON_NULL) => {
98+
from_json_type_inner(&inner.of_type.expect("inner type is missing"), true)
99+
}
100+
Some(__TypeKind::LIST) => {
101+
from_json_type_inner(&inner.of_type.expect("inner type is missing"), false)
102+
}
103+
Some(_) => {
104+
FieldType::Named(Ident::new(&inner.name.expect("type name"), Span::call_site()))
105+
}
106+
None => {
107+
unreachable!("non-convertible type")
108+
}
109+
110+
};
111+
112+
if non_null {
113+
inner_field_type
114+
} else {
115+
FieldType::Optional(Box::new(inner_field_type))
116+
}
117+
}
118+
119+
impl ::std::convert::From<introspection_response::FullTypeFieldsType> for FieldType {
120+
fn from(schema_type: introspection_response::FullTypeFieldsType) -> FieldType {
121+
from_json_type_inner(&schema_type.type_ref, false)
122+
}
123+
}

graphql_query_derive/src/introspection_response.rs

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use serde;
44

55
type Boolean = bool;
66

7-
#[derive(Debug)]
7+
#[derive(Clone, Debug)]
88
pub enum __DirectiveLocation {
99
QUERY,
1010
MUTATION,
@@ -80,7 +80,7 @@ impl<'de> ::serde::Deserialize<'de> for __DirectiveLocation {
8080
}
8181
}
8282

83-
#[derive(Debug)]
83+
#[derive(Clone, Debug)]
8484
pub enum __TypeKind {
8585
SCALAR,
8686
OBJECT,
@@ -126,7 +126,7 @@ impl<'de> ::serde::Deserialize<'de> for __TypeKind {
126126
}
127127
}
128128

129-
#[derive(Debug, Deserialize)]
129+
#[derive(Clone, Debug, Deserialize)]
130130
#[serde(rename_all = "camelCase")]
131131
pub struct FullType {
132132
pub kind: Option<__TypeKind>,
@@ -139,40 +139,40 @@ pub struct FullType {
139139
pub possible_types: Option<Vec<Option<FullTypePossibleTypes>>>,
140140
}
141141

142-
#[derive(Debug, Deserialize)]
142+
#[derive(Clone, Debug, Deserialize)]
143143
#[serde(rename_all = "camelCase")]
144144
pub struct FullTypeFieldsArgs {
145145
#[serde(flatten)]
146146
input_value: InputValue,
147147
}
148148

149-
#[derive(Debug, Deserialize)]
149+
#[derive(Clone, Debug, Deserialize)]
150150
#[serde(rename_all = "camelCase")]
151151
pub struct FullTypeFieldsType {
152152
#[serde(flatten)]
153-
type_ref: TypeRef,
153+
pub type_ref: TypeRef,
154154
}
155155

156-
#[derive(Debug, Deserialize)]
156+
#[derive(Clone, Debug, Deserialize)]
157157
#[serde(rename_all = "camelCase")]
158158
pub struct FullTypeFields {
159-
name: Option<String>,
160-
description: Option<String>,
161-
args: Option<Vec<Option<FullTypeFieldsArgs>>>,
159+
pub name: Option<String>,
160+
pub description: Option<String>,
161+
pub args: Option<Vec<Option<FullTypeFieldsArgs>>>,
162162
#[serde(rename = "type")]
163-
type_: Option<FullTypeFieldsType>,
164-
is_deprecated: Option<Boolean>,
165-
deprecation_reason: Option<String>,
163+
pub type_: Option<FullTypeFieldsType>,
164+
pub is_deprecated: Option<Boolean>,
165+
pub deprecation_reason: Option<String>,
166166
}
167167

168-
#[derive(Debug, Deserialize)]
168+
#[derive(Clone, Debug, Deserialize)]
169169
#[serde(rename_all = "camelCase")]
170170
pub struct FullTypeInputFields {
171171
#[serde(flatten)]
172172
input_value: InputValue,
173173
}
174174

175-
#[derive(Debug, Deserialize)]
175+
#[derive(Clone, Debug, Deserialize)]
176176
#[serde(rename_all = "camelCase")]
177177
pub struct FullTypeInterfaces {
178178
#[serde(flatten)]
@@ -188,14 +188,14 @@ pub struct FullTypeEnumValues {
188188
pub deprecation_reason: Option<String>,
189189
}
190190

191-
#[derive(Debug, Deserialize)]
191+
#[derive(Clone, Debug, Deserialize)]
192192
#[serde(rename_all = "camelCase")]
193193
pub struct FullTypePossibleTypes {
194194
#[serde(flatten)]
195-
type_ref: TypeRef,
195+
pub type_ref: TypeRef,
196196
}
197197

198-
#[derive(Debug, Deserialize)]
198+
#[derive(Clone, Debug, Deserialize)]
199199
#[serde(rename_all = "camelCase")]
200200
pub struct InputValue {
201201
name: Option<String>,
@@ -205,109 +205,109 @@ pub struct InputValue {
205205
default_value: Option<String>,
206206
}
207207

208-
#[derive(Debug, Deserialize)]
208+
#[derive(Clone, Debug, Deserialize)]
209209
#[serde(rename_all = "camelCase")]
210210
pub struct InputValueType {
211211
#[serde(flatten)]
212-
type_ref: TypeRef,
212+
pub type_ref: TypeRef,
213213
}
214214

215-
#[derive(Debug, Deserialize)]
215+
#[derive(Clone, Debug, Deserialize)]
216216
#[serde(rename_all = "camelCase")]
217217
pub struct TypeRef {
218-
kind: Option<__TypeKind>,
219-
name: Option<String>,
220-
of_type: Option<TypeRefOfType>,
218+
pub kind: Option<__TypeKind>,
219+
pub name: Option<String>,
220+
pub of_type: Option<Box<TypeRef>>,
221221
}
222222

223-
#[derive(Debug, Deserialize)]
223+
#[derive(Clone, Debug, Deserialize)]
224224
#[serde(rename_all = "camelCase")]
225225
pub struct TypeRefOfTypeOfTypeOfTypeOfTypeOfTypeOfTypeOfType {
226226
kind: Option<__TypeKind>,
227227
name: Option<String>,
228228
}
229229

230-
#[derive(Debug, Deserialize)]
230+
#[derive(Clone, Debug, Deserialize)]
231231
#[serde(rename_all = "camelCase")]
232232
pub struct TypeRefOfTypeOfTypeOfTypeOfTypeOfTypeOfType {
233233
kind: Option<__TypeKind>,
234234
name: Option<String>,
235235
of_type: Option<TypeRefOfTypeOfTypeOfTypeOfTypeOfTypeOfTypeOfType>,
236236
}
237237

238-
#[derive(Debug, Deserialize)]
238+
#[derive(Clone, Debug, Deserialize)]
239239
#[serde(rename_all = "camelCase")]
240240
pub struct TypeRefOfTypeOfTypeOfTypeOfTypeOfType {
241241
kind: Option<__TypeKind>,
242242
name: Option<String>,
243243
of_type: Option<TypeRefOfTypeOfTypeOfTypeOfTypeOfTypeOfType>,
244244
}
245245

246-
#[derive(Debug, Deserialize)]
246+
#[derive(Clone, Debug, Deserialize)]
247247
#[serde(rename_all = "camelCase")]
248248
pub struct TypeRefOfTypeOfTypeOfTypeOfType {
249249
kind: Option<__TypeKind>,
250250
name: Option<String>,
251251
of_type: Option<TypeRefOfTypeOfTypeOfTypeOfTypeOfType>,
252252
}
253253

254-
#[derive(Debug, Deserialize)]
254+
#[derive(Clone, Debug, Deserialize)]
255255
#[serde(rename_all = "camelCase")]
256256
pub struct TypeRefOfTypeOfTypeOfType {
257257
kind: Option<__TypeKind>,
258258
name: Option<String>,
259259
of_type: Option<TypeRefOfTypeOfTypeOfTypeOfType>,
260260
}
261261

262-
#[derive(Debug, Deserialize)]
262+
#[derive(Clone, Debug, Deserialize)]
263263
#[serde(rename_all = "camelCase")]
264264
pub struct TypeRefOfTypeOfType {
265265
kind: Option<__TypeKind>,
266266
name: Option<String>,
267267
of_type: Option<TypeRefOfTypeOfTypeOfType>,
268268
}
269269

270-
#[derive(Debug, Deserialize)]
270+
#[derive(Clone, Debug, Deserialize)]
271271
#[serde(rename_all = "camelCase")]
272272
pub struct TypeRefOfType {
273273
kind: Option<__TypeKind>,
274274
name: Option<String>,
275275
of_type: Option<TypeRefOfTypeOfType>,
276276
}
277277

278-
#[derive(Debug, Deserialize)]
278+
#[derive(Clone, Debug, Deserialize)]
279279
#[serde(rename_all = "camelCase")]
280280
pub struct RustIntrospectionQuerySchemaQueryType {
281281
name: Option<String>,
282282
}
283283

284-
#[derive(Debug, Deserialize)]
284+
#[derive(Clone, Debug, Deserialize)]
285285
#[serde(rename_all = "camelCase")]
286286
pub struct RustIntrospectionQuerySchemaMutationType {
287287
name: Option<String>,
288288
}
289289

290-
#[derive(Debug, Deserialize)]
290+
#[derive(Clone, Debug, Deserialize)]
291291
#[serde(rename_all = "camelCase")]
292292
pub struct RustIntrospectionQuerySchemaSubscriptionType {
293293
name: Option<String>,
294294
}
295295

296-
#[derive(Debug, Deserialize)]
296+
#[derive(Clone, Debug, Deserialize)]
297297
#[serde(rename_all = "camelCase")]
298298
pub struct RustIntrospectionQuerySchemaTypes {
299299
#[serde(flatten)]
300300
pub full_type: FullType,
301301
}
302302

303-
#[derive(Debug, Deserialize)]
303+
#[derive(Clone, Debug, Deserialize)]
304304
#[serde(rename_all = "camelCase")]
305305
pub struct RustIntrospectionQuerySchemaDirectivesArgs {
306306
#[serde(flatten)]
307307
input_value: InputValue,
308308
}
309309

310-
#[derive(Debug, Deserialize)]
310+
#[derive(Clone, Debug, Deserialize)]
311311
#[serde(rename_all = "camelCase")]
312312
pub struct RustIntrospectionQuerySchemaDirectives {
313313
name: Option<String>,
@@ -316,7 +316,7 @@ pub struct RustIntrospectionQuerySchemaDirectives {
316316
args: Option<Vec<Option<RustIntrospectionQuerySchemaDirectivesArgs>>>,
317317
}
318318

319-
#[derive(Debug, Deserialize)]
319+
#[derive(Clone, Debug, Deserialize)]
320320
#[serde(rename_all = "camelCase")]
321321
pub struct RustIntrospectionQuerySchema {
322322
pub query_type: Option<RustIntrospectionQuerySchemaQueryType>,
@@ -326,13 +326,13 @@ pub struct RustIntrospectionQuerySchema {
326326
directives: Option<Vec<Option<RustIntrospectionQuerySchemaDirectives>>>,
327327
}
328328

329-
#[derive(Debug, Deserialize)]
329+
#[derive(Clone, Debug, Deserialize)]
330330
pub struct Schema {
331331
#[serde(rename = "__schema")]
332332
pub schema: Option<RustIntrospectionQuerySchema>,
333333
}
334334

335-
#[derive(Debug, Deserialize)]
335+
#[derive(Clone, Debug, Deserialize)]
336336
pub struct IntrospectionResponse {
337-
pub data: Schema
337+
pub data: Schema,
338338
}

graphql_query_derive/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,10 @@ fn impl_gql_query(input: &syn::DeriveInput) -> Result<TokenStream, failure::Erro
6363
let mut schema_string = String::new();
6464
::std::fs::File::open(&schema_path)?.read_to_string(&mut schema_string)?;
6565

66-
let extension = schema_path.extension().and_then(|e| e.to_str()).unwrap_or("INVALID");
66+
let extension = schema_path
67+
.extension()
68+
.and_then(|e| e.to_str())
69+
.unwrap_or("INVALID");
6770

6871
let schema = match extension {
6972
"graphql" | "gql" => {

graphql_query_derive/src/schema.rs

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use proc_macro2::TokenStream;
1010
use query::QueryContext;
1111
use std::collections::{BTreeMap, BTreeSet};
1212
use unions::GqlUnion;
13+
use introspection_response;
1314

1415
pub const DEFAULT_SCALARS: &[&'static str] = &["ID", "String", "Int", "Float", "Boolean"];
1516

@@ -259,26 +260,67 @@ impl ::std::convert::From<graphql_parser::schema::Document> for Schema {
259260

260261
impl ::std::convert::From<::introspection_response::IntrospectionResponse> for Schema {
261262
fn from(src: ::introspection_response::IntrospectionResponse) -> Self {
262-
use introspection_response::{__TypeKind};
263+
use introspection_response::__TypeKind;
263264

264265
let mut schema = Schema::new();
265266
let root = src.data.schema.expect("__Schema is not null");
266267

267-
for ty in root.types.expect("types in schema").iter().filter_map(|t| t.as_ref().map(|t| &t.full_type)) {
268-
match ty.kind {
268+
for ty in root
269+
.types
270+
.expect("types in schema")
271+
.iter()
272+
.filter_map(|t| t.as_ref().map(|t| &t.full_type))
273+
{
274+
let name = ty.name.clone().expect("type definition name");
275+
276+
match ty.kind {
269277
Some(__TypeKind::ENUM) => {
270-
let name = ty.name.clone().expect("enum name");
271-
let variants: Vec<String> = ty.enum_values.clone().expect("enum variants")
278+
let variants: Vec<String> = ty
279+
.enum_values
280+
.clone()
281+
.expect("enum variants")
272282
.iter()
273283
.map(|t| t.clone().map(|t| t.name.expect("enum variant name")))
274284
.filter_map(|t| t)
275285
.collect();
276-
schema.enums.insert(name.clone(), GqlEnum {
286+
schema
287+
.enums
288+
.insert(name.clone(), GqlEnum { name, variants });
289+
}
290+
Some(__TypeKind::SCALAR) => {
291+
schema.scalars.insert(name);
292+
}
293+
Some(__TypeKind::UNION) => {
294+
let variants: Vec<String> = ty
295+
.possible_types
296+
.clone()
297+
.unwrap()
298+
.into_iter()
299+
.filter_map(|t| t.and_then(|t| t.type_ref.name.clone()))
300+
.collect();
301+
schema.unions.insert(name.clone(), GqlUnion(variants));
302+
}
303+
Some(__TypeKind::OBJECT) => {
304+
let fields: Vec<GqlObjectField> = ty
305+
.fields
306+
.clone()
307+
.unwrap()
308+
.into_iter()
309+
.filter_map(|t| t.map(|t| GqlObjectField {
310+
name: t.name.expect("field name"),
311+
type_: FieldType::from(t.type_.expect("field type"))
312+
}))
313+
.collect();
314+
schema.objects.insert(name.clone(), GqlObject {
277315
name,
278-
variants,
316+
fields,
279317
});
280318
}
281-
_ => unimplemented!("unimplemented definition")
319+
Some(__TypeKind::INTERFACE) => {
320+
},
321+
Some(__TypeKind::INPUT_OBJECT) => {
322+
},
323+
_ => unimplemented!("unimplemented definition"),
282324
}
283325
}
284326

0 commit comments

Comments
 (0)