Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions graphql_query_derive/src/fragments.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use graphql_parser::query::SelectionSet;
use selection::Selection;
use proc_macro2::{Ident, Span, TokenStream};
use query::QueryContext;

#[derive(Debug, PartialEq)]
pub struct GqlFragment {
pub name: String,
pub on: String,
pub selection: SelectionSet,
pub selection: Selection,
}

impl GqlFragment {
Expand Down
4 changes: 2 additions & 2 deletions graphql_query_derive/src/interfaces.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use graphql_parser::query;
use selection::Selection;
use objects::GqlObjectField;
use proc_macro2::{Ident, Span, TokenStream};
use query::QueryContext;
Expand All @@ -14,7 +14,7 @@ impl GqlInterface {
pub fn response_for_selection(
&self,
_query_context: &QueryContext,
_selection: &query::SelectionSet,
_selection: &Selection,
prefix: &str,
) -> TokenStream {
let name = Ident::new(&prefix, Span::call_site());
Expand Down
22 changes: 11 additions & 11 deletions graphql_query_derive/src/objects.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use failure;
use field_type::FieldType;
use graphql_parser::query;
use heck::{CamelCase, SnakeCase};
use proc_macro2::{Ident, Span, TokenStream};
use query::QueryContext;
use shared::render_object_field;
use selection::*;

#[derive(Debug, PartialEq)]
pub struct GqlObject {
Expand All @@ -22,7 +22,7 @@ impl GqlObject {
pub fn response_for_selection(
&self,
query_context: &QueryContext,
selection: &query::SelectionSet,
selection: &Selection,
prefix: &str,
) -> Result<TokenStream, failure::Error> {
let name = Ident::new(prefix, Span::call_site());
Expand All @@ -41,14 +41,14 @@ impl GqlObject {
pub fn field_impls_for_selection(
&self,
query_context: &QueryContext,
selection: &query::SelectionSet,
selection: &Selection,
prefix: &str,
) -> Result<Vec<TokenStream>, failure::Error> {
selection
.items
.0
.iter()
.map(|selected| {
if let query::Selection::Field(selected) = selected {
if let SelectionItem::Field(selected) = selected {
let ty = self
.fields
.iter()
Expand All @@ -61,7 +61,7 @@ impl GqlObject {
prefix.to_camel_case(),
selected.name.to_camel_case()
);
query_context.maybe_expand_field(&selected, &ty, &prefix)
query_context.maybe_expand_field(&ty, &selected.fields, &prefix)
} else {
Ok(quote!())
}
Expand All @@ -72,14 +72,14 @@ impl GqlObject {
pub fn response_fields_for_selection(
&self,
query_context: &QueryContext,
selection: &query::SelectionSet,
selection: &Selection,
prefix: &str,
) -> Vec<TokenStream> {
let mut fields = Vec::new();

for item in selection.items.iter() {
for item in selection.0.iter() {
match item {
query::Selection::Field(f) => {
SelectionItem::Field(f) => {
let name = &f.name;
let ty = &self
.fields
Expand All @@ -93,7 +93,7 @@ impl GqlObject {
);
fields.push(render_object_field(name, ty));
}
query::Selection::FragmentSpread(fragment) => {
SelectionItem::FragmentSpread(fragment) => {
let field_name =
Ident::new(&fragment.fragment_name.to_snake_case(), Span::call_site());
let type_name = Ident::new(&fragment.fragment_name, Span::call_site());
Expand All @@ -102,7 +102,7 @@ impl GqlObject {
#field_name: #type_name
})
}
query::Selection::InlineFragment(_) => {
SelectionItem::InlineFragment(_) => {
unreachable!("inline fragment on object field")
}
}
Expand Down
10 changes: 5 additions & 5 deletions graphql_query_derive/src/query.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use failure;
use field_type::FieldType;
use fragments::GqlFragment;
use graphql_parser::query;
use proc_macro2::TokenStream;
use schema::Schema;
use std::collections::BTreeMap;
use selection::Selection;

pub struct QueryContext {
pub _subscription_root: Option<Vec<TokenStream>>,
Expand Down Expand Up @@ -42,18 +42,18 @@ impl QueryContext {

pub fn maybe_expand_field(
&self,
field: &query::Field,
ty: &str,
selection: &Selection,
prefix: &str,
) -> Result<TokenStream, failure::Error> {
if let Some(_enm) = self.schema.enums.get(ty) {
Ok(quote!()) // we already expand enums separately
} else if let Some(obj) = self.schema.objects.get(ty) {
obj.response_for_selection(self, &field.selection_set, prefix)
obj.response_for_selection(self, &selection, prefix)
} else if let Some(iface) = self.schema.interfaces.get(ty) {
Ok(iface.response_for_selection(self, &field.selection_set, prefix))
Ok(iface.response_for_selection(self, &selection, prefix))
} else if let Some(unn) = self.schema.unions.get(ty) {
Ok(unn.response_for_selection(self, &field.selection_set, prefix))
Ok(unn.response_for_selection(self, &selection, prefix))
} else {
Ok(quote!())
}
Expand Down
20 changes: 13 additions & 7 deletions graphql_query_derive/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use objects::{GqlObject, GqlObjectField};
use proc_macro2::TokenStream;
use query::QueryContext;
use std::collections::{BTreeMap, BTreeSet};
use selection::Selection;
use unions::GqlUnion;

pub const DEFAULT_SCALARS: &[&'static str] = &["ID", "String", "Int", "Float", "Boolean"];
Expand Down Expand Up @@ -57,14 +58,16 @@ impl Schema {
.expect("query type is defined");
let prefix = &q.name.expect("unnamed operation");
let prefix = format!("RUST_{}", prefix);
let selection = Selection::from(&q.selection_set);

definitions.extend(definition.field_impls_for_selection(
&context,
&q.selection_set,
&selection,
&prefix,
)?);
Some(definition.response_fields_for_selection(
&context,
&q.selection_set,
&selection,
&prefix,
))
};
Expand All @@ -79,15 +82,16 @@ impl Schema {
.expect("mutation type is defined");
let prefix = &q.name.expect("unnamed operation");
let prefix = format!("RUST_{}", prefix);
let selection = Selection::from(&q.selection_set);

definitions.extend(definition.field_impls_for_selection(
&context,
&q.selection_set,
&selection,
&prefix,
)?);
Some(definition.response_fields_for_selection(
&context,
&q.selection_set,
&selection,
&prefix,
))
};
Expand All @@ -104,14 +108,16 @@ impl Schema {
.expect("subscription type is defined");
let prefix = &q.name.expect("unnamed operation");
let prefix = format!("RUST_{}", prefix);
let selection = Selection::from(&q.selection_set);

definitions.extend(definition.field_impls_for_selection(
&context,
&q.selection_set,
&selection,
&prefix,
)?);
Some(definition.response_fields_for_selection(
&context,
&q.selection_set,
&selection,
&prefix,
))
};
Expand All @@ -125,7 +131,7 @@ impl Schema {
fragment.name.clone(),
GqlFragment {
name: fragment.name,
selection: fragment.selection_set,
selection: Selection::from(&fragment.selection_set),
on,
},
);
Expand Down
12 changes: 6 additions & 6 deletions graphql_query_derive/src/selection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ use graphql_parser::query::SelectionSet;

#[derive(Debug, PartialEq)]
pub struct SelectionField {
name: String,
fields: Selection,
pub name: String,
pub fields: Selection,
}

#[derive(Debug, PartialEq)]
pub struct SelectionFragmentSpread {
fragment_name: String,
pub fragment_name: String,
}

#[derive(Debug, PartialEq)]
pub struct SelectionInlineFragment {
on: String,
fields: Selection,
pub on: String,
pub fields: Selection,
}

#[derive(Debug, PartialEq)]
Expand All @@ -25,7 +25,7 @@ pub enum SelectionItem {
}

#[derive(Debug, PartialEq)]
pub struct Selection(Vec<SelectionItem>);
pub struct Selection(pub Vec<SelectionItem>);

impl<'a> ::std::convert::From<&'a SelectionSet> for Selection {
fn from(selection_set: &SelectionSet) -> Selection {
Expand Down
56 changes: 50 additions & 6 deletions graphql_query_derive/src/unions.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,63 @@
use graphql_parser::query;
use proc_macro2::TokenStream;
use proc_macro2::{Ident, Span, TokenStream};
use query::QueryContext;
use std::collections::BTreeSet;
use selection::{Selection, SelectionItem};
use heck::SnakeCase;

#[derive(Debug, PartialEq)]
pub struct GqlUnion(pub BTreeSet<String>);

impl GqlUnion {
pub fn response_for_selection(
&self,
_query_context: &QueryContext,
_selection: &query::SelectionSet,
_prefix: &str,
query_context: &QueryContext,
selection: &Selection,
prefix: &str,
) -> TokenStream {
unimplemented!("union generation")
let struct_name = Ident::new(prefix, Span::call_site());
let mut children_definitions = Vec::new();
let fields = selection.0.iter().map(|item| {
match item {
SelectionItem::Field(_) => unreachable!("field selection on union"),
SelectionItem::FragmentSpread(_) => unreachable!("fragment spread on union"),
SelectionItem::InlineFragment(frag) => {
let field_name = Ident::new(
&format!("on_{}", frag.on).to_snake_case(),
Span::call_site(),
);

let field_type = Ident::new(&format!("{}On{}", prefix, frag.on), Span::call_site());

let new_prefix = format!("{}On{}", prefix, frag.on);

let field_object_type = query_context.schema.objects.get(&frag.on)
.map(|f| query_context.maybe_expand_field(&frag.on, &frag.fields, &new_prefix));
let field_interface = query_context.schema.interfaces.get(&frag.on)
.map(|f| query_context.maybe_expand_field(&frag.on, &frag.fields, &new_prefix));
// nested unions, is that even a thing?
let field_union_type = query_context.schema.unions.get(&frag.on)
.map(|f| query_context.maybe_expand_field(&frag.on, &frag.fields, &new_prefix));

if let Some(tokens) = field_object_type.or(field_interface).or(field_union_type) {
children_definitions.push(tokens)
}

// query_context.maybe_expand_field(

// );
quote! {
#field_name: #field_type
}
}
}
});

quote!{
#[derive(Deserialize)]
pub struct #struct_name {
#(#fields),*
}
}
}
}

Expand Down