From 3df18f41f80af0c8044ded53ca6688d212b67ada Mon Sep 17 00:00:00 2001 From: Christoph Herzog <chris@theduke.at> Date: Wed, 2 May 2018 23:13:38 +0200 Subject: [PATCH 01/18] (juniper_rocket) Bump minimum rocket version to 0.3.9 Needed to bump minimum version to allow working on latest nightly. --- juniper_rocket/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/juniper_rocket/Cargo.toml b/juniper_rocket/Cargo.toml index c3729bbb..bc123b04 100644 --- a/juniper_rocket/Cargo.toml +++ b/juniper_rocket/Cargo.toml @@ -16,8 +16,8 @@ serde_derive = {version="1.0.2" } serde_json = { version = "1.0.2" } juniper = { version = "0.9.2" , path = "../juniper"} -rocket = { version = "0.3.6" } -rocket_codegen = { version = "0.3.6" } +rocket = { version = "0.3.9" } +rocket_codegen = { version = "0.3.9" } [dev-dependencies.juniper] version = "0.9.2" From 05c1011d8309e093703286273832167326efb550 Mon Sep 17 00:00:00 2001 From: Christoph Herzog <chris@theduke.at> Date: Thu, 3 May 2018 01:21:08 +0200 Subject: [PATCH 02/18] (juniper_codegen) Upgrade syn + quote --- juniper_codegen/Cargo.toml | 4 +- juniper_codegen/src/derive_enum.rs | 46 ++++++++++------- juniper_codegen/src/derive_input_object.rs | 53 ++++++++++++------- juniper_codegen/src/derive_object.rs | 25 +++++---- juniper_codegen/src/lib.rs | 15 +++--- juniper_codegen/src/util.rs | 59 ++++++++++------------ 6 files changed, 116 insertions(+), 86 deletions(-) diff --git a/juniper_codegen/Cargo.toml b/juniper_codegen/Cargo.toml index 176f8bb6..13dbd08d 100644 --- a/juniper_codegen/Cargo.toml +++ b/juniper_codegen/Cargo.toml @@ -14,8 +14,8 @@ repository = "https://github.com/graphql-rust/juniper" proc-macro = true [dependencies] -syn = "0.11" -quote = "0.3" +syn = { version = "0.13.*", features = ["full", "extra-traits"] } +quote = "0.5.*" [badges] travis-ci = { repository = "graphql-rust/juniper" } diff --git a/juniper_codegen/src/derive_enum.rs b/juniper_codegen/src/derive_enum.rs index d22fb999..83b9bf78 100644 --- a/juniper_codegen/src/derive_enum.rs +++ b/juniper_codegen/src/derive_enum.rs @@ -1,5 +1,13 @@ use syn; -use syn::*; +use syn::{ + DeriveInput, + Meta, + NestedMeta, + Data, + Fields, + Ident, + Variant, +}; use quote::Tokens; use util::*; @@ -23,16 +31,16 @@ impl EnumAttrs { // Check attributes for name and description. if let Some(items) = get_graphl_attr(&input.attrs) { for item in items { - if let Some(val) = keyed_item_value(item, "name", true) { + if let Some(val) = keyed_item_value(&item, "name", true) { res.name = Some(val); continue; } - if let Some(val) = keyed_item_value(item, "description", true) { + if let Some(val) = keyed_item_value(&item, "description", true) { res.description = Some(val); continue; } match item { - &NestedMetaItem::MetaItem(MetaItem::Word(ref ident)) => { + NestedMeta::Meta(Meta::Word(ref ident)) => { if ident == "_internal" { res.internal = true; continue; @@ -64,15 +72,15 @@ impl EnumVariantAttrs { // Check attributes for name and description. if let Some(items) = get_graphl_attr(&variant.attrs) { for item in items { - if let Some(val) = keyed_item_value(item, "name", true) { + if let Some(val) = keyed_item_value(&item, "name", true) { res.name = Some(val); continue; } - if let Some(val) = keyed_item_value(item, "description", true) { + if let Some(val) = keyed_item_value(&item, "description", true) { res.description = Some(val); continue; } - if let Some(val) = keyed_item_value(item, "deprecated", true) { + if let Some(val) = keyed_item_value(&item, "deprecated", true) { res.deprecation = Some(val); continue; } @@ -87,9 +95,9 @@ impl EnumVariantAttrs { } pub fn impl_enum(ast: &syn::DeriveInput) -> Tokens { - let variants = match ast.body { - Body::Enum(ref var) => var, - Body::Struct(_) => { + let variants = match ast.data { + Data::Enum(ref enum_data) => enum_data.variants.iter().collect::<Vec<_>>(), + _ => { panic!("#[derive(GraphlQLEnum)] may only be applied to enums, not to structs"); } }; @@ -110,12 +118,16 @@ pub fn impl_enum(ast: &syn::DeriveInput) -> Tokens { let mut to_inputs = Vec::<Tokens>::new(); for variant in variants { - if variant.data != VariantData::Unit { - panic!(format!( - "Invalid enum variant {}.\nGraphQL enums may only contain unit variants.", - variant.ident - )); - } + match variant.fields { + Fields::Unit => {}, + _ => { + panic!(format!( + "Invalid enum variant {}.\nGraphQL enums may only contain unit variants.", + variant.ident + )); + } + } ; + let var_attrs = EnumVariantAttrs::from_input(variant); let var_ident = &variant.ident; @@ -209,7 +221,7 @@ pub fn impl_enum(ast: &syn::DeriveInput) -> Tokens { } }; - let dummy_const = Ident::new(format!("_IMPL_GRAPHQLENUM_FOR_{}", ident)); + let dummy_const = Ident::from(format!("_IMPL_GRAPHQLENUM_FOR_{}", ident).as_str()); // This ugly hack makes it possible to use the derive inside juniper itself. // FIXME: Figure out a better way to do this! diff --git a/juniper_codegen/src/derive_input_object.rs b/juniper_codegen/src/derive_input_object.rs index 95dce59e..f645a3ec 100644 --- a/juniper_codegen/src/derive_input_object.rs +++ b/juniper_codegen/src/derive_input_object.rs @@ -1,6 +1,16 @@ -use syn; -use syn::*; -use quote::Tokens; +use std::str::FromStr; + +use syn::{ + self, + DeriveInput, + NestedMeta, + Meta, + Field, + Fields, + Data, + Ident, +}; +use quote::{Tokens, ToTokens}; use util::*; @@ -18,16 +28,16 @@ impl ObjAttrs { // Check attributes for name and description. if let Some(items) = get_graphl_attr(&input.attrs) { for item in items { - if let Some(val) = keyed_item_value(item, "name", true) { + if let Some(val) = keyed_item_value(&item, "name", true) { res.name = Some(val); continue; } - if let Some(val) = keyed_item_value(item, "description", true) { + if let Some(val) = keyed_item_value(&item, "description", true) { res.description = Some(val); continue; } match item { - &NestedMetaItem::MetaItem(MetaItem::Word(ref ident)) => { + NestedMeta::Meta(Meta::Word(ref ident)) => { if ident == "_internal" { res.internal = true; continue; @@ -60,20 +70,20 @@ impl ObjFieldAttrs { // Check attributes for name and description. if let Some(items) = get_graphl_attr(&variant.attrs) { for item in items { - if let Some(val) = keyed_item_value(item, "name", true) { + if let Some(val) = keyed_item_value(&item, "name", true) { res.name = Some(val); continue; } - if let Some(val) = keyed_item_value(item, "description", true) { + if let Some(val) = keyed_item_value(&item, "description", true) { res.description = Some(val); continue; } - if let Some(val) = keyed_item_value(item, "default", true) { + if let Some(val) = keyed_item_value(&item, "default", true) { res.default_expr = Some(val); continue; } match item { - &NestedMetaItem::MetaItem(MetaItem::Word(ref ident)) => { + NestedMeta::Meta(Meta::Word(ref ident)) => { if ident == "default" { res.default = true; continue; @@ -92,16 +102,16 @@ impl ObjFieldAttrs { } pub fn impl_input_object(ast: &syn::DeriveInput) -> Tokens { - let fields = match ast.body { - Body::Struct(ref data) => match data { - &VariantData::Struct(ref fields) => fields, + let fields = match ast.data { + Data::Struct(ref data) => match data.fields { + Fields::Named(ref named) => named.named.iter().collect::<Vec<_>>(), _ => { panic!( "#[derive(GraphQLInputObject)] may only be used on regular structs with fields" ); } }, - Body::Enum(_) => { + _ => { panic!("#[derive(GraphlQLInputObject)] may only be applied to structs, not to enums"); } }; @@ -146,8 +156,17 @@ pub fn impl_input_object(ast: &syn::DeriveInput) -> Tokens { Some(quote! { Default::default() }) } else { match field_attrs.default_expr { - Some(ref def) => match syn::parse_token_trees(def) { - Ok(t) => Some(quote! { #(#t)* }), + Some(ref def) => match ::proc_macro::TokenStream::from_str(def) { + Ok(t) => { + match syn::parse::<syn::Expr>(t) { + Ok(e) => { + Some(e.into_tokens()) + }, + Err(_) => { + panic!("#graphql(default = ?) must be a valid Rust expression inside a string"); + }, + } + }, Err(_) => { panic!("#graphql(default = ?) must be a valid Rust expression inside a string"); } @@ -256,7 +275,7 @@ pub fn impl_input_object(ast: &syn::DeriveInput) -> Tokens { } }; - let dummy_const = Ident::new(format!("_IMPL_GRAPHQLINPUTOBJECT_FOR_{}", ident)); + let dummy_const = Ident::from(format!("_IMPL_GRAPHQLINPUTOBJECT_FOR_{}", ident).as_str()); // This ugly hack makes it possible to use the derive inside juniper itself. // FIXME: Figure out a better way to do this! diff --git a/juniper_codegen/src/derive_object.rs b/juniper_codegen/src/derive_object.rs index e777d071..67133201 100644 --- a/juniper_codegen/src/derive_object.rs +++ b/juniper_codegen/src/derive_object.rs @@ -1,5 +1,10 @@ use syn; -use syn::*; +use syn::{ + DeriveInput, + Data, + Fields, + Field, +}; use quote::Tokens; use util::*; @@ -17,11 +22,11 @@ impl ObjAttrs { // Check attributes for name and description. if let Some(items) = get_graphl_attr(&input.attrs) { for item in items { - if let Some(val) = keyed_item_value(item, "name", true) { + if let Some(val) = keyed_item_value(&item, "name", true) { res.name = Some(val); continue; } - if let Some(val) = keyed_item_value(item, "description", true) { + if let Some(val) = keyed_item_value(&item, "description", true) { res.description = Some(val); continue; } @@ -49,15 +54,15 @@ impl ObjFieldAttrs { // Check attributes for name and description. if let Some(items) = get_graphl_attr(&variant.attrs) { for item in items { - if let Some(val) = keyed_item_value(item, "name", true) { + if let Some(val) = keyed_item_value(&item, "name", true) { res.name = Some(val); continue; } - if let Some(val) = keyed_item_value(item, "description", true) { + if let Some(val) = keyed_item_value(&item, "description", true) { res.description = Some(val); continue; } - if let Some(val) = keyed_item_value(item, "deprecation", true) { + if let Some(val) = keyed_item_value(&item, "deprecation", true) { res.deprecation = Some(val); continue; } @@ -72,14 +77,14 @@ impl ObjFieldAttrs { } pub fn impl_object(ast: &syn::DeriveInput) -> Tokens { - let fields = match ast.body { - Body::Struct(ref data) => match data { - &VariantData::Struct(ref fields) => fields, + let fields = match ast.data { + Data::Struct(ref data) => match data.fields { + Fields::Named(ref fields) => fields.named.iter().collect::<Vec<_>>(), _ => { panic!("#[derive(GraphQLObject)] may only be used on regular structs with fields"); } }, - Body::Enum(_) => { + _ => { panic!("#[derive(GraphlQLObject)] may only be applied to structs, not to enums"); } }; diff --git a/juniper_codegen/src/lib.rs b/juniper_codegen/src/lib.rs index 8c124901..55d7045f 100644 --- a/juniper_codegen/src/lib.rs +++ b/juniper_codegen/src/lib.rs @@ -20,24 +20,21 @@ use proc_macro::TokenStream; #[proc_macro_derive(GraphQLEnum, attributes(graphql))] pub fn derive_enum(input: TokenStream) -> TokenStream { - let s = input.to_string(); - let ast = syn::parse_derive_input(&s).unwrap(); + let ast = syn::parse::<syn::DeriveInput>(input).unwrap(); let gen = derive_enum::impl_enum(&ast); - gen.parse().unwrap() + gen.into() } #[proc_macro_derive(GraphQLInputObject, attributes(graphql))] pub fn derive_input_object(input: TokenStream) -> TokenStream { - let s = input.to_string(); - let ast = syn::parse_derive_input(&s).unwrap(); + let ast = syn::parse::<syn::DeriveInput>(input).unwrap(); let gen = derive_input_object::impl_input_object(&ast); - gen.parse().unwrap() + gen.into() } #[proc_macro_derive(GraphQLObject, attributes(graphql))] pub fn derive_object(input: TokenStream) -> TokenStream { - let s = input.to_string(); - let ast = syn::parse_derive_input(&s).unwrap(); + let ast = syn::parse::<syn::DeriveInput>(input).unwrap(); let gen = derive_object::impl_object(&ast); - gen.parse().unwrap() + gen.into() } diff --git a/juniper_codegen/src/util.rs b/juniper_codegen/src/util.rs index d22b741d..ac1afefd 100644 --- a/juniper_codegen/src/util.rs +++ b/juniper_codegen/src/util.rs @@ -1,10 +1,16 @@ -use syn::*; +use syn::{ + Attribute, + Meta, + NestedMeta, + Lit, +}; -pub fn get_graphl_attr(attrs: &Vec<Attribute>) -> Option<&Vec<NestedMetaItem>> { +// Get the nested items of a a #[graphql(...)] attribute. +pub fn get_graphl_attr(attrs: &Vec<Attribute>) -> Option<Vec<NestedMeta>> { for attr in attrs { - match attr.value { - MetaItem::List(ref attr_name, ref items) => if attr_name == "graphql" { - return Some(items); + match attr.interpret_meta() { + Some(Meta::List(ref list)) if list.ident == "graphql" => { + return Some(list.nested.iter().map(|x| x.clone()).collect()); }, _ => {} } @@ -12,33 +18,24 @@ pub fn get_graphl_attr(attrs: &Vec<Attribute>) -> Option<&Vec<NestedMetaItem>> { None } -pub fn keyed_item_value(item: &NestedMetaItem, name: &str, must_be_string: bool) -> Option<String> { - let item = match item { - &NestedMetaItem::MetaItem(ref item) => item, - _ => { - return None; - } - }; - let lit = match item { - &MetaItem::NameValue(ref ident, ref lit) => if ident == name { - lit - } else { - return None; - }, - _ => { - return None; - } - }; - match lit { - &Lit::Str(ref val, _) => Some(val.clone()), - _ => if must_be_string { - panic!(format!( - "Invalid format for attribute \"{:?}\": expected a string", - item - )); - } else { - None +pub fn keyed_item_value(item: &NestedMeta, name: &str, must_be_string: bool) -> Option<String> { + match item { + &NestedMeta::Meta(Meta::NameValue(ref nameval)) if nameval.ident == name => { + match &nameval.lit { + &Lit::Str(ref strlit) => { + Some(strlit.value()) + }, + _ => if must_be_string { + panic!(format!( + "Invalid format for attribute \"{:?}\": expected a string", + item + )); + } else { + None + }, + } }, + _ => None, } } From ea3c425f0417288f098b30e12703c457f39a99ee Mon Sep 17 00:00:00 2001 From: Atul Bhosale <atul1bhosale@gmail.com> Date: Tue, 23 Jan 2018 01:08:48 +0530 Subject: [PATCH 03/18] Replace try! with ? --- juniper/src/ast.rs | 14 +- juniper/src/executor/mod.rs | 3 +- .../introspection/input_object.rs | 12 +- juniper/src/executor_tests/variables.rs | 3 +- juniper/src/http/mod.rs | 19 +-- juniper/src/integrations/serde.rs | 52 +++---- juniper/src/lib.rs | 2 +- juniper/src/parser/document.rs | 134 +++++++++--------- juniper/src/parser/lexer.rs | 66 ++++----- juniper/src/parser/parser.rs | 18 +-- juniper/src/parser/value.rs | 34 +++-- juniper/src/schema/meta.rs | 99 ++++++++----- juniper/src/schema/model.rs | 15 +- juniper/src/types/name.rs | 2 +- 14 files changed, 260 insertions(+), 213 deletions(-) diff --git a/juniper/src/ast.rs b/juniper/src/ast.rs index 8d5c0ae9..45547ff4 100644 --- a/juniper/src/ast.rs +++ b/juniper/src/ast.rs @@ -432,25 +432,25 @@ impl fmt::Display for InputValue { InputValue::Enum(ref v) => write!(f, "{}", v), InputValue::Variable(ref v) => write!(f, "${}", v), InputValue::List(ref v) => { - try!(write!(f, "[")); + write!(f, "[")?; for (i, spanning) in v.iter().enumerate() { - try!(spanning.item.fmt(f)); + spanning.item.fmt(f)?; if i < v.len() - 1 { - try!(write!(f, ", ")); + write!(f, ", ")?; } } write!(f, "]") } InputValue::Object(ref o) => { - try!(write!(f, "{{")); + write!(f, "{{")?; for (i, &(ref k, ref v)) in o.iter().enumerate() { - try!(write!(f, "{}: ", k.item)); - try!(v.item.fmt(f)); + write!(f, "{}: ", k.item)?; + v.item.fmt(f)?; if i < o.len() - 1 { - try!(write!(f, ", ")); + write!(f, ", ")?; } } diff --git a/juniper/src/executor/mod.rs b/juniper/src/executor/mod.rs index d2001572..85d45913 100644 --- a/juniper/src/executor/mod.rs +++ b/juniper/src/executor/mod.rs @@ -220,7 +220,8 @@ impl<'a, T: GraphQLType, C> IntoResolvable<'a, T, C> for FieldResult<(&'a T::Con } impl<'a, T: GraphQLType, C> IntoResolvable<'a, Option<T>, C> - for FieldResult<Option<(&'a T::Context, T)>> { + for FieldResult<Option<(&'a T::Context, T)>> +{ fn into(self, _: &'a C) -> FieldResult<Option<(&'a T::Context, Option<T>)>> { self.map(|o| o.map(|(ctx, v)| (ctx, Some(v)))) } diff --git a/juniper/src/executor_tests/introspection/input_object.rs b/juniper/src/executor_tests/introspection/input_object.rs index 211fc761..f72d0b5c 100644 --- a/juniper/src/executor_tests/introspection/input_object.rs +++ b/juniper/src/executor_tests/introspection/input_object.rs @@ -68,15 +68,19 @@ pub struct NamedPublic { #[derive(GraphQLInputObject, Debug)] #[graphql(_internal)] struct FieldDescription { - #[graphql(description = "The first field")] field_one: String, - #[graphql(description = "The second field")] field_two: String, + #[graphql(description = "The first field")] + field_one: String, + #[graphql(description = "The second field")] + field_two: String, } #[derive(GraphQLInputObject, Debug)] #[graphql(_internal)] struct FieldWithDefaults { - #[graphql(default = "123")] field_one: i32, - #[graphql(default = "456", description = "The second field")] field_two: i32, + #[graphql(default = "123")] + field_one: i32, + #[graphql(default = "456", description = "The second field")] + field_two: i32, } graphql_object!(Root: () |&self| { diff --git a/juniper/src/executor_tests/variables.rs b/juniper/src/executor_tests/variables.rs index e385cfd8..b67a1ed2 100644 --- a/juniper/src/executor_tests/variables.rs +++ b/juniper/src/executor_tests/variables.rs @@ -56,7 +56,8 @@ struct ExampleInputObject { #[derive(GraphQLInputObject, Debug)] #[graphql(_internal)] struct InputWithDefaults { - #[graphql(default = "123")] a: i32, + #[graphql(default = "123")] + a: i32, } graphql_object!(TestType: () |&self| { diff --git a/juniper/src/http/mod.rs b/juniper/src/http/mod.rs index 03ad2d22..ac975c34 100644 --- a/juniper/src/http/mod.rs +++ b/juniper/src/http/mod.rs @@ -19,7 +19,8 @@ use executor::ExecutionError; #[derive(Deserialize, Clone, Serialize, PartialEq, Debug)] pub struct GraphQLRequest { query: String, - #[serde(rename = "operationName")] operation_name: Option<String>, + #[serde(rename = "operationName")] + operation_name: Option<String>, variables: Option<InputValue>, } @@ -101,22 +102,22 @@ impl<'a> ser::Serialize for GraphQLResponse<'a> { { match self.0 { Ok((ref res, ref err)) => { - let mut map = try!(serializer.serialize_map(None)); + let mut map = serializer.serialize_map(None)?; - try!(map.serialize_key("data")); - try!(map.serialize_value(res)); + map.serialize_key("data")?; + map.serialize_value(res)?; if !err.is_empty() { - try!(map.serialize_key("errors")); - try!(map.serialize_value(err)); + map.serialize_key("errors")?; + map.serialize_value(err)?; } map.end() } Err(ref err) => { - let mut map = try!(serializer.serialize_map(Some(1))); - try!(map.serialize_key("errors")); - try!(map.serialize_value(err)); + let mut map = serializer.serialize_map(Some(1))?; + map.serialize_key("errors")?; + map.serialize_value(err)?; map.end() } } diff --git a/juniper/src/integrations/serde.rs b/juniper/src/integrations/serde.rs index 896c7fa3..55d85d8c 100644 --- a/juniper/src/integrations/serde.rs +++ b/juniper/src/integrations/serde.rs @@ -15,21 +15,21 @@ impl ser::Serialize for ExecutionError { where S: ser::Serializer, { - let mut map = try!(serializer.serialize_map(Some(4))); + let mut map = serializer.serialize_map(Some(4))?; - try!(map.serialize_key("message")); - try!(map.serialize_value(self.error().message())); + map.serialize_key("message")?; + map.serialize_value(self.error().message())?; let locations = vec![self.location()]; - try!(map.serialize_key("locations")); - try!(map.serialize_value(&locations)); + map.serialize_key("locations")?; + map.serialize_value(&locations)?; - try!(map.serialize_key("path")); - try!(map.serialize_value(self.path())); + map.serialize_key("path")?; + map.serialize_value(self.path())?; if !self.error().data().is_null() { - try!(map.serialize_key("data")); - try!(map.serialize_value(self.error().data())); + map.serialize_key("data")?; + map.serialize_value(self.error().data())?; } map.end() @@ -123,7 +123,7 @@ impl<'de> de::Deserialize<'de> for InputValue { { let mut values = Vec::new(); - while let Some(el) = try!(visitor.next_element()) { + while let Some(el) = visitor.next_element()? { values.push(el); } @@ -136,7 +136,7 @@ impl<'de> de::Deserialize<'de> for InputValue { { let mut values: IndexMap<String, InputValue> = IndexMap::new(); - while let Some((key, value)) = try!(visitor.next_entry()) { + while let Some((key, value)) = visitor.next_entry()? { values.insert(key, value); } @@ -176,13 +176,13 @@ impl ser::Serialize for RuleError { where S: ser::Serializer, { - let mut map = try!(serializer.serialize_map(Some(2))); + let mut map = serializer.serialize_map(Some(2))?; - try!(map.serialize_key("message")); - try!(map.serialize_value(self.message())); + map.serialize_key("message")?; + map.serialize_value(self.message())?; - try!(map.serialize_key("locations")); - try!(map.serialize_value(self.locations())); + map.serialize_key("locations")?; + map.serialize_value(self.locations())?; map.end() } @@ -193,15 +193,15 @@ impl ser::Serialize for SourcePosition { where S: ser::Serializer, { - let mut map = try!(serializer.serialize_map(Some(2))); + let mut map = serializer.serialize_map(Some(2))?; let line = self.line() + 1; - try!(map.serialize_key("line")); - try!(map.serialize_value(&line)); + map.serialize_key("line")?; + map.serialize_value(&line)?; let column = self.column() + 1; - try!(map.serialize_key("column")); - try!(map.serialize_value(&column)); + map.serialize_key("column")?; + map.serialize_value(&column)?; map.end() } @@ -212,11 +212,11 @@ impl<'a> ser::Serialize for Spanning<ParseError<'a>> { where S: ser::Serializer, { - let mut map = try!(serializer.serialize_map(Some(2))); + let mut map = serializer.serialize_map(Some(2))?; let message = format!("{}", self.item); - try!(map.serialize_key("message")); - try!(map.serialize_value(&message)); + map.serialize_key("message")?; + map.serialize_value(&message)?; let mut location = IndexMap::new(); location.insert("line".to_owned(), self.start.line() + 1); @@ -224,8 +224,8 @@ impl<'a> ser::Serialize for Spanning<ParseError<'a>> { let locations = vec![location]; - try!(map.serialize_key("locations")); - try!(map.serialize_value(&locations)); + map.serialize_key("locations")?; + map.serialize_value(&locations)?; map.end() } diff --git a/juniper/src/lib.rs b/juniper/src/lib.rs index 8398dd72..10ed9bdd 100644 --- a/juniper/src/lib.rs +++ b/juniper/src/lib.rs @@ -184,7 +184,7 @@ where QueryT: GraphQLType<Context = CtxT>, MutationT: GraphQLType<Context = CtxT>, { - let document = try!(parse_document_source(document_source)); + let document = parse_document_source(document_source)?; { let errors = validate_input_values(variables, &document, &root_node.schema); diff --git a/juniper/src/parser/document.rs b/juniper/src/parser/document.rs index d26e2e48..9e47cc72 100644 --- a/juniper/src/parser/document.rs +++ b/juniper/src/parser/document.rs @@ -11,7 +11,7 @@ use parser::value::parse_value_literal; #[doc(hidden)] pub fn parse_document_source(s: &str) -> UnlocatedParseResult<Document> { let mut lexer = Lexer::new(s); - let mut parser = try!(Parser::new(&mut lexer).map_err(|s| s.map(ParseError::LexerError))); + let mut parser = Parser::new(&mut lexer).map_err(|s| s.map(ParseError::LexerError))?; parse_document(&mut parser) } @@ -19,7 +19,7 @@ fn parse_document<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Docum let mut defs = Vec::new(); loop { - defs.push(try!(parse_definition(parser))); + defs.push(parse_definition(parser)?); if parser.peek().item == Token::EndOfFile { return Ok(defs); @@ -29,19 +29,17 @@ fn parse_document<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Docum fn parse_definition<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Definition<'a>> { match parser.peek().item { - Token::CurlyOpen | Token::Name("query") | Token::Name("mutation") => Ok( - Definition::Operation(try!(parse_operation_definition(parser))), - ), - Token::Name("fragment") => Ok(Definition::Fragment(try!(parse_fragment_definition( - parser - )))), + Token::CurlyOpen | Token::Name("query") | Token::Name("mutation") => { + Ok(Definition::Operation(parse_operation_definition(parser)?)) + } + Token::Name("fragment") => Ok(Definition::Fragment(parse_fragment_definition(parser)?)), _ => Err(parser.next()?.map(ParseError::UnexpectedToken)), } } fn parse_operation_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Operation<'a>> { if parser.peek().item == Token::CurlyOpen { - let selection_set = try!(parse_selection_set(parser)); + let selection_set = parse_selection_set(parser)?; Ok(Spanning::start_end( &selection_set.start, @@ -56,14 +54,14 @@ fn parse_operation_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Op )) } else { let start_pos = parser.peek().start.clone(); - let operation_type = try!(parse_operation_type(parser)); + let operation_type = parse_operation_type(parser)?; let name = match parser.peek().item { - Token::Name(_) => Some(try!(parser.expect_name())), + Token::Name(_) => Some(parser.expect_name()?), _ => None, }; - let variable_definitions = try!(parse_variable_definitions(parser)); - let directives = try!(parse_directives(parser)); - let selection_set = try!(parse_selection_set(parser)); + let variable_definitions = parse_variable_definitions(parser)?; + let directives = parse_directives(parser)?; + let selection_set = parse_selection_set(parser)?; Ok(Spanning::start_end( &start_pos, @@ -82,7 +80,7 @@ fn parse_operation_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Op fn parse_fragment_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Fragment<'a>> { let Spanning { start: start_pos, .. - } = try!(parser.expect(&Token::Name("fragment"))); + } = parser.expect(&Token::Name("fragment"))?; let name = match parser.expect_name() { Ok(n) => if n.item == "on" { return Err(n.map(|_| ParseError::UnexpectedToken(Token::Name("on")))); @@ -92,10 +90,10 @@ fn parse_fragment_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Fra Err(e) => return Err(e), }; - try!(parser.expect(&Token::Name("on"))); - let type_cond = try!(parser.expect_name()); - let directives = try!(parse_directives(parser)); - let selection_set = try!(parse_selection_set(parser)); + parser.expect(&Token::Name("on"))?; + let type_cond = parser.expect_name()?; + let directives = parse_directives(parser)?; + let selection_set = parse_selection_set(parser)?; Ok(Spanning::start_end( &start_pos, @@ -113,7 +111,7 @@ fn parse_optional_selection_set<'a>( parser: &mut Parser<'a>, ) -> OptionParseResult<'a, Vec<Selection<'a>>> { if parser.peek().item == Token::CurlyOpen { - Ok(Some(try!(parse_selection_set(parser)))) + Ok(Some(parse_selection_set(parser)?)) } else { Ok(None) } @@ -134,14 +132,14 @@ fn parse_fragment<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Selec let Spanning { start: ref start_pos, .. - } = try!(parser.expect(&Token::Ellipsis)); + } = parser.expect(&Token::Ellipsis)?; match parser.peek().item { Token::Name("on") => { parser.next()?; - let name = try!(parser.expect_name()); - let directives = try!(parse_directives(parser)); - let selection_set = try!(parse_selection_set(parser)); + let name = parser.expect_name()?; + let directives = parse_directives(parser)?; + let selection_set = parse_selection_set(parser)?; Ok(Selection::InlineFragment(Spanning::start_end( &start_pos.clone(), @@ -154,7 +152,7 @@ fn parse_fragment<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Selec ))) } Token::CurlyOpen => { - let selection_set = try!(parse_selection_set(parser)); + let selection_set = parse_selection_set(parser)?; Ok(Selection::InlineFragment(Spanning::start_end( &start_pos.clone(), @@ -167,8 +165,8 @@ fn parse_fragment<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Selec ))) } Token::Name(_) => { - let frag_name = try!(parser.expect_name()); - let directives = try!(parse_directives(parser)); + let frag_name = parser.expect_name()?; + let directives = parse_directives(parser)?; Ok(Selection::FragmentSpread(Spanning::start_end( &start_pos.clone(), @@ -183,8 +181,8 @@ fn parse_fragment<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Selec ))) } Token::At => { - let directives = try!(parse_directives(parser)); - let selection_set = try!(parse_selection_set(parser)); + let directives = parse_directives(parser)?; + let selection_set = parse_selection_set(parser)?; Ok(Selection::InlineFragment(Spanning::start_end( &start_pos.clone(), @@ -201,17 +199,17 @@ fn parse_fragment<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Selec } fn parse_field<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Field<'a>> { - let mut alias = Some(try!(parser.expect_name())); + let mut alias = Some(parser.expect_name()?); - let name = if try!(parser.skip(&Token::Colon)).is_some() { - try!(parser.expect_name()) + let name = if parser.skip(&Token::Colon)?.is_some() { + parser.expect_name()? } else { alias.take().unwrap() }; - let arguments = try!(parse_arguments(parser)); - let directives = try!(parse_directives(parser)); - let selection_set = try!(parse_optional_selection_set(parser)); + let arguments = parse_arguments(parser)?; + let directives = parse_directives(parser)?; + let selection_set = parse_optional_selection_set(parser)?; Ok(Spanning::start_end( &alias.as_ref().unwrap_or(&name).start.clone(), @@ -237,13 +235,11 @@ fn parse_arguments<'a>(parser: &mut Parser<'a>) -> OptionParseResult<'a, Argumen Ok(None) } else { Ok(Some( - try!(parser.delimited_nonempty_list( - &Token::ParenOpen, - parse_argument, - &Token::ParenClose - )).map(|args| Arguments { - items: args.into_iter().map(|s| s.item).collect(), - }), + parser + .delimited_nonempty_list(&Token::ParenOpen, parse_argument, &Token::ParenClose)? + .map(|args| Arguments { + items: args.into_iter().map(|s| s.item).collect(), + }), )) } } @@ -251,9 +247,9 @@ fn parse_arguments<'a>(parser: &mut Parser<'a>) -> OptionParseResult<'a, Argumen fn parse_argument<'a>( parser: &mut Parser<'a>, ) -> ParseResult<'a, (Spanning<&'a str>, Spanning<InputValue>)> { - let name = try!(parser.expect_name()); - try!(parser.expect(&Token::Colon)); - let value = try!(parse_value_literal(parser, false)); + let name = parser.expect_name()?; + parser.expect(&Token::Colon)?; + let value = parse_value_literal(parser, false)?; Ok(Spanning::start_end( &name.start.clone(), @@ -277,13 +273,15 @@ fn parse_variable_definitions<'a>( Ok(None) } else { Ok(Some( - try!(parser.delimited_nonempty_list( - &Token::ParenOpen, - parse_variable_definition, - &Token::ParenClose - )).map(|defs| VariableDefinitions { - items: defs.into_iter().map(|s| s.item).collect(), - }), + parser + .delimited_nonempty_list( + &Token::ParenOpen, + parse_variable_definition, + &Token::ParenClose, + )? + .map(|defs| VariableDefinitions { + items: defs.into_iter().map(|s| s.item).collect(), + }), )) } } @@ -293,13 +291,13 @@ fn parse_variable_definition<'a>( ) -> ParseResult<'a, (Spanning<&'a str>, VariableDefinition<'a>)> { let Spanning { start: start_pos, .. - } = try!(parser.expect(&Token::Dollar)); - let var_name = try!(parser.expect_name()); - try!(parser.expect(&Token::Colon)); - let var_type = try!(parse_type(parser)); + } = parser.expect(&Token::Dollar)?; + let var_name = parser.expect_name()?; + parser.expect(&Token::Colon)?; + let var_type = parse_type(parser)?; - let default_value = if try!(parser.skip(&Token::Equals)).is_some() { - Some(try!(parse_value_literal(parser, true))) + let default_value = if parser.skip(&Token::Equals)?.is_some() { + Some(parse_value_literal(parser, true)?) } else { None }; @@ -328,7 +326,7 @@ fn parse_directives<'a>( } else { let mut items = Vec::new(); while parser.peek().item == Token::At { - items.push(try!(parse_directive(parser))); + items.push(parse_directive(parser)?); } Ok(Spanning::spanning(items)) @@ -338,9 +336,9 @@ fn parse_directives<'a>( fn parse_directive<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Directive<'a>> { let Spanning { start: start_pos, .. - } = try!(parser.expect(&Token::At)); - let name = try!(parser.expect_name()); - let arguments = try!(parse_arguments(parser)); + } = parser.expect(&Token::At)?; + let name = parser.expect_name()?; + let arguments = parse_arguments(parser)?; Ok(Spanning::start_end( &start_pos, @@ -355,20 +353,20 @@ fn parse_directive<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Directive<'a> pub fn parse_type<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Type<'a>> { let parsed_type = if let Some(Spanning { start: start_pos, .. - }) = try!(parser.skip(&Token::BracketOpen)) + }) = parser.skip(&Token::BracketOpen)? { - let inner_type = try!(parse_type(parser)); - let Spanning { end: end_pos, .. } = try!(parser.expect(&Token::BracketClose)); + let inner_type = parse_type(parser)?; + let Spanning { end: end_pos, .. } = parser.expect(&Token::BracketClose)?; Spanning::start_end(&start_pos, &end_pos, Type::List(Box::new(inner_type.item))) } else { - try!(parser.expect_name()).map(|s| Type::Named(Cow::Borrowed(s))) + parser.expect_name()?.map(|s| Type::Named(Cow::Borrowed(s))) }; Ok(match *parser.peek() { Spanning { item: Token::ExclamationMark, .. - } => try!(wrap_non_null(parser, parsed_type)), + } => wrap_non_null(parser, parsed_type)?, _ => parsed_type, }) } @@ -377,7 +375,7 @@ fn wrap_non_null<'a>( parser: &mut Parser<'a>, inner: Spanning<Type<'a>>, ) -> ParseResult<'a, Type<'a>> { - let Spanning { end: end_pos, .. } = try!(parser.expect(&Token::ExclamationMark)); + let Spanning { end: end_pos, .. } = parser.expect(&Token::ExclamationMark)?; let wrapped = match inner.item { Type::Named(name) => Type::NonNullNamed(name), diff --git a/juniper/src/parser/lexer.rs b/juniper/src/parser/lexer.rs index 88d06532..2c3913a2 100644 --- a/juniper/src/parser/lexer.rs +++ b/juniper/src/parser/lexer.rs @@ -160,10 +160,10 @@ impl<'a> Lexer<'a> { let start_pos = self.position.clone(); for _ in 0..3 { - let (_, ch) = try!(self.next_char().ok_or(Spanning::zero_width( + let (_, ch) = self.next_char().ok_or(Spanning::zero_width( &self.position, - LexerError::UnexpectedEndOfFile - ))); + LexerError::UnexpectedEndOfFile, + ))?; if ch != '.' { return Err(Spanning::zero_width( &start_pos, @@ -181,10 +181,10 @@ impl<'a> Lexer<'a> { fn scan_name(&mut self) -> LexerResult<'a> { let start_pos = self.position.clone(); - let (start_idx, start_ch) = try!(self.next_char().ok_or(Spanning::zero_width( + let (start_idx, start_ch) = self.next_char().ok_or(Spanning::zero_width( &self.position, - LexerError::UnexpectedEndOfFile - ))); + LexerError::UnexpectedEndOfFile, + ))?; assert!(is_name_start(start_ch)); let mut end_idx = start_idx; @@ -207,10 +207,10 @@ impl<'a> Lexer<'a> { fn scan_string(&mut self) -> LexerResult<'a> { let start_pos = self.position.clone(); - let (_, start_ch) = try!(self.next_char().ok_or(Spanning::zero_width( + let (_, start_ch) = self.next_char().ok_or(Spanning::zero_width( &self.position, - LexerError::UnexpectedEndOfFile - ))); + LexerError::UnexpectedEndOfFile, + ))?; assert!(start_ch == '"'); let mut acc = String::new(); @@ -262,7 +262,7 @@ impl<'a> Lexer<'a> { Some((_, 'u')) => { let start_pos = self.position.clone(); self.next_char(); - acc.push(try!(self.scan_escaped_unicode(&start_pos))); + acc.push(self.scan_escaped_unicode(&start_pos)?); } Some((_, ch)) => { let mut s = String::from("\\"); @@ -314,18 +314,18 @@ impl<'a> Lexer<'a> { &mut self, start_pos: &SourcePosition, ) -> Result<char, Spanning<LexerError>> { - let (start_idx, _) = try!(self.peek_char().ok_or(Spanning::zero_width( + let (start_idx, _) = self.peek_char().ok_or(Spanning::zero_width( &self.position, - LexerError::UnterminatedString - ))); + LexerError::UnterminatedString, + ))?; let mut end_idx = start_idx; let mut len = 0; for _ in 0..4 { - let (idx, ch) = try!(self.next_char().ok_or(Spanning::zero_width( + let (idx, ch) = self.next_char().ok_or(Spanning::zero_width( &self.position, - LexerError::UnterminatedString - ))); + LexerError::UnterminatedString, + ))?; if !ch.is_alphanumeric() { break; @@ -344,12 +344,12 @@ impl<'a> Lexer<'a> { )); } - let code_point = try!( - u32::from_str_radix(escape, 16).map_err(|_| Spanning::zero_width( + let code_point = u32::from_str_radix(escape, 16).map_err(|_| { + Spanning::zero_width( start_pos, LexerError::UnknownEscapeSequence("\\u".to_owned() + escape), - )) - ); + ) + })?; char::from_u32(code_point).ok_or_else(|| { Spanning::zero_width( @@ -361,14 +361,14 @@ impl<'a> Lexer<'a> { fn scan_number(&mut self) -> LexerResult<'a> { let start_pos = self.position.clone(); - let int_part = try!(self.scan_integer_part()); + let int_part = self.scan_integer_part()?; let mut frac_part = None; let mut exp_part = None; if let Some((_, '.')) = self.peek_char() { self.next_char(); - frac_part = Some(try!(self.scan_digits())); + frac_part = Some(self.scan_digits()?); } if let Some((_, ch)) = self.peek_char() { @@ -385,7 +385,7 @@ impl<'a> Lexer<'a> { self.next_char(); } } - exp_part = Some(if is_negative { -1 } else { 1 } * try!(self.scan_digits())); + exp_part = Some(if is_negative { -1 } else { 1 } * self.scan_digits()?); } } @@ -416,10 +416,10 @@ impl<'a> Lexer<'a> { fn scan_integer_part(&mut self) -> Result<i32, Spanning<LexerError>> { let is_negative = { - let (_, init_ch) = try!(self.peek_char().ok_or(Spanning::zero_width( + let (_, init_ch) = self.peek_char().ok_or(Spanning::zero_width( &self.position, - LexerError::UnexpectedEndOfFile - ))); + LexerError::UnexpectedEndOfFile, + ))?; if init_ch == '-' { self.next_char(); @@ -429,10 +429,10 @@ impl<'a> Lexer<'a> { } }; - let (_, ch) = try!(self.peek_char().ok_or(Spanning::zero_width( + let (_, ch) = self.peek_char().ok_or(Spanning::zero_width( &self.position, - LexerError::UnexpectedEndOfFile - ))); + LexerError::UnexpectedEndOfFile, + ))?; if ch == '0' { self.next_char(); @@ -445,16 +445,16 @@ impl<'a> Lexer<'a> { _ => Ok(0), } } else { - Ok(try!(self.scan_digits()) * if is_negative { -1 } else { 1 }) + Ok(self.scan_digits()? * if is_negative { -1 } else { 1 }) } } fn scan_digits(&mut self) -> Result<i32, Spanning<LexerError>> { let start_pos = self.position.clone(); - let (start_idx, ch) = try!(self.peek_char().ok_or(Spanning::zero_width( + let (start_idx, ch) = self.peek_char().ok_or(Spanning::zero_width( &self.position, - LexerError::UnexpectedEndOfFile - ))); + LexerError::UnexpectedEndOfFile, + ))?; let mut end_idx = start_idx; if !ch.is_digit(10) { diff --git a/juniper/src/parser/parser.rs b/juniper/src/parser/parser.rs index c700e2ca..e85b5e3a 100644 --- a/juniper/src/parser/parser.rs +++ b/juniper/src/parser/parser.rs @@ -103,15 +103,15 @@ impl<'a> Parser<'a> { { let Spanning { start: start_pos, .. - } = try!(self.expect(opening)); + } = self.expect(opening)?; let mut items = Vec::new(); loop { - if let Some(Spanning { end: end_pos, .. }) = try!(self.skip(closing)) { + if let Some(Spanning { end: end_pos, .. }) = self.skip(closing)? { return Ok(Spanning::start_end(&start_pos, &end_pos, items)); } - items.push(try!(parser(self))); + items.push(parser(self)?); } } @@ -128,13 +128,13 @@ impl<'a> Parser<'a> { { let Spanning { start: start_pos, .. - } = try!(self.expect(opening)); + } = self.expect(opening)?; let mut items = Vec::new(); loop { - items.push(try!(parser(self))); + items.push(parser(self)?); - if let Some(Spanning { end: end_pos, .. }) = try!(self.skip(closing)) { + if let Some(Spanning { end: end_pos, .. }) = self.skip(closing)? { return Ok(Spanning::start_end(&start_pos, &end_pos, items)); } } @@ -153,13 +153,13 @@ impl<'a> Parser<'a> { { let Spanning { start: start_pos, .. - } = try!(self.expect(opening)); + } = self.expect(opening)?; let mut items = Vec::new(); loop { - items.push(try!(parser(self))); + items.push(parser(self)?); - if let Some(Spanning { end: end_pos, .. }) = try!(self.skip(closing)) { + if let Some(Spanning { end: end_pos, .. }) = self.skip(closing)? { return Ok(Spanning::start_end(&start_pos, &end_pos, items)); } } diff --git a/juniper/src/parser/value.rs b/juniper/src/parser/value.rs index 3bd5678b..016df991 100644 --- a/juniper/src/parser/value.rs +++ b/juniper/src/parser/value.rs @@ -63,33 +63,37 @@ pub fn parse_value_literal<'a>( } fn parse_list_literal<'a>(parser: &mut Parser<'a>, is_const: bool) -> ParseResult<'a, InputValue> { - Ok(try!(parser.delimited_list( - &Token::BracketOpen, - |p| parse_value_literal(p, is_const), - &Token::BracketClose - )).map(InputValue::parsed_list)) + Ok(parser + .delimited_list( + &Token::BracketOpen, + |p| parse_value_literal(p, is_const), + &Token::BracketClose, + )? + .map(InputValue::parsed_list)) } fn parse_object_literal<'a>( parser: &mut Parser<'a>, is_const: bool, ) -> ParseResult<'a, InputValue> { - Ok(try!(parser.delimited_list( - &Token::CurlyOpen, - |p| parse_object_field(p, is_const), - &Token::CurlyClose - )).map(|items| InputValue::parsed_object(items.into_iter().map(|s| s.item).collect()))) + Ok(parser + .delimited_list( + &Token::CurlyOpen, + |p| parse_object_field(p, is_const), + &Token::CurlyClose, + )? + .map(|items| InputValue::parsed_object(items.into_iter().map(|s| s.item).collect()))) } fn parse_object_field<'a>( parser: &mut Parser<'a>, is_const: bool, ) -> ParseResult<'a, (Spanning<String>, Spanning<InputValue>)> { - let key = try!(parser.expect_name()); + let key = parser.expect_name()?; - try!(parser.expect(&Token::Colon)); + parser.expect(&Token::Colon)?; - let value = try!(parse_value_literal(parser, is_const)); + let value = parse_value_literal(parser, is_const)?; Ok(Spanning::start_end( &key.start.clone(), @@ -101,12 +105,12 @@ fn parse_object_field<'a>( fn parse_variable_literal<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, InputValue> { let Spanning { start: start_pos, .. - } = try!(parser.expect(&Token::Dollar)); + } = parser.expect(&Token::Dollar)?; let Spanning { item: name, end: end_pos, .. - } = try!(parser.expect_name()); + } = parser.expect_name()?; Ok(Spanning::start_end( &start_pos, diff --git a/juniper/src/schema/meta.rs b/juniper/src/schema/meta.rs index 9e8a6790..c0407ddc 100644 --- a/juniper/src/schema/meta.rs +++ b/juniper/src/schema/meta.rs @@ -8,62 +8,85 @@ use types::base::TypeKind; /// Scalar type metadata pub struct ScalarMeta<'a> { - #[doc(hidden)] pub name: Cow<'a, str>, - #[doc(hidden)] pub description: Option<String>, - #[doc(hidden)] pub try_parse_fn: Box<Fn(&InputValue) -> bool + Send + Sync>, + #[doc(hidden)] + pub name: Cow<'a, str>, + #[doc(hidden)] + pub description: Option<String>, + #[doc(hidden)] + pub try_parse_fn: Box<Fn(&InputValue) -> bool + Send + Sync>, } /// List type metadata #[derive(Debug)] pub struct ListMeta<'a> { - #[doc(hidden)] pub of_type: Type<'a>, + #[doc(hidden)] + pub of_type: Type<'a>, } /// Nullable type metadata #[derive(Debug)] pub struct NullableMeta<'a> { - #[doc(hidden)] pub of_type: Type<'a>, + #[doc(hidden)] + pub of_type: Type<'a>, } /// Object type metadata #[derive(Debug)] pub struct ObjectMeta<'a> { - #[doc(hidden)] pub name: Cow<'a, str>, - #[doc(hidden)] pub description: Option<String>, - #[doc(hidden)] pub fields: Vec<Field<'a>>, - #[doc(hidden)] pub interface_names: Vec<String>, + #[doc(hidden)] + pub name: Cow<'a, str>, + #[doc(hidden)] + pub description: Option<String>, + #[doc(hidden)] + pub fields: Vec<Field<'a>>, + #[doc(hidden)] + pub interface_names: Vec<String>, } /// Enum type metadata pub struct EnumMeta<'a> { - #[doc(hidden)] pub name: Cow<'a, str>, - #[doc(hidden)] pub description: Option<String>, - #[doc(hidden)] pub values: Vec<EnumValue>, - #[doc(hidden)] pub try_parse_fn: Box<Fn(&InputValue) -> bool + Send + Sync>, + #[doc(hidden)] + pub name: Cow<'a, str>, + #[doc(hidden)] + pub description: Option<String>, + #[doc(hidden)] + pub values: Vec<EnumValue>, + #[doc(hidden)] + pub try_parse_fn: Box<Fn(&InputValue) -> bool + Send + Sync>, } /// Interface type metadata #[derive(Debug)] pub struct InterfaceMeta<'a> { - #[doc(hidden)] pub name: Cow<'a, str>, - #[doc(hidden)] pub description: Option<String>, - #[doc(hidden)] pub fields: Vec<Field<'a>>, + #[doc(hidden)] + pub name: Cow<'a, str>, + #[doc(hidden)] + pub description: Option<String>, + #[doc(hidden)] + pub fields: Vec<Field<'a>>, } /// Union type metadata #[derive(Debug)] pub struct UnionMeta<'a> { - #[doc(hidden)] pub name: Cow<'a, str>, - #[doc(hidden)] pub description: Option<String>, - #[doc(hidden)] pub of_type_names: Vec<String>, + #[doc(hidden)] + pub name: Cow<'a, str>, + #[doc(hidden)] + pub description: Option<String>, + #[doc(hidden)] + pub of_type_names: Vec<String>, } /// Input object metadata pub struct InputObjectMeta<'a> { - #[doc(hidden)] pub name: Cow<'a, str>, - #[doc(hidden)] pub description: Option<String>, - #[doc(hidden)] pub input_fields: Vec<Argument<'a>>, - #[doc(hidden)] pub try_parse_fn: Box<Fn(&InputValue) -> bool + Send + Sync>, + #[doc(hidden)] + pub name: Cow<'a, str>, + #[doc(hidden)] + pub description: Option<String>, + #[doc(hidden)] + pub input_fields: Vec<Argument<'a>>, + #[doc(hidden)] + pub try_parse_fn: Box<Fn(&InputValue) -> bool + Send + Sync>, } /// A placeholder for not-yet-registered types @@ -72,7 +95,8 @@ pub struct InputObjectMeta<'a> { /// is inserted into a registry to indicate existence. #[derive(Debug)] pub struct PlaceholderMeta<'a> { - #[doc(hidden)] pub of_type: Type<'a>, + #[doc(hidden)] + pub of_type: Type<'a>, } /// Generic type metadata @@ -92,20 +116,29 @@ pub enum MetaType<'a> { /// Metadata for a field #[derive(Debug, Clone)] pub struct Field<'a> { - #[doc(hidden)] pub name: String, - #[doc(hidden)] pub description: Option<String>, - #[doc(hidden)] pub arguments: Option<Vec<Argument<'a>>>, - #[doc(hidden)] pub field_type: Type<'a>, - #[doc(hidden)] pub deprecation_reason: Option<String>, + #[doc(hidden)] + pub name: String, + #[doc(hidden)] + pub description: Option<String>, + #[doc(hidden)] + pub arguments: Option<Vec<Argument<'a>>>, + #[doc(hidden)] + pub field_type: Type<'a>, + #[doc(hidden)] + pub deprecation_reason: Option<String>, } /// Metadata for an argument to a field #[derive(Debug, Clone)] pub struct Argument<'a> { - #[doc(hidden)] pub name: String, - #[doc(hidden)] pub description: Option<String>, - #[doc(hidden)] pub arg_type: Type<'a>, - #[doc(hidden)] pub default_value: Option<InputValue>, + #[doc(hidden)] + pub name: String, + #[doc(hidden)] + pub description: Option<String>, + #[doc(hidden)] + pub arg_type: Type<'a>, + #[doc(hidden)] + pub default_value: Option<InputValue>, } /// Metadata for a single value in an enum diff --git a/juniper/src/schema/model.rs b/juniper/src/schema/model.rs index 20aa1d95..7fb57734 100644 --- a/juniper/src/schema/model.rs +++ b/juniper/src/schema/model.rs @@ -13,11 +13,16 @@ use schema::meta::{Argument, InterfaceMeta, MetaType, ObjectMeta, PlaceholderMet /// This brings the mutation and query types together, and provides the /// predefined metadata fields. pub struct RootNode<'a, QueryT: GraphQLType, MutationT: GraphQLType> { - #[doc(hidden)] pub query_type: QueryT, - #[doc(hidden)] pub query_info: QueryT::TypeInfo, - #[doc(hidden)] pub mutation_type: MutationT, - #[doc(hidden)] pub mutation_info: MutationT::TypeInfo, - #[doc(hidden)] pub schema: SchemaType<'a>, + #[doc(hidden)] + pub query_type: QueryT, + #[doc(hidden)] + pub query_info: QueryT::TypeInfo, + #[doc(hidden)] + pub mutation_type: MutationT, + #[doc(hidden)] + pub mutation_info: MutationT::TypeInfo, + #[doc(hidden)] + pub schema: SchemaType<'a>, } /// Metadata for a schema diff --git a/juniper/src/types/name.rs b/juniper/src/types/name.rs index 9208c6d2..f146814f 100644 --- a/juniper/src/types/name.rs +++ b/juniper/src/types/name.rs @@ -30,7 +30,7 @@ impl Name { } } } - return input.len() > 0; + return !input.is_empty(); } } From 875c80748d134815db1007608ac4ff96641cd9d1 Mon Sep 17 00:00:00 2001 From: Atul Bhosale <atul1bhosale@gmail.com> Date: Sat, 27 Jan 2018 17:15:28 +0530 Subject: [PATCH 04/18] Fix cargo clippy warnings --- juniper/src/executor/mod.rs | 6 +++--- juniper/src/integrations/serde.rs | 12 ++++++------ juniper/src/macros/scalar.rs | 2 +- juniper/src/parser/lexer.rs | 12 +++++++----- juniper/src/schema/meta.rs | 2 +- juniper/src/types/base.rs | 2 +- juniper/src/types/scalars.rs | 2 +- juniper_iron/examples/iron_server.rs | 2 +- juniper_iron/src/lib.rs | 12 ++++++------ 9 files changed, 27 insertions(+), 25 deletions(-) diff --git a/juniper/src/executor/mod.rs b/juniper/src/executor/mod.rs index 85d45913..c1c84e08 100644 --- a/juniper/src/executor/mod.rs +++ b/juniper/src/executor/mod.rs @@ -230,20 +230,20 @@ impl<'a, T: GraphQLType, C> IntoResolvable<'a, Option<T>, C> /// Conversion trait for context types /// /// Used to support different context types for different parts of an -/// application. By making each GraphQL type only aware of as much +/// application. By making each `GraphQL` type only aware of as much /// context as it needs to, isolation and robustness can be /// improved. Implement this trait if you have contexts that can /// generally be converted between each other. /// /// The empty tuple `()` can be converted into from any context type, -/// making it suitable for GraphQL that don't need _any_ context to +/// making it suitable for `GraphQL` that don't need _any_ context to /// work, e.g. scalars or enums. pub trait FromContext<T> { /// Perform the conversion fn from(value: &T) -> &Self; } -/// Marker trait for types that can act as context objects for GraphQL types. +/// Marker trait for types that can act as context objects for `GraphQL` types. pub trait Context {} impl<'a, C: Context> Context for &'a C {} diff --git a/juniper/src/integrations/serde.rs b/juniper/src/integrations/serde.rs index 55d85d8c..da573cbb 100644 --- a/juniper/src/integrations/serde.rs +++ b/juniper/src/integrations/serde.rs @@ -76,8 +76,8 @@ impl<'de> de::Deserialize<'de> for InputValue { where E: de::Error, { - if value >= i32::min_value() as i64 && value <= i32::max_value() as i64 { - Ok(InputValue::int(value as i32)) + if value >= i64::from(i32::min_value()) && value <= i64::from(i32::max_value()) { + Ok(InputValue::int(i32::from(value))) } else { Err(E::custom(format!("integer out of range"))) } @@ -87,8 +87,8 @@ impl<'de> de::Deserialize<'de> for InputValue { where E: de::Error, { - if value <= i32::max_value() as u64 { - self.visit_i64(value as i64) + if value <= u64::from(i32::max_value()) { + self.visit_i64(i64::from(value)) } else { Err(E::custom(format!("integer out of range"))) } @@ -155,7 +155,7 @@ impl ser::Serialize for InputValue { { match *self { InputValue::Null | InputValue::Variable(_) => serializer.serialize_unit(), - InputValue::Int(v) => serializer.serialize_i64(v as i64), + InputValue::Int(v) => serializer.serialize_i64(i64::from(v)), InputValue::Float(v) => serializer.serialize_f64(v), InputValue::String(ref v) | InputValue::Enum(ref v) => serializer.serialize_str(v), InputValue::Boolean(v) => serializer.serialize_bool(v), @@ -238,7 +238,7 @@ impl ser::Serialize for Value { { match *self { Value::Null => serializer.serialize_unit(), - Value::Int(v) => serializer.serialize_i64(v as i64), + Value::Int(v) => serializer.serialize_i64(i64::from(v)), Value::Float(v) => serializer.serialize_f64(v), Value::String(ref v) => serializer.serialize_str(v), Value::Boolean(v) => serializer.serialize_bool(v), diff --git a/juniper/src/macros/scalar.rs b/juniper/src/macros/scalar.rs index 3bf8d084..9d055c87 100644 --- a/juniper/src/macros/scalar.rs +++ b/juniper/src/macros/scalar.rs @@ -151,6 +151,6 @@ macro_rules! graphql_scalar { // Entry point // RustName { ... } ( $name:ty { $( $items:tt )* }) => { - graphql_scalar!( @parse, ( $name, (stringify!($name)), None ), ( None, None ), $($items)* ); + graphql_scalar!( @parse, ( $name, stringify!($name), None ), ( None, None ), $($items)* ); }; } diff --git a/juniper/src/parser/lexer.rs b/juniper/src/parser/lexer.rs index 2c3913a2..2526d1c0 100644 --- a/juniper/src/parser/lexer.rs +++ b/juniper/src/parser/lexer.rs @@ -390,7 +390,7 @@ impl<'a> Lexer<'a> { } let mantissa = frac_part - .map(|f| f as f64) + .map(|f| f64::from(f)) .map(|frac| { if frac > 0f64 { frac / 10f64.powf(frac.log10().floor() + 1f64) @@ -400,16 +400,18 @@ impl<'a> Lexer<'a> { }) .map(|m| if int_part < 0 { -m } else { m }); - let exp = exp_part.map(|e| e as f64).map(|e| 10f64.powf(e)); + let exp = exp_part.map(|e| f64::from(e)).map(|e| 10f64.powf(e)); Ok(Spanning::start_end( &start_pos, &self.position, match (mantissa, exp) { (None, None) => Token::Int(int_part), - (None, Some(exp)) => Token::Float((int_part as f64) * exp), - (Some(mantissa), None) => Token::Float((int_part as f64) + mantissa), - (Some(mantissa), Some(exp)) => Token::Float(((int_part as f64) + mantissa) * exp), + (None, Some(exp)) => Token::Float((f64::from(int_part)) * exp), + (Some(mantissa), None) => Token::Float((f64::from(int_part)) + mantissa), + (Some(mantissa), Some(exp)) => { + Token::Float(((f64::from(int_part)) + mantissa) * exp) + } }, )) } diff --git a/juniper/src/schema/meta.rs b/juniper/src/schema/meta.rs index c0407ddc..cdfb4f29 100644 --- a/juniper/src/schema/meta.rs +++ b/juniper/src/schema/meta.rs @@ -1,4 +1,4 @@ -//! Types used to describe a GraphQL schema +//! Types used to describe a `GraphQL` schema use std::borrow::Cow; use std::fmt; diff --git a/juniper/src/types/base.rs b/juniper/src/types/base.rs index 7af96420..79dae2e2 100644 --- a/juniper/src/types/base.rs +++ b/juniper/src/types/base.rs @@ -374,7 +374,7 @@ where let sub_exec = executor.field_sub_executor( response_name, - &f.name.item, + f.name.item, start_pos.clone(), f.selection_set.as_ref().map(|v| &v[..]), ); diff --git a/juniper/src/types/scalars.rs b/juniper/src/types/scalars.rs index 9ebbbf61..31042b5a 100644 --- a/juniper/src/types/scalars.rs +++ b/juniper/src/types/scalars.rs @@ -113,7 +113,7 @@ graphql_scalar!(f64 as "Float" { from_input_value(v: &InputValue) -> Option<f64> { match *v { - InputValue::Int(i) => Some(i as f64), + InputValue::Int(i) => Some(f64::from(i)), InputValue::Float(f) => Some(f), _ => None, } diff --git a/juniper_iron/examples/iron_server.rs b/juniper_iron/examples/iron_server.rs index 31a3324c..6ef250fa 100644 --- a/juniper_iron/examples/iron_server.rs +++ b/juniper_iron/examples/iron_server.rs @@ -37,7 +37,7 @@ fn main() { chain.link_before(logger_before); chain.link_after(logger_after); - let host = env::var("LISTEN").unwrap_or("0.0.0.0:8080".to_owned()); + let host = env::var("LISTEN").unwrap_or_else(|_| "0.0.0.0:8080".to_owned()); println!("GraphQL server started on {}", host); Iron::new(chain).http(host.as_str()).unwrap(); } diff --git a/juniper_iron/src/lib.rs b/juniper_iron/src/lib.rs index d7a7d249..58395e2e 100644 --- a/juniper_iron/src/lib.rs +++ b/juniper_iron/src/lib.rs @@ -125,7 +125,7 @@ use serde_json::error::Error as SerdeError; use juniper::{GraphQLType, InputValue, RootNode}; use juniper::http; -/// Handler that executes GraphQL queries in the given schema +/// Handler that executes `GraphQL` queries in the given schema /// /// The handler responds to GET requests and POST requests only. In GET /// requests, the query should be supplied in the `query` URL parameter, e.g. @@ -146,7 +146,7 @@ where root_node: RootNode<'a, Query, Mutation>, } -/// Handler that renders GraphiQL - a graphical query editor interface +/// Handler that renders `GraphiQL` - a graphical query editor interface pub struct GraphiQLHandler { graphql_url: String, } @@ -201,7 +201,7 @@ where fn handle_get(&self, req: &mut Request) -> IronResult<http::GraphQLRequest> { let url_query_string = req.get_mut::<UrlEncodedQuery>() - .map_err(|e| GraphQLIronError::Url(e))?; + .map_err(GraphQLIronError::Url)?; let input_query = parse_url_param(url_query_string.remove("query"))? .ok_or_else(|| GraphQLIronError::InvalidData("No query provided"))?; @@ -221,7 +221,7 @@ where Ok( serde_json::from_str::<http::GraphQLRequest>(request_payload.as_str()) - .map_err(|err| GraphQLIronError::Serde(err))?, + .map_err(GraphQLIronError::Serde)?, ) } @@ -296,7 +296,7 @@ impl fmt::Display for GraphQLIronError { match *self { GraphQLIronError::Serde(ref err) => fmt::Display::fmt(err, &mut f), GraphQLIronError::Url(ref err) => fmt::Display::fmt(err, &mut f), - GraphQLIronError::InvalidData(ref err) => fmt::Display::fmt(err, &mut f), + GraphQLIronError::InvalidData(err) => fmt::Display::fmt(err, &mut f), } } } @@ -306,7 +306,7 @@ impl Error for GraphQLIronError { match *self { GraphQLIronError::Serde(ref err) => err.description(), GraphQLIronError::Url(ref err) => err.description(), - GraphQLIronError::InvalidData(ref err) => err, + GraphQLIronError::InvalidData(err) => err, } } From 73a4efe984ef52207490d4f18c28eeb055d496c4 Mon Sep 17 00:00:00 2001 From: Marcus Griep <marcus@griep.us> Date: Wed, 21 Feb 2018 10:41:38 -0500 Subject: [PATCH 05/18] Change $outname from :tt to :expr It doesn't appear that `:tt` accepts the `stringify!()`-ed value in this position. The :tt is only later used as an `:expr` to produce the name for metadata purposes. Converting this position to be an `:expr` allows the `stringify!()`-ed value and accepts all current uses of the `graphql_scalar!()` macro in this repository. --- juniper/src/macros/scalar.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/juniper/src/macros/scalar.rs b/juniper/src/macros/scalar.rs index 9d055c87..98082b6c 100644 --- a/juniper/src/macros/scalar.rs +++ b/juniper/src/macros/scalar.rs @@ -57,7 +57,7 @@ macro_rules! graphql_scalar { // and body for the from() method on FromInputValue. ( @generate, - ( $name:ty, $outname:tt, $descr:tt ), + ( $name:ty, $outname:expr, $descr:tt ), ( ( $resolve_selfvar:ident, $resolve_body:block ), ( $fiv_arg:ident, $fiv_result:ty, $fiv_body:block ) @@ -135,7 +135,7 @@ macro_rules! graphql_scalar { // description: <description> ( @parse, - ( $name:ty, $outname:tt, $_ignored:tt ), + ( $name:ty, $outname:expr, $_ignored:tt ), $acc:tt, description: $descr:tt $($rest:tt)* ) => { From d1cddfb55f7926cd68343211dffc2fba68d76413 Mon Sep 17 00:00:00 2001 From: Marcus Griep <marcus@griep.us> Date: Wed, 21 Feb 2018 10:45:30 -0500 Subject: [PATCH 06/18] Revert lossy conversions to use `as` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The conversions in this changeset cannot use the `From<T>` trait implementation because the conversion is lossy, either because they involve converting a signed value to an unsigned value (`i32`⇒`u64`) or because the convert from a larger data type to a smaller one (`u64`⇒`i32`). In this case, the `as` type cast is necessary to perform a bitwise conversion. This coercion can cause negative values to become very large unsigned values. This is intentional on line 90. --- juniper/src/integrations/serde.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/juniper/src/integrations/serde.rs b/juniper/src/integrations/serde.rs index da573cbb..9d973ee1 100644 --- a/juniper/src/integrations/serde.rs +++ b/juniper/src/integrations/serde.rs @@ -77,7 +77,7 @@ impl<'de> de::Deserialize<'de> for InputValue { E: de::Error, { if value >= i64::from(i32::min_value()) && value <= i64::from(i32::max_value()) { - Ok(InputValue::int(i32::from(value))) + Ok(InputValue::int(value as i32)) } else { Err(E::custom(format!("integer out of range"))) } @@ -87,8 +87,8 @@ impl<'de> de::Deserialize<'de> for InputValue { where E: de::Error, { - if value <= u64::from(i32::max_value()) { - self.visit_i64(i64::from(value)) + if value <= i32::max_value() as u64 { + self.visit_i64(value as i64) } else { Err(E::custom(format!("integer out of range"))) } From b94ed37c1f255f7968bc4dc1dde5296eaeb0d952 Mon Sep 17 00:00:00 2001 From: Marcus Griep <marcus@griep.us> Date: Wed, 21 Feb 2018 11:26:59 -0500 Subject: [PATCH 07/18] Remove unnecessary `format!()` The `E::custom()` function requires a value of any type that implements `fmt::Display`, so a plain `&str` works just fine here. --- juniper/src/integrations/serde.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/juniper/src/integrations/serde.rs b/juniper/src/integrations/serde.rs index 9d973ee1..b1b7bdc0 100644 --- a/juniper/src/integrations/serde.rs +++ b/juniper/src/integrations/serde.rs @@ -79,7 +79,7 @@ impl<'de> de::Deserialize<'de> for InputValue { if value >= i64::from(i32::min_value()) && value <= i64::from(i32::max_value()) { Ok(InputValue::int(value as i32)) } else { - Err(E::custom(format!("integer out of range"))) + Err(E::custom("integer out of range")) } } @@ -90,7 +90,7 @@ impl<'de> de::Deserialize<'de> for InputValue { if value <= i32::max_value() as u64 { self.visit_i64(value as i64) } else { - Err(E::custom(format!("integer out of range"))) + Err(E::custom("integer out of range")) } } From 9313c7ca6dfecd287a2fd84117339a493041e25e Mon Sep 17 00:00:00 2001 From: Christoph Herzog <chris@theduke.at> Date: Thu, 3 May 2018 07:37:10 +0200 Subject: [PATCH 08/18] Run `rust fmt`. --- juniper/benches/bench.rs | 2 +- juniper/src/ast.rs | 4 +- juniper/src/executor/mod.rs | 8 +- juniper/src/executor_tests/directives.rs | 2 +- juniper/src/executor_tests/enums.rs | 34 +- juniper/src/executor_tests/executor.rs | 214 +++---- .../src/executor_tests/interfaces_unions.rs | 88 ++- .../src/executor_tests/introspection/enums.rs | 38 +- .../introspection/input_object.rs | 175 +++-- .../src/executor_tests/introspection/mod.rs | 26 +- juniper/src/executor_tests/mod.rs | 6 +- juniper/src/executor_tests/variables.rs | 426 ++++++------- juniper/src/http/mod.rs | 4 +- juniper/src/integrations/chrono.rs | 2 +- juniper/src/integrations/serde.rs | 4 +- juniper/src/lib.rs | 22 +- juniper/src/macros/tests/args.rs | 48 +- juniper/src/macros/tests/field.rs | 4 +- juniper/src/macros/tests/interface.rs | 20 +- juniper/src/macros/tests/mod.rs | 4 +- juniper/src/macros/tests/object.rs | 84 ++- juniper/src/macros/tests/scalar.rs | 2 +- juniper/src/macros/tests/union.rs | 16 +- juniper/src/parser/document.rs | 2 +- juniper/src/parser/lexer.rs | 4 +- juniper/src/parser/mod.rs | 6 +- juniper/src/parser/parser.rs | 2 +- juniper/src/parser/tests/document.rs | 148 +++-- juniper/src/parser/tests/lexer.rs | 7 +- juniper/src/parser/tests/value.rs | 26 +- juniper/src/schema/meta.rs | 27 +- juniper/src/schema/mod.rs | 2 +- juniper/src/schema/model.rs | 15 +- juniper/src/schema/schema.rs | 2 +- juniper/src/tests/introspection_tests.rs | 108 ++-- juniper/src/tests/mod.rs | 8 +- juniper/src/tests/model.rs | 3 +- juniper/src/tests/query_tests.rs | 558 ++++++++-------- juniper/src/tests/schema.rs | 2 +- juniper/src/tests/type_info_tests.rs | 2 +- juniper/src/types/base.rs | 47 +- juniper/src/types/containers.rs | 2 +- juniper/src/types/mod.rs | 6 +- juniper/src/types/pointers.rs | 2 +- juniper/src/types/utilities.rs | 4 +- juniper/src/validation/input_value.rs | 6 +- juniper/src/validation/mod.rs | 14 +- .../rules/arguments_of_correct_type.rs | 312 ++++----- .../rules/default_values_of_correct_type.rs | 22 +- .../rules/fields_on_correct_type.rs | 92 ++- .../rules/fragments_on_composite_types.rs | 40 +- .../validation/rules/known_argument_names.rs | 22 +- .../src/validation/rules/known_directives.rs | 16 +- .../validation/rules/known_fragment_names.rs | 2 +- .../src/validation/rules/known_type_names.rs | 2 +- .../rules/lone_anonymous_operation.rs | 9 +- .../validation/rules/no_fragment_cycles.rs | 44 +- .../rules/no_undefined_variables.rs | 68 +- .../validation/rules/no_unused_fragments.rs | 9 +- .../validation/rules/no_unused_variables.rs | 31 +- .../rules/overlapping_fields_can_be_merged.rs | 598 ++++++++---------- .../rules/possible_fragment_spreads.rs | 114 ++-- .../rules/provided_non_null_arguments.rs | 22 +- juniper/src/validation/rules/scalar_leafs.rs | 72 +-- .../validation/rules/unique_argument_names.rs | 34 +- .../validation/rules/unique_fragment_names.rs | 32 +- .../rules/unique_input_field_names.rs | 18 +- .../rules/unique_operation_names.rs | 32 +- .../rules/variables_in_allowed_position.rs | 112 ++-- juniper/src/validation/test_harness.rs | 32 +- juniper/src/validation/visitor.rs | 2 +- juniper/src/value.rs | 4 +- 72 files changed, 1781 insertions(+), 2196 deletions(-) diff --git a/juniper/benches/bench.rs b/juniper/benches/bench.rs index ed18a460..0e79f032 100644 --- a/juniper/benches/bench.rs +++ b/juniper/benches/bench.rs @@ -4,8 +4,8 @@ extern crate juniper; use bencher::Bencher; -use juniper::{execute, EmptyMutation, RootNode, Variables}; use juniper::tests::model::Database; +use juniper::{execute, EmptyMutation, RootNode, Variables}; fn query_type_name(b: &mut Bencher) { let database = Database::new(); diff --git a/juniper/src/ast.rs b/juniper/src/ast.rs index 45547ff4..8d10d3b2 100644 --- a/juniper/src/ast.rs +++ b/juniper/src/ast.rs @@ -1,8 +1,8 @@ -use std::fmt; use std::borrow::Cow; +use std::fmt; use std::hash::Hash; -use std::vec; use std::slice; +use std::vec; use indexmap::IndexMap; diff --git a/juniper/src/executor/mod.rs b/juniper/src/executor/mod.rs index c1c84e08..414cf5f1 100644 --- a/juniper/src/executor/mod.rs +++ b/juniper/src/executor/mod.rs @@ -1,16 +1,16 @@ -use std::cmp::Ordering; -use std::fmt::Display; use std::borrow::Cow; +use std::cmp::Ordering; use std::collections::HashMap; +use std::fmt::Display; use std::sync::RwLock; use fnv::FnvHashMap; -use GraphQLError; use ast::{Definition, Document, Fragment, FromInputValue, InputValue, OperationType, Selection, ToInputValue, Type}; -use value::Value; use parser::SourcePosition; +use value::Value; +use GraphQLError; use schema::meta::{Argument, EnumMeta, EnumValue, Field, InputObjectMeta, InterfaceMeta, ListMeta, MetaType, NullableMeta, ObjectMeta, PlaceholderMeta, ScalarMeta, UnionMeta}; diff --git a/juniper/src/executor_tests/directives.rs b/juniper/src/executor_tests/directives.rs index 197429ab..50102036 100644 --- a/juniper/src/executor_tests/directives.rs +++ b/juniper/src/executor_tests/directives.rs @@ -1,9 +1,9 @@ use indexmap::IndexMap; -use value::Value; use executor::Variables; use schema::model::RootNode; use types::scalars::EmptyMutation; +use value::Value; struct TestType; diff --git a/juniper/src/executor_tests/enums.rs b/juniper/src/executor_tests/enums.rs index daa3a4ca..4793ab84 100644 --- a/juniper/src/executor_tests/enums.rs +++ b/juniper/src/executor_tests/enums.rs @@ -1,13 +1,13 @@ use indexmap::IndexMap; -use value::Value; use ast::InputValue; use executor::Variables; -use schema::model::RootNode; -use GraphQLError::ValidationError; -use validation::RuleError; use parser::SourcePosition; +use schema::model::RootNode; use types::scalars::EmptyMutation; +use validation::RuleError; +use value::Value; +use GraphQLError::ValidationError; #[derive(GraphQLEnum, Debug)] #[graphql(_internal)] @@ -77,12 +77,10 @@ fn does_not_accept_string_literals() { assert_eq!( error, - ValidationError(vec![ - RuleError::new( - r#"Invalid value for argument "color", expected type "Color!""#, - &[SourcePosition::new(18, 0, 18)], - ), - ]) + ValidationError(vec![RuleError::new( + r#"Invalid value for argument "color", expected type "Color!""#, + &[SourcePosition::new(18, 0, 18)], + )]) ); } @@ -112,12 +110,10 @@ fn does_not_accept_incorrect_enum_name_in_variables() { assert_eq!( error, - ValidationError(vec![ - RuleError::new( - r#"Variable "$color" got invalid value. Invalid value for enum "Color"."#, - &[SourcePosition::new(8, 0, 8)], - ), - ]) + ValidationError(vec![RuleError::new( + r#"Variable "$color" got invalid value. Invalid value for enum "Color"."#, + &[SourcePosition::new(8, 0, 8)], + )]) ); } @@ -134,11 +130,9 @@ fn does_not_accept_incorrect_type_in_variables() { assert_eq!( error, - ValidationError(vec![ - RuleError::new( + ValidationError(vec![RuleError::new( r#"Variable "$color" got invalid value. Expected "Color", found not a string or enum."#, &[SourcePosition::new(8, 0, 8)], - ), - ]) + )]) ); } diff --git a/juniper/src/executor_tests/executor.rs b/juniper/src/executor_tests/executor.rs index 7b4d62ea..7da8fb0f 100644 --- a/juniper/src/executor_tests/executor.rs +++ b/juniper/src/executor_tests/executor.rs @@ -1,8 +1,8 @@ mod field_execution { - use value::Value; use ast::InputValue; use schema::model::RootNode; use types::scalars::EmptyMutation; + use value::Value; struct DataType; struct DeepDataType; @@ -128,9 +128,9 @@ mod field_execution { } mod merge_parallel_fragments { - use value::Value; use schema::model::RootNode; use types::scalars::EmptyMutation; + use value::Value; struct Type; @@ -198,9 +198,9 @@ mod merge_parallel_fragments { } mod merge_parallel_inline_fragments { - use value::Value; use schema::model::RootNode; use types::scalars::EmptyMutation; + use value::Value; struct Type; struct Other; @@ -270,38 +270,34 @@ mod merge_parallel_inline_fragments { ("b", Value::string("Banana")), ( "deeper", - Value::list( - vec![ - Value::object( - vec![ - ( - "deepest", - Value::object( - vec![ - ("b", Value::string("Banana")), - ("c", Value::string("Cherry")), - ].into_iter() - .collect(), - ), - ), - ].into_iter().collect() - ), - Value::object( - vec![ - ( - "deepest", - Value::object( - vec![ - ("b", Value::string("Banana")), - ("c", Value::string("Cherry")), - ].into_iter() - .collect(), - ), - ), - ].into_iter().collect() - ), - ] - ), + Value::list(vec![ + Value::object( + vec![( + "deepest", + Value::object( + vec![ + ("b", Value::string("Banana")), + ("c", Value::string("Cherry")), + ].into_iter() + .collect(), + ), + )].into_iter() + .collect(), + ), + Value::object( + vec![( + "deepest", + Value::object( + vec![ + ("b", Value::string("Banana")), + ("c", Value::string("Cherry")), + ].into_iter() + .collect(), + ), + )].into_iter() + .collect(), + ), + ]), ), ("c", Value::string("Cherry")), ].into_iter() @@ -317,10 +313,10 @@ mod merge_parallel_inline_fragments { } mod threads_context_correctly { - use value::Value; - use types::scalars::EmptyMutation; - use schema::model::RootNode; use executor::Context; + use schema::model::RootNode; + use types::scalars::EmptyMutation; + use value::Value; struct Schema; @@ -369,11 +365,11 @@ mod threads_context_correctly { mod dynamic_context_switching { use indexmap::IndexMap; - use value::Value; - use types::scalars::EmptyMutation; - use schema::model::RootNode; - use parser::SourcePosition; use executor::{Context, ExecutionError, FieldError, FieldResult}; + use parser::SourcePosition; + use schema::model::RootNode; + use types::scalars::EmptyMutation; + use value::Value; struct Schema; @@ -509,16 +505,14 @@ mod dynamic_context_switching { assert_eq!( result, Value::object( - vec![ - ( - "first", - Value::object( - vec![("value", Value::string("First value"))] - .into_iter() - .collect(), - ), + vec![( + "first", + Value::object( + vec![("value", Value::string("First value"))] + .into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect() ) ); @@ -557,13 +551,11 @@ mod dynamic_context_switching { assert_eq!( errs, - vec![ - ExecutionError::new( - SourcePosition::new(25, 2, 12), - &["missing"], - FieldError::new("Could not find key 2", Value::null()), - ), - ] + vec![ExecutionError::new( + SourcePosition::new(25, 2, 12), + &["missing"], + FieldError::new("Could not find key 2", Value::null()), + )] ); println!("Result: {:?}", result); @@ -606,13 +598,11 @@ mod dynamic_context_switching { assert_eq!( errs, - [ - ExecutionError::new( - SourcePosition::new(123, 4, 12), - &["tooLarge"], - FieldError::new("Key too large: 200", Value::null()), - ), - ] + [ExecutionError::new( + SourcePosition::new(123, 4, 12), + &["tooLarge"], + FieldError::new("Key too large: 200", Value::null()), + )] ); println!("Result: {:?}", result); @@ -671,16 +661,14 @@ mod dynamic_context_switching { assert_eq!( result, Value::object( - vec![ - ( - "first", - Value::object( - vec![("value", Value::string("First value"))] - .into_iter() - .collect(), - ), + vec![( + "first", + Value::object( + vec![("value", Value::string("First value"))] + .into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect() ) ); @@ -688,11 +676,11 @@ mod dynamic_context_switching { } mod propagates_errors_to_nullable_fields { - use value::Value; - use schema::model::RootNode; use executor::{ExecutionError, FieldError, FieldResult}; use parser::SourcePosition; + use schema::model::RootNode; use types::scalars::EmptyMutation; + use value::Value; struct Schema; struct Inner; @@ -728,13 +716,11 @@ mod propagates_errors_to_nullable_fields { assert_eq!( errs, - vec![ - ExecutionError::new( - SourcePosition::new(10, 0, 10), - &["inner", "nullableErrorField"], - FieldError::new("Error for nullableErrorField", Value::null()), - ), - ] + vec![ExecutionError::new( + SourcePosition::new(10, 0, 10), + &["inner", "nullableErrorField"], + FieldError::new("Error for nullableErrorField", Value::null()), + )] ); } @@ -753,13 +739,11 @@ mod propagates_errors_to_nullable_fields { assert_eq!( errs, - vec![ - ExecutionError::new( - SourcePosition::new(10, 0, 10), - &["inner", "nonNullableErrorField"], - FieldError::new("Error for nonNullableErrorField", Value::null()), - ), - ] + vec![ExecutionError::new( + SourcePosition::new(10, 0, 10), + &["inner", "nonNullableErrorField"], + FieldError::new("Error for nonNullableErrorField", Value::null()), + )] ); } @@ -781,13 +765,11 @@ mod propagates_errors_to_nullable_fields { assert_eq!( errs, - vec![ - ExecutionError::new( - SourcePosition::new(26, 0, 26), - &["inner", "nullableField", "nonNullableErrorField"], - FieldError::new("Error for nonNullableErrorField", Value::null()), - ), - ] + vec![ExecutionError::new( + SourcePosition::new(26, 0, 26), + &["inner", "nullableField", "nonNullableErrorField"], + FieldError::new("Error for nonNullableErrorField", Value::null()), + )] ); } @@ -806,13 +788,11 @@ mod propagates_errors_to_nullable_fields { assert_eq!( errs, - vec![ - ExecutionError::new( - SourcePosition::new(29, 0, 29), - &["inner", "nonNullableField", "nonNullableErrorField"], - FieldError::new("Error for nonNullableErrorField", Value::null()), - ), - ] + vec![ExecutionError::new( + SourcePosition::new(29, 0, 29), + &["inner", "nonNullableField", "nonNullableErrorField"], + FieldError::new("Error for nonNullableErrorField", Value::null()), + )] ); } @@ -834,13 +814,11 @@ mod propagates_errors_to_nullable_fields { assert_eq!( errs, - vec![ - ExecutionError::new( - SourcePosition::new(29, 0, 29), - &["inner", "nonNullableField", "nullableErrorField"], - FieldError::new("Error for nullableErrorField", Value::null()), - ), - ] + vec![ExecutionError::new( + SourcePosition::new(29, 0, 29), + &["inner", "nonNullableField", "nullableErrorField"], + FieldError::new("Error for nullableErrorField", Value::null()), + )] ); } @@ -859,13 +837,11 @@ mod propagates_errors_to_nullable_fields { assert_eq!( errs, - vec![ - ExecutionError::new( - SourcePosition::new(11, 0, 11), - &["inners", "nonNullableErrorField"], - FieldError::new("Error for nonNullableErrorField", Value::null()), - ), - ] + vec![ExecutionError::new( + SourcePosition::new(11, 0, 11), + &["inners", "nonNullableErrorField"], + FieldError::new("Error for nonNullableErrorField", Value::null()), + )] ); } @@ -919,9 +895,9 @@ mod propagates_errors_to_nullable_fields { } mod named_operations { - use value::Value; use schema::model::RootNode; use types::scalars::EmptyMutation; + use value::Value; use GraphQLError; struct Schema; diff --git a/juniper/src/executor_tests/interfaces_unions.rs b/juniper/src/executor_tests/interfaces_unions.rs index 7be8b38e..c6117566 100644 --- a/juniper/src/executor_tests/interfaces_unions.rs +++ b/juniper/src/executor_tests/interfaces_unions.rs @@ -1,7 +1,7 @@ mod interface { - use value::Value; use schema::model::RootNode; use types::scalars::EmptyMutation; + use value::Value; trait Pet { fn name(&self) -> &str; @@ -116,27 +116,25 @@ mod interface { assert_eq!( result, Value::object( - vec![ - ( - "pets", - Value::list(vec![ - Value::object( - vec![ - ("name", Value::string("Odie")), - ("woofs", Value::boolean(true)), - ].into_iter() - .collect(), - ), - Value::object( - vec![ - ("name", Value::string("Garfield")), - ("meows", Value::boolean(false)), - ].into_iter() - .collect(), - ), - ]), - ), - ].into_iter() + vec![( + "pets", + Value::list(vec![ + Value::object( + vec![ + ("name", Value::string("Odie")), + ("woofs", Value::boolean(true)), + ].into_iter() + .collect(), + ), + Value::object( + vec![ + ("name", Value::string("Garfield")), + ("meows", Value::boolean(false)), + ].into_iter() + .collect(), + ), + ]), + )].into_iter() .collect() ) ); @@ -144,9 +142,9 @@ mod interface { } mod union { - use value::Value; use schema::model::RootNode; use types::scalars::EmptyMutation; + use value::Value; trait Pet { fn as_dog(&self) -> Option<&Dog> { @@ -249,29 +247,27 @@ mod union { assert_eq!( result, Value::object( - vec![ - ( - "pets", - Value::list(vec![ - Value::object( - vec![ - ("__typename", Value::string("Dog")), - ("name", Value::string("Odie")), - ("woofs", Value::boolean(true)), - ].into_iter() - .collect(), - ), - Value::object( - vec![ - ("__typename", Value::string("Cat")), - ("name", Value::string("Garfield")), - ("meows", Value::boolean(false)), - ].into_iter() - .collect(), - ), - ]), - ), - ].into_iter() + vec![( + "pets", + Value::list(vec![ + Value::object( + vec![ + ("__typename", Value::string("Dog")), + ("name", Value::string("Odie")), + ("woofs", Value::boolean(true)), + ].into_iter() + .collect(), + ), + Value::object( + vec![ + ("__typename", Value::string("Cat")), + ("name", Value::string("Garfield")), + ("meows", Value::boolean(false)), + ].into_iter() + .collect(), + ), + ]), + )].into_iter() .collect() ) ); diff --git a/juniper/src/executor_tests/introspection/enums.rs b/juniper/src/executor_tests/introspection/enums.rs index 27f378bc..9e21d0a0 100644 --- a/juniper/src/executor_tests/introspection/enums.rs +++ b/juniper/src/executor_tests/introspection/enums.rs @@ -1,9 +1,9 @@ use indexmap::IndexMap; use executor::Variables; -use value::Value; use schema::model::RootNode; use types::scalars::EmptyMutation; +use value::Value; /* @@ -48,15 +48,19 @@ enum EnumDescription { #[derive(GraphQLEnum)] #[graphql(_internal)] enum EnumValueDescription { - #[graphql(description = "The FOO value")] Foo, - #[graphql(description = "The BAR value")] Bar, + #[graphql(description = "The FOO value")] + Foo, + #[graphql(description = "The BAR value")] + Bar, } #[derive(GraphQLEnum)] #[graphql(_internal)] enum EnumDeprecation { - #[graphql(deprecated = "Please don't use FOO any more")] Foo, - #[graphql(description = "The BAR value", deprecated = "Please don't use BAR any more")] Bar, + #[graphql(deprecated = "Please don't use FOO any more")] + Foo, + #[graphql(description = "The BAR value", deprecated = "Please don't use BAR any more")] + Bar, } struct Root; @@ -131,7 +135,7 @@ fn default_name_introspection() { ("isDeprecated", Value::boolean(false)), ("deprecationReason", Value::null()), ].into_iter() - .collect() + .collect(), )) ); @@ -143,7 +147,7 @@ fn default_name_introspection() { ("isDeprecated", Value::boolean(false)), ("deprecationReason", Value::null()), ].into_iter() - .collect() + .collect(), )) ); }); @@ -180,7 +184,7 @@ fn named_introspection() { ("isDeprecated", Value::boolean(false)), ("deprecationReason", Value::null()), ].into_iter() - .collect() + .collect(), )) ); @@ -192,7 +196,7 @@ fn named_introspection() { ("isDeprecated", Value::boolean(false)), ("deprecationReason", Value::null()), ].into_iter() - .collect() + .collect(), )) ); }); @@ -232,7 +236,7 @@ fn no_trailing_comma_introspection() { ("isDeprecated", Value::boolean(false)), ("deprecationReason", Value::null()), ].into_iter() - .collect() + .collect(), )) ); @@ -244,7 +248,7 @@ fn no_trailing_comma_introspection() { ("isDeprecated", Value::boolean(false)), ("deprecationReason", Value::null()), ].into_iter() - .collect() + .collect(), )) ); }); @@ -287,7 +291,7 @@ fn enum_description_introspection() { ("isDeprecated", Value::boolean(false)), ("deprecationReason", Value::null()), ].into_iter() - .collect() + .collect(), )) ); @@ -299,7 +303,7 @@ fn enum_description_introspection() { ("isDeprecated", Value::boolean(false)), ("deprecationReason", Value::null()), ].into_iter() - .collect() + .collect(), )) ); }); @@ -339,7 +343,7 @@ fn enum_value_description_introspection() { ("isDeprecated", Value::boolean(false)), ("deprecationReason", Value::null()), ].into_iter() - .collect() + .collect(), )) ); @@ -351,7 +355,7 @@ fn enum_value_description_introspection() { ("isDeprecated", Value::boolean(false)), ("deprecationReason", Value::null()), ].into_iter() - .collect() + .collect(), )) ); }); @@ -394,7 +398,7 @@ fn enum_deprecation_introspection() { Value::string("Please don't use FOO any more"), ), ].into_iter() - .collect() + .collect(), )) ); @@ -409,7 +413,7 @@ fn enum_deprecation_introspection() { Value::string("Please don't use BAR any more"), ), ].into_iter() - .collect() + .collect(), )) ); }); diff --git a/juniper/src/executor_tests/introspection/input_object.rs b/juniper/src/executor_tests/introspection/input_object.rs index f72d0b5c..6d48b2e2 100644 --- a/juniper/src/executor_tests/introspection/input_object.rs +++ b/juniper/src/executor_tests/introspection/input_object.rs @@ -2,9 +2,9 @@ use indexmap::IndexMap; use ast::{FromInputValue, InputValue}; use executor::Variables; -use value::Value; use schema::model::RootNode; use types::scalars::EmptyMutation; +use value::Value; struct Root; @@ -53,8 +53,11 @@ pub struct PublicWithDescription { } #[derive(GraphQLInputObject, Debug)] -#[graphql(name = "APublicNamedInputObjectWithDescription", - description = "Description for the input object", _internal)] +#[graphql( + name = "APublicNamedInputObjectWithDescription", + description = "Description for the input object", + _internal +)] pub struct NamedPublicWithDescription { field_one: String, } @@ -166,22 +169,20 @@ fn default_name_introspection() { ( "type", Value::object( - vec![ - ( - "ofType", - Value::object( - vec![("name", Value::string("String"))] - .into_iter() - .collect(), - ), + vec![( + "ofType", + Value::object( + vec![("name", Value::string("String"))] + .into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect(), ), ), ("defaultValue", Value::null()), ].into_iter() - .collect() + .collect(), )) ); @@ -193,22 +194,20 @@ fn default_name_introspection() { ( "type", Value::object( - vec![ - ( - "ofType", - Value::object( - vec![("name", Value::string("String"))] - .into_iter() - .collect(), - ), + vec![( + "ofType", + Value::object( + vec![("name", Value::string("String"))] + .into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect(), ), ), ("defaultValue", Value::null()), ].into_iter() - .collect() + .collect(), )) ); }); @@ -272,22 +271,20 @@ fn no_trailing_comma_introspection() { ( "type", Value::object( - vec![ - ( - "ofType", - Value::object( - vec![("name", Value::string("String"))] - .into_iter() - .collect(), - ), + vec![( + "ofType", + Value::object( + vec![("name", Value::string("String"))] + .into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect(), ), ), ("defaultValue", Value::null()), ].into_iter() - .collect() + .collect(), )) ); @@ -299,22 +296,20 @@ fn no_trailing_comma_introspection() { ( "type", Value::object( - vec![ - ( - "ofType", - Value::object( - vec![("name", Value::string("String"))] - .into_iter() - .collect(), - ), + vec![( + "ofType", + Value::object( + vec![("name", Value::string("String"))] + .into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect(), ), ), ("defaultValue", Value::null()), ].into_iter() - .collect() + .collect(), )) ); }); @@ -355,22 +350,20 @@ fn derive_introspection() { ( "type", Value::object( - vec![ - ( - "ofType", - Value::object( - vec![("name", Value::string("String"))] - .into_iter() - .collect(), - ), + vec![( + "ofType", + Value::object( + vec![("name", Value::string("String"))] + .into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect(), ), ), ("defaultValue", Value::null()), ].into_iter() - .collect() + .collect(), )) ); }); @@ -427,22 +420,20 @@ fn named_introspection() { ( "type", Value::object( - vec![ - ( - "ofType", - Value::object( - vec![("name", Value::string("String"))] - .into_iter() - .collect(), - ), + vec![( + "ofType", + Value::object( + vec![("name", Value::string("String"))] + .into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect(), ), ), ("defaultValue", Value::null()), ].into_iter() - .collect() + .collect(), )) ); }); @@ -486,22 +477,20 @@ fn description_introspection() { ( "type", Value::object( - vec![ - ( - "ofType", - Value::object( - vec![("name", Value::string("String"))] - .into_iter() - .collect(), - ), + vec![( + "ofType", + Value::object( + vec![("name", Value::string("String"))] + .into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect(), ), ), ("defaultValue", Value::null()), ].into_iter() - .collect() + .collect(), )) ); }); @@ -545,22 +534,20 @@ fn field_description_introspection() { ( "type", Value::object( - vec![ - ( - "ofType", - Value::object( - vec![("name", Value::string("String"))] - .into_iter() - .collect(), - ), + vec![( + "ofType", + Value::object( + vec![("name", Value::string("String"))] + .into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect(), ), ), ("defaultValue", Value::null()), ].into_iter() - .collect() + .collect(), )) ); @@ -572,22 +559,20 @@ fn field_description_introspection() { ( "type", Value::object( - vec![ - ( - "ofType", - Value::object( - vec![("name", Value::string("String"))] - .into_iter() - .collect(), - ), + vec![( + "ofType", + Value::object( + vec![("name", Value::string("String"))] + .into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect(), ), ), ("defaultValue", Value::null()), ].into_iter() - .collect() + .collect(), )) ); }); @@ -628,7 +613,7 @@ fn field_with_defaults_introspection() { ), ("defaultValue", Value::string("123")), ].into_iter() - .collect() + .collect(), )) ); @@ -642,7 +627,7 @@ fn field_with_defaults_introspection() { ), ("defaultValue", Value::string("456")), ].into_iter() - .collect() + .collect(), )) ); }); diff --git a/juniper/src/executor_tests/introspection/mod.rs b/juniper/src/executor_tests/introspection/mod.rs index 25f6251c..4351745e 100644 --- a/juniper/src/executor_tests/introspection/mod.rs +++ b/juniper/src/executor_tests/introspection/mod.rs @@ -1,14 +1,14 @@ -mod input_object; mod enums; +mod input_object; // This asserts that the input objects defined public actually became public #[allow(unused_imports)] use self::input_object::{NamedPublic, NamedPublicWithDescription}; use executor::Variables; -use value::Value; use schema::model::RootNode; use types::scalars::EmptyMutation; +use value::Value; #[derive(GraphQLEnum)] #[graphql(name = "SampleEnum", _internal)] @@ -155,7 +155,7 @@ fn enum_introspection() { ("isDeprecated", Value::boolean(false)), ("deprecationReason", Value::null()), ].into_iter() - .collect() + .collect(), )) ); @@ -167,7 +167,7 @@ fn enum_introspection() { ("isDeprecated", Value::boolean(false)), ("deprecationReason", Value::null()), ].into_iter() - .collect() + .collect(), )) ); } @@ -290,7 +290,7 @@ fn interface_introspection() { ("isDeprecated", Value::boolean(false)), ("deprecationReason", Value::null()), ].into_iter() - .collect() + .collect(), )) ); } @@ -366,13 +366,11 @@ fn object_introspection() { ); assert_eq!( type_info.get("interfaces"), - Some(&Value::list(vec![ - Value::object( - vec![("name", Value::string("SampleInterface"))] - .into_iter() - .collect(), - ), - ])) + Some(&Value::list(vec![Value::object( + vec![("name", Value::string("SampleInterface"))] + .into_iter() + .collect(), + )])) ); assert_eq!(type_info.get("enumValues"), Some(&Value::null())); assert_eq!(type_info.get("inputFields"), Some(&Value::null())); @@ -418,7 +416,7 @@ fn object_introspection() { ("isDeprecated", Value::boolean(false)), ("deprecationReason", Value::null()), ].into_iter() - .collect() + .collect(), )) ); @@ -506,7 +504,7 @@ fn object_introspection() { ("isDeprecated", Value::boolean(false)), ("deprecationReason", Value::null()), ].into_iter() - .collect() + .collect(), )) ); } diff --git a/juniper/src/executor_tests/mod.rs b/juniper/src/executor_tests/mod.rs index bf962966..01097618 100644 --- a/juniper/src/executor_tests/mod.rs +++ b/juniper/src/executor_tests/mod.rs @@ -1,6 +1,6 @@ -mod introspection; -mod variables; -mod enums; mod directives; +mod enums; mod executor; mod interfaces_unions; +mod introspection; +mod variables; diff --git a/juniper/src/executor_tests/variables.rs b/juniper/src/executor_tests/variables.rs index b67a1ed2..f76c288e 100644 --- a/juniper/src/executor_tests/variables.rs +++ b/juniper/src/executor_tests/variables.rs @@ -1,13 +1,13 @@ use indexmap::IndexMap; -use value::Value; use ast::InputValue; use executor::Variables; -use schema::model::RootNode; -use GraphQLError::ValidationError; -use validation::RuleError; use parser::SourcePosition; +use schema::model::RootNode; use types::scalars::EmptyMutation; +use validation::RuleError; +use value::Value; +use GraphQLError::ValidationError; #[derive(Debug)] struct TestComplexScalar; @@ -178,19 +178,17 @@ fn inline_runs_from_input_value_on_scalar() { fn variable_complex_input() { run_variable_query( r#"query q($input: TestInputObject) { fieldWithObjectInput(input: $input) }"#, - vec![ - ( - "input".to_owned(), - InputValue::object( - vec![ - ("a", InputValue::string("foo")), - ("b", InputValue::list(vec![InputValue::string("bar")])), - ("c", InputValue::string("baz")), - ].into_iter() - .collect(), - ), + vec![( + "input".to_owned(), + InputValue::object( + vec![ + ("a", InputValue::string("foo")), + ("b", InputValue::list(vec![InputValue::string("bar")])), + ("c", InputValue::string("baz")), + ].into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect(), |result| { assert_eq!( @@ -204,19 +202,17 @@ fn variable_complex_input() { fn variable_parse_single_value_to_list() { run_variable_query( r#"query q($input: TestInputObject) { fieldWithObjectInput(input: $input) }"#, - vec![ - ( - "input".to_owned(), - InputValue::object( - vec![ - ("a", InputValue::string("foo")), - ("b", InputValue::string("bar")), - ("c", InputValue::string("baz")), - ].into_iter() - .collect(), - ), + vec![( + "input".to_owned(), + InputValue::object( + vec![ + ("a", InputValue::string("foo")), + ("b", InputValue::string("bar")), + ("c", InputValue::string("baz")), + ].into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect(), |result| { assert_eq!( @@ -230,18 +226,16 @@ fn variable_parse_single_value_to_list() { fn variable_runs_from_input_value_on_scalar() { run_variable_query( r#"query q($input: TestInputObject) { fieldWithObjectInput(input: $input) }"#, - vec![ - ( - "input".to_owned(), - InputValue::object( - vec![ - ("c", InputValue::string("baz")), - ("d", InputValue::string("SerializedValue")), - ].into_iter() - .collect(), - ), + vec![( + "input".to_owned(), + InputValue::object( + vec![ + ("c", InputValue::string("baz")), + ("d", InputValue::string("SerializedValue")), + ].into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect(), |result| { assert_eq!( @@ -256,31 +250,27 @@ fn variable_error_on_nested_non_null() { let schema = RootNode::new(TestType, EmptyMutation::<()>::new()); let query = r#"query q($input: TestInputObject) { fieldWithObjectInput(input: $input) }"#; - let vars = vec![ - ( - "input".to_owned(), - InputValue::object( - vec![ - ("a", InputValue::string("foo")), - ("b", InputValue::string("bar")), - ("c", InputValue::null()), - ].into_iter() - .collect(), - ), + let vars = vec![( + "input".to_owned(), + InputValue::object( + vec![ + ("a", InputValue::string("foo")), + ("b", InputValue::string("bar")), + ("c", InputValue::null()), + ].into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect(); let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!( error, - ValidationError(vec![ - RuleError::new( + ValidationError(vec![RuleError::new( r#"Variable "$input" got invalid value. In field "c": Expected "String!", found null."#, &[SourcePosition::new(8, 0, 8)], - ), - ]) + )]) ); } @@ -308,30 +298,26 @@ fn variable_error_on_omit_non_null() { let schema = RootNode::new(TestType, EmptyMutation::<()>::new()); let query = r#"query q($input: TestInputObject) { fieldWithObjectInput(input: $input) }"#; - let vars = vec![ - ( - "input".to_owned(), - InputValue::object( - vec![ - ("a", InputValue::string("foo")), - ("b", InputValue::string("bar")), - ].into_iter() - .collect(), - ), + let vars = vec![( + "input".to_owned(), + InputValue::object( + vec![ + ("a", InputValue::string("foo")), + ("b", InputValue::string("bar")), + ].into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect(); let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!( error, - ValidationError(vec![ - RuleError::new( + ValidationError(vec![RuleError::new( r#"Variable "$input" got invalid value. In field "c": Expected "String!", found null."#, &[SourcePosition::new(8, 0, 8)], - ), - ]) + )]) ); } @@ -341,22 +327,16 @@ fn variable_multiple_errors_with_nesting() { let query = r#"query q($input: TestNestedInputObject) { fieldWithNestedObjectInput(input: $input) }"#; - let vars = vec![ - ( - "input".to_owned(), - InputValue::object( - vec![ - ( - "na", - InputValue::object( - vec![("a", InputValue::string("foo"))].into_iter().collect(), - ), - ), - ].into_iter() - .collect(), - ), + let vars = vec![( + "input".to_owned(), + InputValue::object( + vec![( + "na", + InputValue::object(vec![("a", InputValue::string("foo"))].into_iter().collect()), + )].into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect(); let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); @@ -378,32 +358,28 @@ fn variable_error_on_additional_field() { let schema = RootNode::new(TestType, EmptyMutation::<()>::new()); let query = r#"query q($input: TestInputObject) { fieldWithObjectInput(input: $input) }"#; - let vars = vec![ - ( - "input".to_owned(), - InputValue::object( - vec![ - ("a", InputValue::string("foo")), - ("b", InputValue::string("bar")), - ("c", InputValue::string("baz")), - ("extra", InputValue::string("dog")), - ].into_iter() - .collect(), - ), + let vars = vec![( + "input".to_owned(), + InputValue::object( + vec![ + ("a", InputValue::string("foo")), + ("b", InputValue::string("bar")), + ("c", InputValue::string("baz")), + ("extra", InputValue::string("dog")), + ].into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect(); let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!( error, - ValidationError(vec![ - RuleError::new( - r#"Variable "$input" got invalid value. In field "extra": Unknown field."#, - &[SourcePosition::new(8, 0, 8)], - ), - ]) + ValidationError(vec![RuleError::new( + r#"Variable "$input" got invalid value. In field "extra": Unknown field."#, + &[SourcePosition::new(8, 0, 8)], + )]) ); } @@ -499,12 +475,10 @@ fn does_not_allow_non_nullable_input_to_be_omitted_in_variable() { assert_eq!( error, - ValidationError(vec![ - RuleError::new( - r#"Variable "$value" of required type "String!" was not provided."#, - &[SourcePosition::new(8, 0, 8)], - ), - ]) + ValidationError(vec![RuleError::new( + r#"Variable "$value" of required type "String!" was not provided."#, + &[SourcePosition::new(8, 0, 8)], + )]) ); } @@ -521,12 +495,10 @@ fn does_not_allow_non_nullable_input_to_be_set_to_null_in_variable() { assert_eq!( error, - ValidationError(vec![ - RuleError::new( - r#"Variable "$value" of required type "String!" was not provided."#, - &[SourcePosition::new(8, 0, 8)], - ), - ]) + ValidationError(vec![RuleError::new( + r#"Variable "$value" of required type "String!" was not provided."#, + &[SourcePosition::new(8, 0, 8)], + )]) ); } @@ -576,12 +548,10 @@ fn allow_lists_to_be_null() { fn allow_lists_to_contain_values() { run_variable_query( r#"query q($input: [String]) { list(input: $input) }"#, - vec![ - ( - "input".to_owned(), - InputValue::list(vec![InputValue::string("A")]), - ), - ].into_iter() + vec![( + "input".to_owned(), + InputValue::list(vec![InputValue::string("A")]), + )].into_iter() .collect(), |result| { assert_eq!( @@ -596,16 +566,14 @@ fn allow_lists_to_contain_values() { fn allow_lists_to_contain_null() { run_variable_query( r#"query q($input: [String]) { list(input: $input) }"#, - vec![ - ( - "input".to_owned(), - InputValue::list(vec![ - InputValue::string("A"), - InputValue::null(), - InputValue::string("B"), - ]), - ), - ].into_iter() + vec![( + "input".to_owned(), + InputValue::list(vec![ + InputValue::string("A"), + InputValue::null(), + InputValue::string("B"), + ]), + )].into_iter() .collect(), |result| { assert_eq!( @@ -629,12 +597,10 @@ fn does_not_allow_non_null_lists_to_be_null() { assert_eq!( error, - ValidationError(vec![ - RuleError::new( - r#"Variable "$input" of required type "[String]!" was not provided."#, - &[SourcePosition::new(8, 0, 8)], - ), - ]) + ValidationError(vec![RuleError::new( + r#"Variable "$input" of required type "[String]!" was not provided."#, + &[SourcePosition::new(8, 0, 8)], + )]) ); } @@ -642,12 +608,10 @@ fn does_not_allow_non_null_lists_to_be_null() { fn allow_non_null_lists_to_contain_values() { run_variable_query( r#"query q($input: [String]!) { nnList(input: $input) }"#, - vec![ - ( - "input".to_owned(), - InputValue::list(vec![InputValue::string("A")]), - ), - ].into_iter() + vec![( + "input".to_owned(), + InputValue::list(vec![InputValue::string("A")]), + )].into_iter() .collect(), |result| { assert_eq!(result.get("nnList"), Some(&Value::string(r#"[Some("A")]"#))); @@ -658,16 +622,14 @@ fn allow_non_null_lists_to_contain_values() { fn allow_non_null_lists_to_contain_null() { run_variable_query( r#"query q($input: [String]!) { nnList(input: $input) }"#, - vec![ - ( - "input".to_owned(), - InputValue::list(vec![ - InputValue::string("A"), - InputValue::null(), - InputValue::string("B"), - ]), - ), - ].into_iter() + vec![( + "input".to_owned(), + InputValue::list(vec![ + InputValue::string("A"), + InputValue::null(), + InputValue::string("B"), + ]), + )].into_iter() .collect(), |result| { assert_eq!( @@ -695,12 +657,10 @@ fn allow_lists_of_non_null_to_be_null() { fn allow_lists_of_non_null_to_contain_values() { run_variable_query( r#"query q($input: [String!]) { listNn(input: $input) }"#, - vec![ - ( - "input".to_owned(), - InputValue::list(vec![InputValue::string("A")]), - ), - ].into_iter() + vec![( + "input".to_owned(), + InputValue::list(vec![InputValue::string("A")]), + )].into_iter() .collect(), |result| { assert_eq!(result.get("listNn"), Some(&Value::string(r#"Some(["A"])"#))); @@ -713,16 +673,14 @@ fn does_not_allow_lists_of_non_null_to_contain_null() { let schema = RootNode::new(TestType, EmptyMutation::<()>::new()); let query = r#"query q($input: [String!]) { listNn(input: $input) }"#; - let vars = vec![ - ( - "input".to_owned(), - InputValue::list(vec![ - InputValue::string("A"), - InputValue::null(), - InputValue::string("B"), - ]), - ), - ].into_iter() + let vars = vec![( + "input".to_owned(), + InputValue::list(vec![ + InputValue::string("A"), + InputValue::null(), + InputValue::string("B"), + ]), + )].into_iter() .collect(); let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); @@ -740,16 +698,14 @@ fn does_not_allow_non_null_lists_of_non_null_to_contain_null() { let schema = RootNode::new(TestType, EmptyMutation::<()>::new()); let query = r#"query q($input: [String!]!) { nnListNn(input: $input) }"#; - let vars = vec![ - ( - "input".to_owned(), - InputValue::list(vec![ - InputValue::string("A"), - InputValue::null(), - InputValue::string("B"), - ]), - ), - ].into_iter() + let vars = vec![( + "input".to_owned(), + InputValue::list(vec![ + InputValue::string("A"), + InputValue::null(), + InputValue::string("B"), + ]), + )].into_iter() .collect(); let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); @@ -775,12 +731,10 @@ fn does_not_allow_non_null_lists_of_non_null_to_be_null() { assert_eq!( error, - ValidationError(vec![ - RuleError::new( - r#"Variable "$input" of required type "[String!]!" was not provided."#, - &[SourcePosition::new(8, 0, 8)], - ), - ]) + ValidationError(vec![RuleError::new( + r#"Variable "$input" of required type "[String!]!" was not provided."#, + &[SourcePosition::new(8, 0, 8)], + )]) ); } @@ -788,12 +742,10 @@ fn does_not_allow_non_null_lists_of_non_null_to_be_null() { fn allow_non_null_lists_of_non_null_to_contain_values() { run_variable_query( r#"query q($input: [String!]!) { nnListNn(input: $input) }"#, - vec![ - ( - "input".to_owned(), - InputValue::list(vec![InputValue::string("A")]), - ), - ].into_iter() + vec![( + "input".to_owned(), + InputValue::list(vec![InputValue::string("A")]), + )].into_iter() .collect(), |result| { assert_eq!(result.get("nnListNn"), Some(&Value::string(r#"["A"]"#))); @@ -806,12 +758,10 @@ fn does_not_allow_invalid_types_to_be_used_as_values() { let schema = RootNode::new(TestType, EmptyMutation::<()>::new()); let query = r#"query q($input: TestType!) { fieldWithObjectInput(input: $input) }"#; - let vars = vec![ - ( - "value".to_owned(), - InputValue::list(vec![InputValue::string("A"), InputValue::string("B")]), - ), - ].into_iter() + let vars = vec![( + "value".to_owned(), + InputValue::list(vec![InputValue::string("A"), InputValue::string("B")]), + )].into_iter() .collect(); let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); @@ -829,12 +779,10 @@ fn does_not_allow_unknown_types_to_be_used_as_values() { let schema = RootNode::new(TestType, EmptyMutation::<()>::new()); let query = r#"query q($input: UnknownType!) { fieldWithObjectInput(input: $input) }"#; - let vars = vec![ - ( - "value".to_owned(), - InputValue::list(vec![InputValue::string("A"), InputValue::string("B")]), - ), - ].into_iter() + let vars = vec![( + "value".to_owned(), + InputValue::list(vec![InputValue::string("A"), InputValue::string("B")]), + )].into_iter() .collect(); let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); @@ -954,12 +902,10 @@ fn does_not_allow_missing_required_field() { assert_eq!( error, - ValidationError(vec![ - RuleError::new( - r#"Invalid value for argument "arg", expected type "ExampleInputObject!""#, - &[SourcePosition::new(20, 0, 20)], - ), - ]) + ValidationError(vec![RuleError::new( + r#"Invalid value for argument "arg", expected type "ExampleInputObject!""#, + &[SourcePosition::new(20, 0, 20)], + )]) ); } @@ -974,12 +920,10 @@ fn does_not_allow_null_in_required_field() { assert_eq!( error, - ValidationError(vec![ - RuleError::new( - r#"Invalid value for argument "arg", expected type "ExampleInputObject!""#, - &[SourcePosition::new(20, 0, 20)], - ), - ]) + ValidationError(vec![RuleError::new( + r#"Invalid value for argument "arg", expected type "ExampleInputObject!""#, + &[SourcePosition::new(20, 0, 20)], + )]) ); } @@ -994,12 +938,10 @@ fn does_not_allow_missing_variable_for_required_field() { assert_eq!( error, - ValidationError(vec![ - RuleError::new( - r#"Variable "$var" of required type "Int!" was not provided."#, - &[SourcePosition::new(8, 0, 8)], - ), - ]) + ValidationError(vec![RuleError::new( + r#"Variable "$var" of required type "Int!" was not provided."#, + &[SourcePosition::new(8, 0, 8)], + )]) ); } @@ -1016,12 +958,10 @@ fn does_not_allow_null_variable_for_required_field() { assert_eq!( error, - ValidationError(vec![ - RuleError::new( - r#"Variable "$var" of required type "Int!" was not provided."#, - &[SourcePosition::new(8, 0, 8)], - ), - ]) + ValidationError(vec![RuleError::new( + r#"Variable "$var" of required type "Int!" was not provided."#, + &[SourcePosition::new(8, 0, 8)], + )]) ); } @@ -1117,12 +1057,10 @@ mod integers { assert_eq!( error, - ValidationError(vec![ - RuleError::new( - r#"Variable "$var" got invalid value. Expected "Int"."#, - &[SourcePosition::new(8, 0, 8)], - ), - ]) + ValidationError(vec![RuleError::new( + r#"Variable "$var" got invalid value. Expected "Int"."#, + &[SourcePosition::new(8, 0, 8)], + )]) ); } @@ -1139,12 +1077,10 @@ mod integers { assert_eq!( error, - ValidationError(vec![ - RuleError::new( - r#"Variable "$var" got invalid value. Expected "Int"."#, - &[SourcePosition::new(8, 0, 8)], - ), - ]) + ValidationError(vec![RuleError::new( + r#"Variable "$var" got invalid value. Expected "Int"."#, + &[SourcePosition::new(8, 0, 8)], + )]) ); } } @@ -1197,12 +1133,10 @@ mod floats { assert_eq!( error, - ValidationError(vec![ - RuleError::new( - r#"Variable "$var" got invalid value. Expected "Float"."#, - &[SourcePosition::new(8, 0, 8)], - ), - ]) + ValidationError(vec![RuleError::new( + r#"Variable "$var" got invalid value. Expected "Float"."#, + &[SourcePosition::new(8, 0, 8)], + )]) ); } } diff --git a/juniper/src/http/mod.rs b/juniper/src/http/mod.rs index ac975c34..89b5ab35 100644 --- a/juniper/src/http/mod.rs +++ b/juniper/src/http/mod.rs @@ -5,9 +5,9 @@ pub mod graphiql; use serde::ser; use serde::ser::SerializeMap; -use {GraphQLError, GraphQLType, RootNode, Value, Variables}; use ast::InputValue; use executor::ExecutionError; +use {GraphQLError, GraphQLType, RootNode, Value, Variables}; /// The expected structure of the decoded JSON document for either POST or GET requests. /// @@ -127,8 +127,8 @@ impl<'a> ser::Serialize for GraphQLResponse<'a> { #[cfg(any(test, feature = "expose-test-schema"))] #[allow(missing_docs)] pub mod tests { - use serde_json::Value as Json; use serde_json; + use serde_json::Value as Json; /// Normalized response content we expect to get back from /// the http framework integration we are testing. diff --git a/juniper/src/integrations/chrono.rs b/juniper/src/integrations/chrono.rs index 1c999b44..f6fce0da 100644 --- a/juniper/src/integrations/chrono.rs +++ b/juniper/src/integrations/chrono.rs @@ -169,9 +169,9 @@ mod integration_test { use chrono::Utc; use executor::Variables; - use value::Value; use schema::model::RootNode; use types::scalars::EmptyMutation; + use value::Value; #[test] fn test_serialization() { diff --git a/juniper/src/integrations/serde.rs b/juniper/src/integrations/serde.rs index b1b7bdc0..72b96ef8 100644 --- a/juniper/src/integrations/serde.rs +++ b/juniper/src/integrations/serde.rs @@ -1,14 +1,14 @@ use indexmap::IndexMap; -use serde::{de, ser}; use serde::ser::SerializeMap; +use serde::{de, ser}; use std::fmt; -use {GraphQLError, Value}; use ast::InputValue; use executor::ExecutionError; use parser::{ParseError, SourcePosition, Spanning}; use validation::RuleError; +use {GraphQLError, Value}; impl ser::Serialize for ExecutionError { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> diff --git a/juniper/src/lib.rs b/juniper/src/lib.rs index 10ed9bdd..28b90da0 100644 --- a/juniper/src/lib.rs +++ b/juniper/src/lib.rs @@ -122,16 +122,16 @@ mod value; #[macro_use] mod macros; mod ast; -pub mod parser; -mod types; -mod schema; -mod validation; -mod util; mod executor; +pub mod parser; +mod schema; +mod types; +mod util; +mod validation; // This needs to be public until docs have support for private modules: // https://github.com/rust-lang/cargo/issues/1520 -pub mod integrations; pub mod http; +pub mod integrations; // TODO: remove this alias export in 0.10. (breaking change) pub use http::graphiql; @@ -146,18 +146,18 @@ mod executor_tests; // Needs to be public because macros use it. pub use util::to_camel_case; +use executor::execute_validated_query; use parser::{parse_document_source, ParseError, Spanning}; use validation::{validate_input_values, visit_all_rules, ValidatorContext}; -use executor::execute_validated_query; pub use ast::{FromInputValue, InputValue, Selection, ToInputValue, Type}; -pub use value::Value; -pub use types::base::{Arguments, GraphQLType, TypeKind}; pub use executor::{Context, ExecutionError, ExecutionResult, Executor, FieldError, FieldResult, FromContext, IntoResolvable, Registry, Variables}; -pub use validation::RuleError; -pub use types::scalars::{EmptyMutation, ID}; pub use schema::model::RootNode; +pub use types::base::{Arguments, GraphQLType, TypeKind}; +pub use types::scalars::{EmptyMutation, ID}; +pub use validation::RuleError; +pub use value::Value; pub use schema::meta; diff --git a/juniper/src/macros/tests/args.rs b/juniper/src/macros/tests/args.rs index 056624d0..ec80170d 100644 --- a/juniper/src/macros/tests/args.rs +++ b/juniper/src/macros/tests/args.rs @@ -1,7 +1,7 @@ use executor::Variables; -use value::Value; use schema::model::RootNode; use types::scalars::EmptyMutation; +use value::Value; struct Root; @@ -192,7 +192,7 @@ fn introspect_field_exec_arg_and_more() { ), ), ].into_iter() - .collect() + .collect(), )) ); }); @@ -225,7 +225,7 @@ fn introspect_field_single_arg() { ), ), ].into_iter() - .collect() + .collect(), )) ); }); @@ -258,7 +258,7 @@ fn introspect_field_multi_args() { ), ), ].into_iter() - .collect() + .collect(), )) ); @@ -284,7 +284,7 @@ fn introspect_field_multi_args() { ), ), ].into_iter() - .collect() + .collect(), )) ); }); @@ -317,7 +317,7 @@ fn introspect_field_multi_args_trailing_comma() { ), ), ].into_iter() - .collect() + .collect(), )) ); @@ -343,7 +343,7 @@ fn introspect_field_multi_args_trailing_comma() { ), ), ].into_iter() - .collect() + .collect(), )) ); }); @@ -376,7 +376,7 @@ fn introspect_field_single_arg_descr() { ), ), ].into_iter() - .collect() + .collect(), )) ); }); @@ -409,7 +409,7 @@ fn introspect_field_multi_args_descr() { ), ), ].into_iter() - .collect() + .collect(), )) ); @@ -435,7 +435,7 @@ fn introspect_field_multi_args_descr() { ), ), ].into_iter() - .collect() + .collect(), )) ); }); @@ -468,7 +468,7 @@ fn introspect_field_multi_args_descr_trailing_comma() { ), ), ].into_iter() - .collect() + .collect(), )) ); @@ -494,7 +494,7 @@ fn introspect_field_multi_args_descr_trailing_comma() { ), ), ].into_iter() - .collect() + .collect(), )) ); }); @@ -520,7 +520,7 @@ fn introspect_field_arg_with_default() { ), ), ].into_iter() - .collect() + .collect(), )) ); }); @@ -546,7 +546,7 @@ fn introspect_field_multi_args_with_default() { ), ), ].into_iter() - .collect() + .collect(), )) ); @@ -565,7 +565,7 @@ fn introspect_field_multi_args_with_default() { ), ), ].into_iter() - .collect() + .collect(), )) ); }); @@ -591,7 +591,7 @@ fn introspect_field_multi_args_with_default_trailing_comma() { ), ), ].into_iter() - .collect() + .collect(), )) ); @@ -610,7 +610,7 @@ fn introspect_field_multi_args_with_default_trailing_comma() { ), ), ].into_iter() - .collect() + .collect(), )) ); }); @@ -636,7 +636,7 @@ fn introspect_field_arg_with_default_descr() { ), ), ].into_iter() - .collect() + .collect(), )) ); }); @@ -662,7 +662,7 @@ fn introspect_field_multi_args_with_default_descr() { ), ), ].into_iter() - .collect() + .collect(), )) ); @@ -681,7 +681,7 @@ fn introspect_field_multi_args_with_default_descr() { ), ), ].into_iter() - .collect() + .collect(), )) ); }); @@ -707,7 +707,7 @@ fn introspect_field_multi_args_with_default_trailing_comma_descr() { ), ), ].into_iter() - .collect() + .collect(), )) ); @@ -726,7 +726,7 @@ fn introspect_field_multi_args_with_default_trailing_comma_descr() { ), ), ].into_iter() - .collect() + .collect(), )) ); }); @@ -752,7 +752,7 @@ fn introspect_field_args_with_complex_default() { ), ), ].into_iter() - .collect() + .collect(), )) ); @@ -774,7 +774,7 @@ fn introspect_field_args_with_complex_default() { ), ), ].into_iter() - .collect() + .collect(), )) ); }); diff --git a/juniper/src/macros/tests/field.rs b/juniper/src/macros/tests/field.rs index 9ef8b6aa..e902f488 100644 --- a/juniper/src/macros/tests/field.rs +++ b/juniper/src/macros/tests/field.rs @@ -1,10 +1,10 @@ use indexmap::IndexMap; -use value::Value; use ast::InputValue; -use schema::model::RootNode; use executor::FieldResult; +use schema::model::RootNode; use types::scalars::EmptyMutation; +use value::Value; struct Interface; struct Root; diff --git a/juniper/src/macros/tests/interface.rs b/juniper/src/macros/tests/interface.rs index 4bf19904..0c2427f8 100644 --- a/juniper/src/macros/tests/interface.rs +++ b/juniper/src/macros/tests/interface.rs @@ -2,9 +2,9 @@ use indexmap::IndexMap; use std::marker::PhantomData; use ast::InputValue; -use value::Value; use schema::model::RootNode; use types::scalars::EmptyMutation; +use value::Value; /* @@ -184,7 +184,7 @@ fn introspect_custom_name() { fields.contains(&Value::object( vec![("name", Value::string("simple"))] .into_iter() - .collect() + .collect(), )) ); }); @@ -200,7 +200,7 @@ fn introspect_with_lifetime() { fields.contains(&Value::object( vec![("name", Value::string("simple"))] .into_iter() - .collect() + .collect(), )) ); }); @@ -216,7 +216,7 @@ fn introspect_with_generics() { fields.contains(&Value::object( vec![("name", Value::string("simple"))] .into_iter() - .collect() + .collect(), )) ); }); @@ -235,7 +235,7 @@ fn introspect_description_first() { fields.contains(&Value::object( vec![("name", Value::string("simple"))] .into_iter() - .collect() + .collect(), )) ); }); @@ -254,7 +254,7 @@ fn introspect_fields_first() { fields.contains(&Value::object( vec![("name", Value::string("simple"))] .into_iter() - .collect() + .collect(), )) ); }); @@ -273,7 +273,7 @@ fn introspect_interfaces_first() { fields.contains(&Value::object( vec![("name", Value::string("simple"))] .into_iter() - .collect() + .collect(), )) ); }); @@ -295,7 +295,7 @@ fn introspect_commas_with_trailing() { fields.contains(&Value::object( vec![("name", Value::string("simple"))] .into_iter() - .collect() + .collect(), )) ); }); @@ -314,7 +314,7 @@ fn introspect_commas_on_meta() { fields.contains(&Value::object( vec![("name", Value::string("simple"))] .into_iter() - .collect() + .collect(), )) ); }); @@ -336,7 +336,7 @@ fn introspect_resolvers_with_trailing_comma() { fields.contains(&Value::object( vec![("name", Value::string("simple"))] .into_iter() - .collect() + .collect(), )) ); }); diff --git a/juniper/src/macros/tests/mod.rs b/juniper/src/macros/tests/mod.rs index c3b038cc..82f642e8 100644 --- a/juniper/src/macros/tests/mod.rs +++ b/juniper/src/macros/tests/mod.rs @@ -1,6 +1,6 @@ -mod scalar; mod args; mod field; -mod object; mod interface; +mod object; +mod scalar; mod union; diff --git a/juniper/src/macros/tests/object.rs b/juniper/src/macros/tests/object.rs index f56d7a39..16b1430c 100644 --- a/juniper/src/macros/tests/object.rs +++ b/juniper/src/macros/tests/object.rs @@ -2,10 +2,10 @@ use indexmap::IndexMap; use std::marker::PhantomData; use ast::InputValue; -use value::Value; +use executor::{Context, FieldResult}; use schema::model::RootNode; use types::scalars::EmptyMutation; -use executor::{Context, FieldResult}; +use value::Value; /* @@ -250,15 +250,13 @@ fn introspect_description_first() { ); assert_eq!( object.get("interfaces"), - Some(&Value::list(vec![ - Value::object( - vec![ - ("name", Value::string("Interface")), - ("kind", Value::string("INTERFACE")), - ].into_iter() - .collect(), - ), - ])) + Some(&Value::list(vec![Value::object( + vec![ + ("name", Value::string("Interface")), + ("kind", Value::string("INTERFACE")), + ].into_iter() + .collect(), + )])) ); assert!(fields.contains(&graphql_value!({ @@ -278,15 +276,13 @@ fn introspect_fields_first() { ); assert_eq!( object.get("interfaces"), - Some(&Value::list(vec![ - Value::object( - vec![ - ("name", Value::string("Interface")), - ("kind", Value::string("INTERFACE")), - ].into_iter() - .collect(), - ), - ])) + Some(&Value::list(vec![Value::object( + vec![ + ("name", Value::string("Interface")), + ("kind", Value::string("INTERFACE")), + ].into_iter() + .collect(), + )])) ); assert!(fields.contains(&graphql_value!({ @@ -306,15 +302,13 @@ fn introspect_interfaces_first() { ); assert_eq!( object.get("interfaces"), - Some(&Value::list(vec![ - Value::object( - vec![ - ("name", Value::string("Interface")), - ("kind", Value::string("INTERFACE")), - ].into_iter() - .collect(), - ), - ])) + Some(&Value::list(vec![Value::object( + vec![ + ("name", Value::string("Interface")), + ("kind", Value::string("INTERFACE")), + ].into_iter() + .collect(), + )])) ); assert!(fields.contains(&graphql_value!({ @@ -337,15 +331,13 @@ fn introspect_commas_with_trailing() { ); assert_eq!( object.get("interfaces"), - Some(&Value::list(vec![ - Value::object( - vec![ - ("name", Value::string("Interface")), - ("kind", Value::string("INTERFACE")), - ].into_iter() - .collect(), - ), - ])) + Some(&Value::list(vec![Value::object( + vec![ + ("name", Value::string("Interface")), + ("kind", Value::string("INTERFACE")), + ].into_iter() + .collect(), + )])) ); assert!(fields.contains(&graphql_value!({ @@ -365,15 +357,13 @@ fn introspect_commas_on_meta() { ); assert_eq!( object.get("interfaces"), - Some(&Value::list(vec![ - Value::object( - vec![ - ("name", Value::string("Interface")), - ("kind", Value::string("INTERFACE")), - ].into_iter() - .collect(), - ), - ])) + Some(&Value::list(vec![Value::object( + vec![ + ("name", Value::string("Interface")), + ("kind", Value::string("INTERFACE")), + ].into_iter() + .collect(), + )])) ); assert!(fields.contains(&graphql_value!({ diff --git a/juniper/src/macros/tests/scalar.rs b/juniper/src/macros/tests/scalar.rs index 8a4af913..c7c0ef5a 100644 --- a/juniper/src/macros/tests/scalar.rs +++ b/juniper/src/macros/tests/scalar.rs @@ -1,9 +1,9 @@ use indexmap::IndexMap; use executor::Variables; -use value::Value; use schema::model::RootNode; use types::scalars::EmptyMutation; +use value::Value; struct DefaultName(i32); struct OtherOrder(i32); diff --git a/juniper/src/macros/tests/union.rs b/juniper/src/macros/tests/union.rs index 86517fb7..fd1db109 100644 --- a/juniper/src/macros/tests/union.rs +++ b/juniper/src/macros/tests/union.rs @@ -2,9 +2,9 @@ use indexmap::IndexMap; use std::marker::PhantomData; use ast::InputValue; -use value::Value; use schema::model::RootNode; use types::scalars::EmptyMutation; +use value::Value; /* @@ -162,7 +162,7 @@ fn introspect_custom_name() { possible_types.contains(&Value::object( vec![("name", Value::string("Concrete"))] .into_iter() - .collect() + .collect(), )) ); }); @@ -178,7 +178,7 @@ fn introspect_with_lifetime() { possible_types.contains(&Value::object( vec![("name", Value::string("Concrete"))] .into_iter() - .collect() + .collect(), )) ); }); @@ -194,7 +194,7 @@ fn introspect_with_generics() { possible_types.contains(&Value::object( vec![("name", Value::string("Concrete"))] .into_iter() - .collect() + .collect(), )) ); }); @@ -213,7 +213,7 @@ fn introspect_description_first() { possible_types.contains(&Value::object( vec![("name", Value::string("Concrete"))] .into_iter() - .collect() + .collect(), )) ); }); @@ -232,7 +232,7 @@ fn introspect_resolvers_first() { possible_types.contains(&Value::object( vec![("name", Value::string("Concrete"))] .into_iter() - .collect() + .collect(), )) ); }); @@ -254,7 +254,7 @@ fn introspect_commas_with_trailing() { possible_types.contains(&Value::object( vec![("name", Value::string("Concrete"))] .into_iter() - .collect() + .collect(), )) ); }); @@ -276,7 +276,7 @@ fn introspect_resolvers_with_trailing_comma() { possible_types.contains(&Value::object( vec![("name", Value::string("Concrete"))] .into_iter() - .collect() + .collect(), )) ); }); diff --git a/juniper/src/parser/document.rs b/juniper/src/parser/document.rs index 9e47cc72..d2a59a3b 100644 --- a/juniper/src/parser/document.rs +++ b/juniper/src/parser/document.rs @@ -4,9 +4,9 @@ use ast::{Arguments, Definition, Directive, Document, Field, Fragment, FragmentS InlineFragment, InputValue, Operation, OperationType, Selection, Type, VariableDefinition, VariableDefinitions}; +use parser::value::parse_value_literal; use parser::{Lexer, OptionParseResult, ParseError, ParseResult, Parser, Spanning, Token, UnlocatedParseResult}; -use parser::value::parse_value_literal; #[doc(hidden)] pub fn parse_document_source(s: &str) -> UnlocatedParseResult<Document> { diff --git a/juniper/src/parser/lexer.rs b/juniper/src/parser/lexer.rs index 2526d1c0..6be67994 100644 --- a/juniper/src/parser/lexer.rs +++ b/juniper/src/parser/lexer.rs @@ -1,8 +1,8 @@ use std::char; -use std::str::CharIndices; +use std::fmt; use std::iter::{Iterator, Peekable}; use std::result::Result; -use std::fmt; +use std::str::CharIndices; use parser::{SourcePosition, Spanning}; diff --git a/juniper/src/parser/mod.rs b/juniper/src/parser/mod.rs index 487b07b4..18676fde 100644 --- a/juniper/src/parser/mod.rs +++ b/juniper/src/parser/mod.rs @@ -1,16 +1,16 @@ //! Query parser and language utilities -mod utils; +mod document; mod lexer; mod parser; +mod utils; mod value; -mod document; #[cfg(test)] mod tests; pub use self::document::parse_document_source; -pub use self::parser::{OptionParseResult, ParseError, ParseResult, Parser, UnlocatedParseResult}; pub use self::lexer::{Lexer, LexerError, Token}; +pub use self::parser::{OptionParseResult, ParseError, ParseResult, Parser, UnlocatedParseResult}; pub use self::utils::{SourcePosition, Spanning}; diff --git a/juniper/src/parser/parser.rs b/juniper/src/parser/parser.rs index e85b5e3a..a6105c7e 100644 --- a/juniper/src/parser/parser.rs +++ b/juniper/src/parser/parser.rs @@ -1,5 +1,5 @@ -use std::result::Result; use std::fmt; +use std::result::Result; use parser::{Lexer, LexerError, Spanning, Token}; diff --git a/juniper/src/parser/tests/document.rs b/juniper/src/parser/tests/document.rs index 958942eb..6cbb618f 100644 --- a/juniper/src/parser/tests/document.rs +++ b/juniper/src/parser/tests/document.rs @@ -1,6 +1,6 @@ use ast::{Arguments, Definition, Document, Field, InputValue, Operation, OperationType, Selection}; -use parser::{ParseError, SourcePosition, Spanning, Token}; use parser::document::parse_document_source; +use parser::{ParseError, SourcePosition, Spanning, Token}; fn parse_document(s: &str) -> Document { parse_document_source(s).expect(&format!("Parse error on input {:#?}", s)) @@ -26,85 +26,79 @@ fn simple_ast() { } "# ), - vec![ - Definition::Operation(Spanning::start_end( - &SourcePosition::new(13, 1, 12), - &SourcePosition::new(124, 6, 13), - Operation { - operation_type: OperationType::Query, - name: None, - variable_definitions: None, - directives: None, - selection_set: vec![ - Selection::Field(Spanning::start_end( + vec![Definition::Operation(Spanning::start_end( + &SourcePosition::new(13, 1, 12), + &SourcePosition::new(124, 6, 13), + Operation { + operation_type: OperationType::Query, + name: None, + variable_definitions: None, + directives: None, + selection_set: vec![Selection::Field(Spanning::start_end( + &SourcePosition::new(31, 2, 16), + &SourcePosition::new(110, 5, 17), + Field { + alias: None, + name: Spanning::start_end( &SourcePosition::new(31, 2, 16), - &SourcePosition::new(110, 5, 17), - Field { - alias: None, - name: Spanning::start_end( - &SourcePosition::new(31, 2, 16), - &SourcePosition::new(35, 2, 20), - "node", - ), - arguments: Some(Spanning::start_end( - &SourcePosition::new(35, 2, 20), - &SourcePosition::new(42, 2, 27), - Arguments { - items: vec![ - ( - Spanning::start_end( - &SourcePosition::new(36, 2, 21), - &SourcePosition::new(38, 2, 23), - "id", - ), - Spanning::start_end( - &SourcePosition::new(40, 2, 25), - &SourcePosition::new(41, 2, 26), - InputValue::int(4), - ), - ), - ], - }, - )), - directives: None, - selection_set: Some(vec![ - Selection::Field(Spanning::start_end( - &SourcePosition::new(65, 3, 20), - &SourcePosition::new(67, 3, 22), - Field { - alias: None, - name: Spanning::start_end( - &SourcePosition::new(65, 3, 20), - &SourcePosition::new(67, 3, 22), - "id", - ), - arguments: None, - directives: None, - selection_set: None, - }, - )), - Selection::Field(Spanning::start_end( - &SourcePosition::new(88, 4, 20), - &SourcePosition::new(92, 4, 24), - Field { - alias: None, - name: Spanning::start_end( - &SourcePosition::new(88, 4, 20), - &SourcePosition::new(92, 4, 24), - "name", - ), - arguments: None, - directives: None, - selection_set: None, - }, - )), - ]), + &SourcePosition::new(35, 2, 20), + "node", + ), + arguments: Some(Spanning::start_end( + &SourcePosition::new(35, 2, 20), + &SourcePosition::new(42, 2, 27), + Arguments { + items: vec![( + Spanning::start_end( + &SourcePosition::new(36, 2, 21), + &SourcePosition::new(38, 2, 23), + "id", + ), + Spanning::start_end( + &SourcePosition::new(40, 2, 25), + &SourcePosition::new(41, 2, 26), + InputValue::int(4), + ), + )], }, )), - ], - }, - )), - ] + directives: None, + selection_set: Some(vec![ + Selection::Field(Spanning::start_end( + &SourcePosition::new(65, 3, 20), + &SourcePosition::new(67, 3, 22), + Field { + alias: None, + name: Spanning::start_end( + &SourcePosition::new(65, 3, 20), + &SourcePosition::new(67, 3, 22), + "id", + ), + arguments: None, + directives: None, + selection_set: None, + }, + )), + Selection::Field(Spanning::start_end( + &SourcePosition::new(88, 4, 20), + &SourcePosition::new(92, 4, 24), + Field { + alias: None, + name: Spanning::start_end( + &SourcePosition::new(88, 4, 20), + &SourcePosition::new(92, 4, 24), + "name", + ), + arguments: None, + directives: None, + selection_set: None, + }, + )), + ]), + }, + ))], + }, + ))] ) } diff --git a/juniper/src/parser/tests/lexer.rs b/juniper/src/parser/tests/lexer.rs index 4ad97ed4..59cf12f2 100644 --- a/juniper/src/parser/tests/lexer.rs +++ b/juniper/src/parser/tests/lexer.rs @@ -50,9 +50,10 @@ fn tokenize_error(s: &str) -> Spanning<LexerError> { fn empty_source() { assert_eq!( tokenize_to_vec(""), - vec![ - Spanning::zero_width(&SourcePosition::new_origin(), Token::EndOfFile), - ] + vec![Spanning::zero_width( + &SourcePosition::new_origin(), + Token::EndOfFile, + )] ); } diff --git a/juniper/src/parser/tests/value.rs b/juniper/src/parser/tests/value.rs index 2f99eba3..cc77729f 100644 --- a/juniper/src/parser/tests/value.rs +++ b/juniper/src/parser/tests/value.rs @@ -1,8 +1,8 @@ use indexmap::IndexMap; use ast::InputValue; -use parser::{Lexer, Parser, SourcePosition, Spanning}; use parser::value::parse_value_literal; +use parser::{Lexer, Parser, SourcePosition, Spanning}; fn parse_value(s: &str) -> Spanning<InputValue> { let mut lexer = Lexer::new(s); @@ -142,20 +142,18 @@ fn input_value_literals() { Spanning::start_end( &SourcePosition::new(18, 0, 18), &SourcePosition::new(30, 0, 30), - InputValue::parsed_object(vec![ - ( - Spanning::start_end( - &SourcePosition::new(19, 0, 19), - &SourcePosition::new(22, 0, 22), - "foo".to_owned(), - ), - Spanning::start_end( - &SourcePosition::new(24, 0, 24), - &SourcePosition::new(29, 0, 29), - InputValue::string("bar"), - ), + InputValue::parsed_object(vec![( + Spanning::start_end( + &SourcePosition::new(19, 0, 19), + &SourcePosition::new(22, 0, 22), + "foo".to_owned(), ), - ]), + Spanning::start_end( + &SourcePosition::new(24, 0, 24), + &SourcePosition::new(29, 0, 29), + InputValue::string("bar"), + ), + )]), ), ), ]) diff --git a/juniper/src/schema/meta.rs b/juniper/src/schema/meta.rs index cdfb4f29..ab620346 100644 --- a/juniper/src/schema/meta.rs +++ b/juniper/src/schema/meta.rs @@ -102,15 +102,24 @@ pub struct PlaceholderMeta<'a> { /// Generic type metadata #[derive(Debug)] pub enum MetaType<'a> { - #[doc(hidden)] Scalar(ScalarMeta<'a>), - #[doc(hidden)] List(ListMeta<'a>), - #[doc(hidden)] Nullable(NullableMeta<'a>), - #[doc(hidden)] Object(ObjectMeta<'a>), - #[doc(hidden)] Enum(EnumMeta<'a>), - #[doc(hidden)] Interface(InterfaceMeta<'a>), - #[doc(hidden)] Union(UnionMeta<'a>), - #[doc(hidden)] InputObject(InputObjectMeta<'a>), - #[doc(hidden)] Placeholder(PlaceholderMeta<'a>), + #[doc(hidden)] + Scalar(ScalarMeta<'a>), + #[doc(hidden)] + List(ListMeta<'a>), + #[doc(hidden)] + Nullable(NullableMeta<'a>), + #[doc(hidden)] + Object(ObjectMeta<'a>), + #[doc(hidden)] + Enum(EnumMeta<'a>), + #[doc(hidden)] + Interface(InterfaceMeta<'a>), + #[doc(hidden)] + Union(UnionMeta<'a>), + #[doc(hidden)] + InputObject(InputObjectMeta<'a>), + #[doc(hidden)] + Placeholder(PlaceholderMeta<'a>), } /// Metadata for a field diff --git a/juniper/src/schema/mod.rs b/juniper/src/schema/mod.rs index 3ec3af0d..ae361c99 100644 --- a/juniper/src/schema/mod.rs +++ b/juniper/src/schema/mod.rs @@ -1,3 +1,3 @@ +pub mod meta; pub mod model; pub mod schema; -pub mod meta; diff --git a/juniper/src/schema/model.rs b/juniper/src/schema/model.rs index 7fb57734..9e286f0a 100644 --- a/juniper/src/schema/model.rs +++ b/juniper/src/schema/model.rs @@ -2,11 +2,11 @@ use std::fmt; use fnv::FnvHashMap; +use ast::Type; +use executor::{Context, Registry}; +use schema::meta::{Argument, InterfaceMeta, MetaType, ObjectMeta, PlaceholderMeta, UnionMeta}; use types::base::GraphQLType; use types::name::Name; -use executor::{Context, Registry}; -use ast::Type; -use schema::meta::{Argument, InterfaceMeta, MetaType, ObjectMeta, PlaceholderMeta, UnionMeta}; /// Root query node of a schema /// @@ -55,9 +55,12 @@ pub enum DirectiveLocation { Query, Mutation, Field, - #[graphql(name = "FRAGMENT_DEFINITION")] FragmentDefinition, - #[graphql(name = "FRAGMENT_SPREAD")] FragmentSpread, - #[graphql(name = "INLINE_SPREAD")] InlineFragment, + #[graphql(name = "FRAGMENT_DEFINITION")] + FragmentDefinition, + #[graphql(name = "FRAGMENT_SPREAD")] + FragmentSpread, + #[graphql(name = "INLINE_SPREAD")] + InlineFragment, } impl<'a, QueryT, MutationT> RootNode<'a, QueryT, MutationT> diff --git a/juniper/src/schema/schema.rs b/juniper/src/schema/schema.rs index cfeff2d5..ce8b894e 100644 --- a/juniper/src/schema/schema.rs +++ b/juniper/src/schema/schema.rs @@ -1,5 +1,5 @@ -use types::base::{Arguments, GraphQLType, TypeKind}; use executor::{ExecutionResult, Executor, Registry}; +use types::base::{Arguments, GraphQLType, TypeKind}; use schema::meta::{Argument, EnumMeta, EnumValue, Field, InputObjectMeta, InterfaceMeta, MetaType, ObjectMeta, UnionMeta}; diff --git a/juniper/src/tests/introspection_tests.rs b/juniper/src/tests/introspection_tests.rs index 04b16d5b..6b60d351 100644 --- a/juniper/src/tests/introspection_tests.rs +++ b/juniper/src/tests/introspection_tests.rs @@ -1,10 +1,10 @@ use std::collections::HashSet; use executor::Variables; -use value::Value; use schema::model::RootNode; use tests::model::Database; use types::scalars::EmptyMutation; +use value::Value; #[test] fn test_query_type_name() { @@ -23,24 +23,18 @@ fn test_query_type_name() { ::execute(doc, None, &schema, &Variables::new(), &database), Ok(( Value::object( - vec![ - ( - "__schema", - Value::object( - vec![ - ( - "queryType", - Value::object( - vec![("name", Value::string("Query"))] - .into_iter() - .collect(), - ), - ), - ].into_iter() - .collect(), - ), + vec![( + "__schema", + Value::object( + vec![( + "queryType", + Value::object( + vec![("name", Value::string("Query"))].into_iter().collect(), + ), + )].into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect() ), vec![] @@ -63,12 +57,10 @@ fn test_specific_type_name() { ::execute(doc, None, &schema, &Variables::new(), &database), Ok(( Value::object( - vec![ - ( - "__type", - Value::object(vec![("name", Value::string("Droid"))].into_iter().collect()), - ), - ].into_iter() + vec![( + "__type", + Value::object(vec![("name", Value::string("Droid"))].into_iter().collect()), + )].into_iter() .collect() ), vec![] @@ -93,18 +85,16 @@ fn test_specific_object_type_name_and_kind() { ::execute(doc, None, &schema, &Variables::new(), &database), Ok(( Value::object( - vec![ - ( - "__type", - Value::object( - vec![ - ("name", Value::string("Droid")), - ("kind", Value::string("OBJECT")), - ].into_iter() - .collect(), - ), + vec![( + "__type", + Value::object( + vec![ + ("name", Value::string("Droid")), + ("kind", Value::string("OBJECT")), + ].into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect() ), vec![] @@ -129,18 +119,16 @@ fn test_specific_interface_type_name_and_kind() { ::execute(doc, None, &schema, &Variables::new(), &database), Ok(( Value::object( - vec![ - ( - "__type", - Value::object( - vec![ - ("name", Value::string("Character")), - ("kind", Value::string("INTERFACE")), - ].into_iter() - .collect(), - ), + vec![( + "__type", + Value::object( + vec![ + ("name", Value::string("Character")), + ("kind", Value::string("INTERFACE")), + ].into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect() ), vec![] @@ -165,23 +153,19 @@ fn test_documentation() { ::execute(doc, None, &schema, &Variables::new(), &database), Ok(( Value::object( - vec![ - ( - "__type", - Value::object( - vec![ - ("name", Value::string("Droid")), - ( - "description", - Value::string( - "A mechanical creature in the Star Wars universe.", - ), - ), - ].into_iter() - .collect(), - ), + vec![( + "__type", + Value::object( + vec![ + ("name", Value::string("Droid")), + ( + "description", + Value::string("A mechanical creature in the Star Wars universe."), + ), + ].into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect() ), vec![] diff --git a/juniper/src/tests/mod.rs b/juniper/src/tests/mod.rs index 97d01a37..e4c12df8 100644 --- a/juniper/src/tests/mod.rs +++ b/juniper/src/tests/mod.rs @@ -1,10 +1,10 @@ //! Library tests and fixtures -pub mod model; -mod schema; -#[cfg(test)] -mod query_tests; #[cfg(test)] mod introspection_tests; +pub mod model; +#[cfg(test)] +mod query_tests; +mod schema; #[cfg(test)] mod type_info_tests; diff --git a/juniper/src/tests/model.rs b/juniper/src/tests/model.rs index 570b5d0c..b0be619c 100644 --- a/juniper/src/tests/model.rs +++ b/juniper/src/tests/model.rs @@ -5,7 +5,8 @@ use std::collections::HashMap; #[derive(GraphQLEnum, Copy, Clone, Eq, PartialEq, Debug)] #[graphql(_internal)] pub enum Episode { - #[graphql(name = "NEW_HOPE")] NewHope, + #[graphql(name = "NEW_HOPE")] + NewHope, Empire, Jedi, } diff --git a/juniper/src/tests/query_tests.rs b/juniper/src/tests/query_tests.rs index 92f56d8d..1cc2154d 100644 --- a/juniper/src/tests/query_tests.rs +++ b/juniper/src/tests/query_tests.rs @@ -1,9 +1,9 @@ use ast::InputValue; use executor::Variables; -use value::Value; use schema::model::RootNode; -use types::scalars::EmptyMutation; use tests::model::Database; +use types::scalars::EmptyMutation; +use value::Value; #[test] fn test_hero_name() { @@ -20,12 +20,10 @@ fn test_hero_name() { ::execute(doc, None, &schema, &Variables::new(), &database), Ok(( Value::object( - vec![ - ( - "hero", - Value::object(vec![("name", Value::string("R2-D2"))].into_iter().collect()), - ), - ].into_iter() + vec![( + "hero", + Value::object(vec![("name", Value::string("R2-D2"))].into_iter().collect()), + )].into_iter() .collect() ), vec![] @@ -49,18 +47,16 @@ fn test_hero_field_order() { ::execute(doc, None, &schema, &Variables::new(), &database), Ok(( Value::object( - vec![ - ( - "hero", - Value::object( - vec![ - ("id", Value::string("2001")), - ("name", Value::string("R2-D2")), - ].into_iter() - .collect(), - ), + vec![( + "hero", + Value::object( + vec![ + ("id", Value::string("2001")), + ("name", Value::string("R2-D2")), + ].into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect() ), vec![] @@ -78,18 +74,16 @@ fn test_hero_field_order() { ::execute(doc_reversed, None, &schema, &Variables::new(), &database), Ok(( Value::object( - vec![ - ( - "hero", - Value::object( - vec![ - ("name", Value::string("R2-D2")), - ("id", Value::string("2001")), - ].into_iter() - .collect(), - ), + vec![( + "hero", + Value::object( + vec![ + ("name", Value::string("R2-D2")), + ("id", Value::string("2001")), + ].into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect() ), vec![] @@ -116,38 +110,36 @@ fn test_hero_name_and_friends() { ::execute(doc, None, &schema, &Variables::new(), &database), Ok(( Value::object( - vec![ - ( - "hero", - Value::object( - vec![ - ("id", Value::string("2001")), - ("name", Value::string("R2-D2")), - ( - "friends", - Value::list(vec![ - Value::object( - vec![("name", Value::string("Luke Skywalker"))] - .into_iter() - .collect(), - ), - Value::object( - vec![("name", Value::string("Han Solo"))] - .into_iter() - .collect(), - ), - Value::object( - vec![("name", Value::string("Leia Organa"))] - .into_iter() - .collect(), - ), - ]), - ), - ].into_iter() - .collect(), - ), + vec![( + "hero", + Value::object( + vec![ + ("id", Value::string("2001")), + ("name", Value::string("R2-D2")), + ( + "friends", + Value::list(vec![ + Value::object( + vec![("name", Value::string("Luke Skywalker"))] + .into_iter() + .collect(), + ), + Value::object( + vec![("name", Value::string("Han Solo"))] + .into_iter() + .collect(), + ), + Value::object( + vec![("name", Value::string("Leia Organa"))] + .into_iter() + .collect(), + ), + ]), + ), + ].into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect() ), vec![] @@ -178,153 +170,141 @@ fn test_hero_name_and_friends_and_friends_of_friends() { ::execute(doc, None, &schema, &Variables::new(), &database), Ok(( Value::object( - vec![ - ( - "hero", - Value::object( - vec![ - ("id", Value::string("2001")), - ("name", Value::string("R2-D2")), - ( - "friends", - Value::list(vec![ - Value::object( - vec![ - ("name", Value::string("Luke Skywalker")), - ( - "appearsIn", - Value::list(vec![ - Value::string("NEW_HOPE"), - Value::string("EMPIRE"), - Value::string("JEDI"), - ]), - ), - ( - "friends", - Value::list(vec![ - Value::object( - vec![ - ("name", Value::string("Han Solo")), - ].into_iter() - .collect(), - ), - Value::object( - vec![ - ( - "name", - Value::string("Leia Organa"), - ), - ].into_iter() - .collect(), - ), - Value::object( - vec![("name", Value::string("C-3PO"))] - .into_iter() - .collect(), - ), - Value::object( - vec![("name", Value::string("R2-D2"))] - .into_iter() - .collect(), - ), - ]), - ), - ].into_iter() - .collect(), - ), - Value::object( - vec![ - ("name", Value::string("Han Solo")), - ( - "appearsIn", - Value::list(vec![ - Value::string("NEW_HOPE"), - Value::string("EMPIRE"), - Value::string("JEDI"), - ]), - ), - ( - "friends", - Value::list(vec![ - Value::object( - vec![ - ( - "name", - Value::string("Luke Skywalker"), - ), - ].into_iter() - .collect(), - ), - Value::object( - vec![ - ( - "name", - Value::string("Leia Organa"), - ), - ].into_iter() - .collect(), - ), - Value::object( - vec![("name", Value::string("R2-D2"))] - .into_iter() - .collect(), - ), - ]), - ), - ].into_iter() - .collect(), - ), - Value::object( - vec![ - ("name", Value::string("Leia Organa")), - ( - "appearsIn", - Value::list(vec![ - Value::string("NEW_HOPE"), - Value::string("EMPIRE"), - Value::string("JEDI"), - ]), - ), - ( - "friends", - Value::list(vec![ - Value::object( - vec![ - ( - "name", - Value::string("Luke Skywalker"), - ), - ].into_iter() - .collect(), - ), - Value::object( - vec![ - ("name", Value::string("Han Solo")), - ].into_iter() - .collect(), - ), - Value::object( - vec![("name", Value::string("C-3PO"))] - .into_iter() - .collect(), - ), - Value::object( - vec![("name", Value::string("R2-D2"))] - .into_iter() - .collect(), - ), - ]), - ), - ].into_iter() - .collect(), - ), - ]), - ), - ].into_iter() - .collect(), - ), + vec![( + "hero", + Value::object( + vec![ + ("id", Value::string("2001")), + ("name", Value::string("R2-D2")), + ( + "friends", + Value::list(vec![ + Value::object( + vec![ + ("name", Value::string("Luke Skywalker")), + ( + "appearsIn", + Value::list(vec![ + Value::string("NEW_HOPE"), + Value::string("EMPIRE"), + Value::string("JEDI"), + ]), + ), + ( + "friends", + Value::list(vec![ + Value::object( + vec![("name", Value::string("Han Solo"))] + .into_iter() + .collect(), + ), + Value::object( + vec![( + "name", + Value::string("Leia Organa"), + )].into_iter() + .collect(), + ), + Value::object( + vec![("name", Value::string("C-3PO"))] + .into_iter() + .collect(), + ), + Value::object( + vec![("name", Value::string("R2-D2"))] + .into_iter() + .collect(), + ), + ]), + ), + ].into_iter() + .collect(), + ), + Value::object( + vec![ + ("name", Value::string("Han Solo")), + ( + "appearsIn", + Value::list(vec![ + Value::string("NEW_HOPE"), + Value::string("EMPIRE"), + Value::string("JEDI"), + ]), + ), + ( + "friends", + Value::list(vec![ + Value::object( + vec![( + "name", + Value::string("Luke Skywalker"), + )].into_iter() + .collect(), + ), + Value::object( + vec![( + "name", + Value::string("Leia Organa"), + )].into_iter() + .collect(), + ), + Value::object( + vec![("name", Value::string("R2-D2"))] + .into_iter() + .collect(), + ), + ]), + ), + ].into_iter() + .collect(), + ), + Value::object( + vec![ + ("name", Value::string("Leia Organa")), + ( + "appearsIn", + Value::list(vec![ + Value::string("NEW_HOPE"), + Value::string("EMPIRE"), + Value::string("JEDI"), + ]), + ), + ( + "friends", + Value::list(vec![ + Value::object( + vec![( + "name", + Value::string("Luke Skywalker"), + )].into_iter() + .collect(), + ), + Value::object( + vec![("name", Value::string("Han Solo"))] + .into_iter() + .collect(), + ), + Value::object( + vec![("name", Value::string("C-3PO"))] + .into_iter() + .collect(), + ), + Value::object( + vec![("name", Value::string("R2-D2"))] + .into_iter() + .collect(), + ), + ]), + ), + ].into_iter() + .collect(), + ), + ]), + ), + ].into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect() ), vec![] @@ -342,16 +322,14 @@ fn test_query_name() { ::execute(doc, None, &schema, &Variables::new(), &database), Ok(( Value::object( - vec![ - ( - "human", - Value::object( - vec![("name", Value::string("Luke Skywalker"))] - .into_iter() - .collect(), - ), + vec![( + "human", + Value::object( + vec![("name", Value::string("Luke Skywalker"))] + .into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect() ), vec![] @@ -369,16 +347,14 @@ fn test_query_alias_single() { ::execute(doc, None, &schema, &Variables::new(), &database), Ok(( Value::object( - vec![ - ( - "luke", - Value::object( - vec![("name", Value::string("Luke Skywalker"))] - .into_iter() - .collect(), - ), + vec![( + "luke", + Value::object( + vec![("name", Value::string("Luke Skywalker"))] + .into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect() ), vec![] @@ -487,16 +463,14 @@ fn test_query_name_variable() { ::execute(doc, None, &schema, &vars, &database), Ok(( Value::object( - vec![ - ( - "human", - Value::object( - vec![("name", Value::string("Luke Skywalker"))] - .into_iter() - .collect(), - ), + vec![( + "human", + Value::object( + vec![("name", Value::string("Luke Skywalker"))] + .into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect() ), vec![] @@ -533,41 +507,33 @@ fn test_query_friends_names() { ::execute(doc, None, &schema, &Variables::new(), &database), Ok(( Value::object( - vec![ - ( - "human", - Value::object( - vec![ - ( - "friends", - Value::list(vec![ - Value::object( - vec![("name", Value::string("Han Solo"))] - .into_iter() - .collect(), - ), - Value::object( - vec![("name", Value::string("Leia Organa"))] - .into_iter() - .collect(), - ), - Value::object( - vec![("name", Value::string("C-3PO"))] - .into_iter() - .collect(), - ), - Value::object( - vec![("name", Value::string("R2-D2"))] - .into_iter() - .collect(), - ), - ]), + vec![( + "human", + Value::object( + vec![( + "friends", + Value::list(vec![ + Value::object( + vec![("name", Value::string("Han Solo"))] + .into_iter() + .collect(), ), - ].into_iter() - .collect(), - ), + Value::object( + vec![("name", Value::string("Leia Organa"))] + .into_iter() + .collect(), + ), + Value::object( + vec![("name", Value::string("C-3PO"))].into_iter().collect(), + ), + Value::object( + vec![("name", Value::string("R2-D2"))].into_iter().collect(), + ), + ]), + )].into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect() ), vec![] @@ -596,19 +562,17 @@ fn test_query_inline_fragments_droid() { ::execute(doc, None, &schema, &Variables::new(), &database), Ok(( Value::object( - vec![ - ( - "hero", - Value::object( - vec![ - ("name", Value::string("R2-D2")), - ("__typename", Value::string("Droid")), - ("primaryFunction", Value::string("Astromech")), - ].into_iter() - .collect(), - ), + vec![( + "hero", + Value::object( + vec![ + ("name", Value::string("R2-D2")), + ("__typename", Value::string("Droid")), + ("primaryFunction", Value::string("Astromech")), + ].into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect() ), vec![] @@ -633,18 +597,16 @@ fn test_query_inline_fragments_human() { ::execute(doc, None, &schema, &Variables::new(), &database), Ok(( Value::object( - vec![ - ( - "hero", - Value::object( - vec![ - ("name", Value::string("Luke Skywalker")), - ("__typename", Value::string("Human")), - ].into_iter() - .collect(), - ), + vec![( + "hero", + Value::object( + vec![ + ("name", Value::string("Luke Skywalker")), + ("__typename", Value::string("Human")), + ].into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect() ), vec![] @@ -667,16 +629,14 @@ fn test_object_typename() { ::execute(doc, None, &schema, &Variables::new(), &database), Ok(( Value::object( - vec![ - ( - "human", - Value::object( - vec![("__typename", Value::string("Human"))] - .into_iter() - .collect(), - ), + vec![( + "human", + Value::object( + vec![("__typename", Value::string("Human"))] + .into_iter() + .collect(), ), - ].into_iter() + )].into_iter() .collect() ), vec![] diff --git a/juniper/src/tests/schema.rs b/juniper/src/tests/schema.rs index 86d2f6a5..a3735986 100644 --- a/juniper/src/tests/schema.rs +++ b/juniper/src/tests/schema.rs @@ -1,5 +1,5 @@ -use tests::model::{Character, Database, Droid, Episode, Human}; use executor::Context; +use tests::model::{Character, Database, Droid, Episode, Human}; impl Context for Database {} diff --git a/juniper/src/tests/type_info_tests.rs b/juniper/src/tests/type_info_tests.rs index 5856ac6e..4c0750ac 100644 --- a/juniper/src/tests/type_info_tests.rs +++ b/juniper/src/tests/type_info_tests.rs @@ -1,11 +1,11 @@ use indexmap::IndexMap; use executor::{ExecutionResult, Executor, Registry, Variables}; -use value::Value; use schema::meta::MetaType; use schema::model::RootNode; use types::base::{Arguments, GraphQLType}; use types::scalars::EmptyMutation; +use value::Value; pub struct NodeTypeInfo { name: String, diff --git a/juniper/src/types/base.rs b/juniper/src/types/base.rs index 79dae2e2..80ff52b0 100644 --- a/juniper/src/types/base.rs +++ b/juniper/src/types/base.rs @@ -1,13 +1,13 @@ -use indexmap::IndexMap; use indexmap::map::Entry; +use indexmap::IndexMap; use ast::{Directive, FromInputValue, InputValue, Selection}; use executor::Variables; use value::Value; -use schema::meta::{Argument, MetaType}; use executor::{ExecutionResult, Executor, Registry}; use parser::Spanning; +use schema::meta::{Argument, MetaType}; /// GraphQL type kind /// @@ -505,29 +505,28 @@ fn is_excluded(directives: &Option<Vec<Spanning<Directive>>>, vars: &Variables) fn merge_key_into(result: &mut IndexMap<String, Value>, response_name: &str, value: Value) { match result.entry(response_name.to_owned()) { - Entry::Occupied(mut e) => { - match e.get_mut() { - &mut Value::Object(ref mut dest_obj) => { - if let Value::Object(src_obj) = value { - merge_maps(dest_obj, src_obj); - } - }, - &mut Value::List(ref mut dest_list) => { - if let Value::List(src_list) = value { - dest_list.iter_mut().zip(src_list.into_iter()).for_each(|(d, s)| { - match d { - &mut Value::Object(ref mut d_obj) => { - if let Value::Object(s_obj) = s { - merge_maps(d_obj, s_obj); - } - }, - _ => {}, - } - }); - } - }, - _ => {} + Entry::Occupied(mut e) => match e.get_mut() { + &mut Value::Object(ref mut dest_obj) => { + if let Value::Object(src_obj) = value { + merge_maps(dest_obj, src_obj); + } } + &mut Value::List(ref mut dest_list) => { + if let Value::List(src_list) = value { + dest_list + .iter_mut() + .zip(src_list.into_iter()) + .for_each(|(d, s)| match d { + &mut Value::Object(ref mut d_obj) => { + if let Value::Object(s_obj) = s { + merge_maps(d_obj, s_obj); + } + } + _ => {} + }); + } + } + _ => {} }, Entry::Vacant(e) => { e.insert(value); diff --git a/juniper/src/types/containers.rs b/juniper/src/types/containers.rs index 94c01bb3..b47b6540 100644 --- a/juniper/src/types/containers.rs +++ b/juniper/src/types/containers.rs @@ -1,6 +1,6 @@ use ast::{FromInputValue, InputValue, Selection, ToInputValue}; -use value::Value; use schema::meta::MetaType; +use value::Value; use executor::{Executor, Registry}; use types::base::GraphQLType; diff --git a/juniper/src/types/mod.rs b/juniper/src/types/mod.rs index 5ced41f3..3780e184 100644 --- a/juniper/src/types/mod.rs +++ b/juniper/src/types/mod.rs @@ -1,6 +1,6 @@ pub mod base; -pub mod scalars; -pub mod pointers; pub mod containers; -pub mod utilities; pub mod name; +pub mod pointers; +pub mod scalars; +pub mod utilities; diff --git a/juniper/src/types/pointers.rs b/juniper/src/types/pointers.rs index ed4df3a2..f6dd0fa3 100644 --- a/juniper/src/types/pointers.rs +++ b/juniper/src/types/pointers.rs @@ -1,8 +1,8 @@ use ast::{FromInputValue, InputValue, Selection, ToInputValue}; use value::Value; -use schema::meta::MetaType; use executor::{ExecutionResult, Executor, Registry}; +use schema::meta::MetaType; use types::base::{Arguments, GraphQLType}; impl<T, CtxT> GraphQLType for Box<T> diff --git a/juniper/src/types/utilities.rs b/juniper/src/types/utilities.rs index 0638e0e5..6f6d5621 100644 --- a/juniper/src/types/utilities.rs +++ b/juniper/src/types/utilities.rs @@ -1,7 +1,7 @@ -use std::collections::HashSet; use ast::InputValue; -use schema::model::{SchemaType, TypeType}; use schema::meta::{EnumMeta, InputObjectMeta, MetaType}; +use schema::model::{SchemaType, TypeType}; +use std::collections::HashSet; pub fn is_valid_literal_value( schema: &SchemaType, diff --git a/juniper/src/validation/input_value.rs b/juniper/src/validation/input_value.rs index 377a932b..6734e1a6 100644 --- a/juniper/src/validation/input_value.rs +++ b/juniper/src/validation/input_value.rs @@ -1,12 +1,12 @@ use std::collections::HashSet; use std::fmt; -use parser::SourcePosition; use ast::{Definition, Document, InputValue, VariableDefinitions}; use executor::Variables; -use validation::RuleError; -use schema::model::{SchemaType, TypeType}; +use parser::SourcePosition; use schema::meta::{EnumMeta, InputObjectMeta, MetaType, ScalarMeta}; +use schema::model::{SchemaType, TypeType}; +use validation::RuleError; #[derive(Debug)] enum Path<'a> { diff --git a/juniper/src/validation/mod.rs b/juniper/src/validation/mod.rs index 6c5c9fd1..a7adae53 100644 --- a/juniper/src/validation/mod.rs +++ b/juniper/src/validation/mod.rs @@ -1,21 +1,21 @@ //! Query validation related methods and data structures -mod visitor; -mod traits; mod context; +mod input_value; mod multi_visitor; mod rules; -mod input_value; +mod traits; +mod visitor; #[cfg(test)] mod test_harness; +pub use self::context::{RuleError, ValidatorContext}; +pub use self::input_value::validate_input_values; +pub use self::multi_visitor::{MultiVisitor, MultiVisitorNil}; +pub use self::rules::visit_all_rules; pub use self::traits::Visitor; pub use self::visitor::visit; -pub use self::context::{RuleError, ValidatorContext}; -pub use self::rules::visit_all_rules; -pub use self::multi_visitor::{MultiVisitor, MultiVisitorNil}; -pub use self::input_value::validate_input_values; #[cfg(test)] pub use self::test_harness::{expect_fails_rule, expect_fails_rule_with_schema, expect_passes_rule, diff --git a/juniper/src/validation/rules/arguments_of_correct_type.rs b/juniper/src/validation/rules/arguments_of_correct_type.rs index b26e972d..25b53303 100644 --- a/juniper/src/validation/rules/arguments_of_correct_type.rs +++ b/juniper/src/validation/rules/arguments_of_correct_type.rs @@ -1,7 +1,7 @@ use ast::{Directive, Field, InputValue}; +use parser::Spanning; use schema::meta::Argument; use types::utilities::is_valid_literal_value; -use parser::Spanning; use validation::{ValidatorContext, Visitor}; pub struct ArgumentsOfCorrectType<'a> { @@ -96,12 +96,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("nonNullIntArg", "Int!"), - &[SourcePosition::new(97, 3, 50)], - ), - ], + &[RuleError::new( + &error_message("nonNullIntArg", "Int!"), + &[SourcePosition::new(97, 3, 50)], + )], ); } @@ -228,12 +226,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("stringArg", "String"), - &[SourcePosition::new(89, 3, 42)], - ), - ], + &[RuleError::new( + &error_message("stringArg", "String"), + &[SourcePosition::new(89, 3, 42)], + )], ); } @@ -248,12 +244,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("stringArg", "String"), - &[SourcePosition::new(89, 3, 42)], - ), - ], + &[RuleError::new( + &error_message("stringArg", "String"), + &[SourcePosition::new(89, 3, 42)], + )], ); } @@ -268,12 +262,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("stringArg", "String"), - &[SourcePosition::new(89, 3, 42)], - ), - ], + &[RuleError::new( + &error_message("stringArg", "String"), + &[SourcePosition::new(89, 3, 42)], + )], ); } @@ -288,12 +280,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("stringArg", "String"), - &[SourcePosition::new(89, 3, 42)], - ), - ], + &[RuleError::new( + &error_message("stringArg", "String"), + &[SourcePosition::new(89, 3, 42)], + )], ); } @@ -308,12 +298,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("intArg", "Int"), - &[SourcePosition::new(83, 3, 36)], - ), - ], + &[RuleError::new( + &error_message("intArg", "Int"), + &[SourcePosition::new(83, 3, 36)], + )], ); } @@ -328,12 +316,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("intArg", "Int"), - &[SourcePosition::new(83, 3, 36)], - ), - ], + &[RuleError::new( + &error_message("intArg", "Int"), + &[SourcePosition::new(83, 3, 36)], + )], ); } @@ -348,12 +334,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("intArg", "Int"), - &[SourcePosition::new(83, 3, 36)], - ), - ], + &[RuleError::new( + &error_message("intArg", "Int"), + &[SourcePosition::new(83, 3, 36)], + )], ); } @@ -368,12 +352,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("intArg", "Int"), - &[SourcePosition::new(83, 3, 36)], - ), - ], + &[RuleError::new( + &error_message("intArg", "Int"), + &[SourcePosition::new(83, 3, 36)], + )], ); } @@ -388,12 +370,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("floatArg", "Float"), - &[SourcePosition::new(87, 3, 40)], - ), - ], + &[RuleError::new( + &error_message("floatArg", "Float"), + &[SourcePosition::new(87, 3, 40)], + )], ); } @@ -408,12 +388,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("floatArg", "Float"), - &[SourcePosition::new(87, 3, 40)], - ), - ], + &[RuleError::new( + &error_message("floatArg", "Float"), + &[SourcePosition::new(87, 3, 40)], + )], ); } @@ -428,12 +406,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("floatArg", "Float"), - &[SourcePosition::new(87, 3, 40)], - ), - ], + &[RuleError::new( + &error_message("floatArg", "Float"), + &[SourcePosition::new(87, 3, 40)], + )], ); } @@ -448,12 +424,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("booleanArg", "Boolean"), - &[SourcePosition::new(91, 3, 44)], - ), - ], + &[RuleError::new( + &error_message("booleanArg", "Boolean"), + &[SourcePosition::new(91, 3, 44)], + )], ); } @@ -468,12 +442,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("booleanArg", "Boolean"), - &[SourcePosition::new(91, 3, 44)], - ), - ], + &[RuleError::new( + &error_message("booleanArg", "Boolean"), + &[SourcePosition::new(91, 3, 44)], + )], ); } @@ -488,12 +460,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("booleanArg", "Boolean"), - &[SourcePosition::new(91, 3, 44)], - ), - ], + &[RuleError::new( + &error_message("booleanArg", "Boolean"), + &[SourcePosition::new(91, 3, 44)], + )], ); } @@ -508,12 +478,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("booleanArg", "Boolean"), - &[SourcePosition::new(91, 3, 44)], - ), - ], + &[RuleError::new( + &error_message("booleanArg", "Boolean"), + &[SourcePosition::new(91, 3, 44)], + )], ); } @@ -528,12 +496,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("idArg", "ID"), - &[SourcePosition::new(81, 3, 34)], - ), - ], + &[RuleError::new( + &error_message("idArg", "ID"), + &[SourcePosition::new(81, 3, 34)], + )], ); } @@ -548,12 +514,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("idArg", "ID"), - &[SourcePosition::new(81, 3, 34)], - ), - ], + &[RuleError::new( + &error_message("idArg", "ID"), + &[SourcePosition::new(81, 3, 34)], + )], ); } @@ -568,12 +532,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("idArg", "ID"), - &[SourcePosition::new(81, 3, 34)], - ), - ], + &[RuleError::new( + &error_message("idArg", "ID"), + &[SourcePosition::new(81, 3, 34)], + )], ); } @@ -588,12 +550,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("dogCommand", "DogCommand"), - &[SourcePosition::new(79, 3, 44)], - ), - ], + &[RuleError::new( + &error_message("dogCommand", "DogCommand"), + &[SourcePosition::new(79, 3, 44)], + )], ); } @@ -608,12 +568,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("dogCommand", "DogCommand"), - &[SourcePosition::new(79, 3, 44)], - ), - ], + &[RuleError::new( + &error_message("dogCommand", "DogCommand"), + &[SourcePosition::new(79, 3, 44)], + )], ); } @@ -628,12 +586,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("dogCommand", "DogCommand"), - &[SourcePosition::new(79, 3, 44)], - ), - ], + &[RuleError::new( + &error_message("dogCommand", "DogCommand"), + &[SourcePosition::new(79, 3, 44)], + )], ); } @@ -648,12 +604,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("dogCommand", "DogCommand"), - &[SourcePosition::new(79, 3, 44)], - ), - ], + &[RuleError::new( + &error_message("dogCommand", "DogCommand"), + &[SourcePosition::new(79, 3, 44)], + )], ); } @@ -668,12 +622,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("dogCommand", "DogCommand"), - &[SourcePosition::new(79, 3, 44)], - ), - ], + &[RuleError::new( + &error_message("dogCommand", "DogCommand"), + &[SourcePosition::new(79, 3, 44)], + )], ); } @@ -688,12 +640,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("dogCommand", "DogCommand"), - &[SourcePosition::new(79, 3, 44)], - ), - ], + &[RuleError::new( + &error_message("dogCommand", "DogCommand"), + &[SourcePosition::new(79, 3, 44)], + )], ); } @@ -750,12 +700,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("stringListArg", "[String]"), - &[SourcePosition::new(97, 3, 50)], - ), - ], + &[RuleError::new( + &error_message("stringListArg", "[String]"), + &[SourcePosition::new(97, 3, 50)], + )], ); } @@ -770,12 +718,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("stringListArg", "[String]"), - &[SourcePosition::new(97, 3, 50)], - ), - ], + &[RuleError::new( + &error_message("stringListArg", "[String]"), + &[SourcePosition::new(97, 3, 50)], + )], ); } @@ -954,12 +900,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("req1", "Int!"), - &[SourcePosition::new(82, 3, 35)], - ), - ], + &[RuleError::new( + &error_message("req1", "Int!"), + &[SourcePosition::new(82, 3, 35)], + )], ); } @@ -1070,12 +1014,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("complexArg", "ComplexInput"), - &[SourcePosition::new(91, 3, 44)], - ), - ], + &[RuleError::new( + &error_message("complexArg", "ComplexInput"), + &[SourcePosition::new(91, 3, 44)], + )], ); } @@ -1093,12 +1035,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("complexArg", "ComplexInput"), - &[SourcePosition::new(91, 3, 44)], - ), - ], + &[RuleError::new( + &error_message("complexArg", "ComplexInput"), + &[SourcePosition::new(91, 3, 44)], + )], ); } @@ -1116,12 +1056,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("complexArg", "ComplexInput"), - &[SourcePosition::new(91, 3, 44)], - ), - ], + &[RuleError::new( + &error_message("complexArg", "ComplexInput"), + &[SourcePosition::new(91, 3, 44)], + )], ); } diff --git a/juniper/src/validation/rules/default_values_of_correct_type.rs b/juniper/src/validation/rules/default_values_of_correct_type.rs index e8d76337..5fd14eb2 100644 --- a/juniper/src/validation/rules/default_values_of_correct_type.rs +++ b/juniper/src/validation/rules/default_values_of_correct_type.rs @@ -1,6 +1,6 @@ use ast::VariableDefinition; -use types::utilities::is_valid_literal_value; use parser::Spanning; +use types::utilities::is_valid_literal_value; use validation::{ValidatorContext, Visitor}; pub struct DefaultValuesOfCorrectType {} @@ -162,12 +162,10 @@ mod tests { dog { name } } "#, - &[ - RuleError::new( - &type_error_message("a", "ComplexInput"), - &[SourcePosition::new(57, 1, 56)], - ), - ], + &[RuleError::new( + &type_error_message("a", "ComplexInput"), + &[SourcePosition::new(57, 1, 56)], + )], ); } @@ -180,12 +178,10 @@ mod tests { dog { name } } "#, - &[ - RuleError::new( - &type_error_message("a", "[String]"), - &[SourcePosition::new(44, 1, 43)], - ), - ], + &[RuleError::new( + &type_error_message("a", "[String]"), + &[SourcePosition::new(44, 1, 43)], + )], ); } diff --git a/juniper/src/validation/rules/fields_on_correct_type.rs b/juniper/src/validation/rules/fields_on_correct_type.rs index 9873417a..ecb93307 100644 --- a/juniper/src/validation/rules/fields_on_correct_type.rs +++ b/juniper/src/validation/rules/fields_on_correct_type.rs @@ -1,7 +1,7 @@ use ast::Field; +use parser::Spanning; use schema::meta::MetaType; use validation::{ValidatorContext, Visitor}; -use parser::Spanning; pub struct FieldsOnCorrectType {} @@ -160,12 +160,10 @@ mod tests { meowVolume } "#, - &[ - RuleError::new( - &error_message("meowVolume", "Dog"), - &[SourcePosition::new(57, 2, 12)], - ), - ], + &[RuleError::new( + &error_message("meowVolume", "Dog"), + &[SourcePosition::new(57, 2, 12)], + )], ); } @@ -180,12 +178,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("unknown_field", "Dog"), - &[SourcePosition::new(61, 2, 12)], - ), - ], + &[RuleError::new( + &error_message("unknown_field", "Dog"), + &[SourcePosition::new(61, 2, 12)], + )], ); } @@ -200,12 +196,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("unknown_field", "Pet"), - &[SourcePosition::new(83, 3, 14)], - ), - ], + &[RuleError::new( + &error_message("unknown_field", "Pet"), + &[SourcePosition::new(83, 3, 14)], + )], ); } @@ -220,12 +214,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("meowVolume", "Dog"), - &[SourcePosition::new(84, 3, 14)], - ), - ], + &[RuleError::new( + &error_message("meowVolume", "Dog"), + &[SourcePosition::new(84, 3, 14)], + )], ); } @@ -238,12 +230,10 @@ mod tests { volume : mooVolume } "#, - &[ - RuleError::new( - &error_message("mooVolume", "Dog"), - &[SourcePosition::new(79, 2, 21)], - ), - ], + &[RuleError::new( + &error_message("mooVolume", "Dog"), + &[SourcePosition::new(79, 2, 21)], + )], ); } @@ -256,12 +246,10 @@ mod tests { barkVolume : kawVolume } "#, - &[ - RuleError::new( - &error_message("kawVolume", "Dog"), - &[SourcePosition::new(88, 2, 25)], - ), - ], + &[RuleError::new( + &error_message("kawVolume", "Dog"), + &[SourcePosition::new(88, 2, 25)], + )], ); } @@ -274,12 +262,10 @@ mod tests { tailLength } "#, - &[ - RuleError::new( - &error_message("tailLength", "Pet"), - &[SourcePosition::new(63, 2, 12)], - ), - ], + &[RuleError::new( + &error_message("tailLength", "Pet"), + &[SourcePosition::new(63, 2, 12)], + )], ); } @@ -292,12 +278,10 @@ mod tests { nickname } "#, - &[ - RuleError::new( - &error_message("nickname", "Pet"), - &[SourcePosition::new(78, 2, 12)], - ), - ], + &[RuleError::new( + &error_message("nickname", "Pet"), + &[SourcePosition::new(78, 2, 12)], + )], ); } @@ -322,12 +306,10 @@ mod tests { name } "#, - &[ - RuleError::new( - &error_message("name", "CatOrDog"), - &[SourcePosition::new(82, 2, 12)], - ), - ], + &[RuleError::new( + &error_message("name", "CatOrDog"), + &[SourcePosition::new(82, 2, 12)], + )], ); } diff --git a/juniper/src/validation/rules/fragments_on_composite_types.rs b/juniper/src/validation/rules/fragments_on_composite_types.rs index 5b113d19..aac5c12e 100644 --- a/juniper/src/validation/rules/fragments_on_composite_types.rs +++ b/juniper/src/validation/rules/fragments_on_composite_types.rs @@ -145,12 +145,10 @@ mod tests { bad } "#, - &[ - RuleError::new( - &error_message(Some("scalarFragment"), "Boolean"), - &[SourcePosition::new(38, 1, 37)], - ), - ], + &[RuleError::new( + &error_message(Some("scalarFragment"), "Boolean"), + &[SourcePosition::new(38, 1, 37)], + )], ); } @@ -163,12 +161,10 @@ mod tests { bad } "#, - &[ - RuleError::new( - &error_message(Some("scalarFragment"), "FurColor"), - &[SourcePosition::new(38, 1, 37)], - ), - ], + &[RuleError::new( + &error_message(Some("scalarFragment"), "FurColor"), + &[SourcePosition::new(38, 1, 37)], + )], ); } @@ -181,12 +177,10 @@ mod tests { stringField } "#, - &[ - RuleError::new( - &error_message(Some("inputFragment"), "ComplexInput"), - &[SourcePosition::new(37, 1, 36)], - ), - ], + &[RuleError::new( + &error_message(Some("inputFragment"), "ComplexInput"), + &[SourcePosition::new(37, 1, 36)], + )], ); } @@ -201,12 +195,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message(None, "String"), - &[SourcePosition::new(64, 2, 19)], - ), - ], + &[RuleError::new( + &error_message(None, "String"), + &[SourcePosition::new(64, 2, 19)], + )], ); } } diff --git a/juniper/src/validation/rules/known_argument_names.rs b/juniper/src/validation/rules/known_argument_names.rs index 7b77e713..cd136eba 100644 --- a/juniper/src/validation/rules/known_argument_names.rs +++ b/juniper/src/validation/rules/known_argument_names.rs @@ -1,6 +1,6 @@ use ast::{Directive, Field, InputValue}; -use schema::meta::Argument; use parser::Spanning; +use schema::meta::Argument; use validation::{ValidatorContext, Visitor}; #[derive(Debug)] @@ -204,12 +204,10 @@ mod tests { dog @skip(unless: true) } "#, - &[ - RuleError::new( - &directive_error_message("unless", "skip"), - &[SourcePosition::new(35, 2, 22)], - ), - ], + &[RuleError::new( + &directive_error_message("unless", "skip"), + &[SourcePosition::new(35, 2, 22)], + )], ); } @@ -222,12 +220,10 @@ mod tests { doesKnowCommand(unknown: true) } "#, - &[ - RuleError::new( - &field_error_message("unknown", "doesKnowCommand", "Dog"), - &[SourcePosition::new(72, 2, 28)], - ), - ], + &[RuleError::new( + &field_error_message("unknown", "doesKnowCommand", "Dog"), + &[SourcePosition::new(72, 2, 28)], + )], ); } diff --git a/juniper/src/validation/rules/known_directives.rs b/juniper/src/validation/rules/known_directives.rs index 2c06b8f0..b5765df9 100644 --- a/juniper/src/validation/rules/known_directives.rs +++ b/juniper/src/validation/rules/known_directives.rs @@ -1,7 +1,7 @@ use ast::{Directive, Field, Fragment, FragmentSpread, InlineFragment, Operation, OperationType}; -use validation::{ValidatorContext, Visitor}; -use schema::model::DirectiveLocation; use parser::Spanning; +use schema::model::DirectiveLocation; +use validation::{ValidatorContext, Visitor}; pub struct KnownDirectives { location_stack: Vec<DirectiveLocation>, @@ -141,8 +141,8 @@ mod tests { use super::{factory, misplaced_error_message, unknown_error_message}; use parser::SourcePosition; - use validation::{expect_fails_rule, expect_passes_rule, RuleError}; use schema::model::DirectiveLocation; + use validation::{expect_fails_rule, expect_passes_rule, RuleError}; #[test] fn with_no_directives() { @@ -189,12 +189,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &unknown_error_message("unknown"), - &[SourcePosition::new(29, 2, 16)], - ), - ], + &[RuleError::new( + &unknown_error_message("unknown"), + &[SourcePosition::new(29, 2, 16)], + )], ); } diff --git a/juniper/src/validation/rules/known_fragment_names.rs b/juniper/src/validation/rules/known_fragment_names.rs index 2b767f7c..f91afc8f 100644 --- a/juniper/src/validation/rules/known_fragment_names.rs +++ b/juniper/src/validation/rules/known_fragment_names.rs @@ -1,6 +1,6 @@ use ast::FragmentSpread; -use validation::{ValidatorContext, Visitor}; use parser::Spanning; +use validation::{ValidatorContext, Visitor}; pub struct KnownFragmentNames {} diff --git a/juniper/src/validation/rules/known_type_names.rs b/juniper/src/validation/rules/known_type_names.rs index b71ebeb5..9db2c2db 100644 --- a/juniper/src/validation/rules/known_type_names.rs +++ b/juniper/src/validation/rules/known_type_names.rs @@ -1,6 +1,6 @@ use ast::{Fragment, InlineFragment, VariableDefinition}; -use validation::{ValidatorContext, Visitor}; use parser::{SourcePosition, Spanning}; +use validation::{ValidatorContext, Visitor}; pub struct KnownTypeNames {} diff --git a/juniper/src/validation/rules/lone_anonymous_operation.rs b/juniper/src/validation/rules/lone_anonymous_operation.rs index e7c88ba8..e3ce8d6b 100644 --- a/juniper/src/validation/rules/lone_anonymous_operation.rs +++ b/juniper/src/validation/rules/lone_anonymous_operation.rs @@ -1,6 +1,6 @@ use ast::{Definition, Document, Operation}; -use validation::{ValidatorContext, Visitor}; use parser::Spanning; +use validation::{ValidatorContext, Visitor}; pub struct LoneAnonymousOperation { operation_count: Option<usize>, @@ -134,9 +134,10 @@ mod tests { fieldB } "#, - &[ - RuleError::new(error_message(), &[SourcePosition::new(11, 1, 10)]), - ], + &[RuleError::new( + error_message(), + &[SourcePosition::new(11, 1, 10)], + )], ); } } diff --git a/juniper/src/validation/rules/no_fragment_cycles.rs b/juniper/src/validation/rules/no_fragment_cycles.rs index 1604648f..2e397e40 100644 --- a/juniper/src/validation/rules/no_fragment_cycles.rs +++ b/juniper/src/validation/rules/no_fragment_cycles.rs @@ -1,8 +1,8 @@ use std::collections::{HashMap, HashSet}; use ast::{Document, Fragment, FragmentSpread}; -use validation::{RuleError, ValidatorContext, Visitor}; use parser::Spanning; +use validation::{RuleError, ValidatorContext, Visitor}; pub struct NoFragmentCycles<'a> { current_fragment: Option<&'a str>, @@ -203,9 +203,10 @@ mod tests { r#" fragment fragA on Human { relatives { ...fragA } }, "#, - &[ - RuleError::new(&error_message("fragA"), &[SourcePosition::new(49, 1, 48)]), - ], + &[RuleError::new( + &error_message("fragA"), + &[SourcePosition::new(49, 1, 48)], + )], ); } @@ -216,9 +217,10 @@ mod tests { r#" fragment fragA on Dog { ...fragA } "#, - &[ - RuleError::new(&error_message("fragA"), &[SourcePosition::new(35, 1, 34)]), - ], + &[RuleError::new( + &error_message("fragA"), + &[SourcePosition::new(35, 1, 34)], + )], ); } @@ -233,9 +235,10 @@ mod tests { } } "#, - &[ - RuleError::new(&error_message("fragA"), &[SourcePosition::new(74, 3, 14)]), - ], + &[RuleError::new( + &error_message("fragA"), + &[SourcePosition::new(74, 3, 14)], + )], ); } @@ -247,9 +250,10 @@ mod tests { fragment fragA on Dog { ...fragB } fragment fragB on Dog { ...fragA } "#, - &[ - RuleError::new(&error_message("fragA"), &[SourcePosition::new(35, 1, 34)]), - ], + &[RuleError::new( + &error_message("fragA"), + &[SourcePosition::new(35, 1, 34)], + )], ); } @@ -261,9 +265,10 @@ mod tests { fragment fragB on Dog { ...fragA } fragment fragA on Dog { ...fragB } "#, - &[ - RuleError::new(&error_message("fragB"), &[SourcePosition::new(35, 1, 34)]), - ], + &[RuleError::new( + &error_message("fragB"), + &[SourcePosition::new(35, 1, 34)], + )], ); } @@ -283,9 +288,10 @@ mod tests { } } "#, - &[ - RuleError::new(&error_message("fragA"), &[SourcePosition::new(74, 3, 14)]), - ], + &[RuleError::new( + &error_message("fragA"), + &[SourcePosition::new(74, 3, 14)], + )], ); } diff --git a/juniper/src/validation/rules/no_undefined_variables.rs b/juniper/src/validation/rules/no_undefined_variables.rs index 2b00d3c4..66c82a5c 100644 --- a/juniper/src/validation/rules/no_undefined_variables.rs +++ b/juniper/src/validation/rules/no_undefined_variables.rs @@ -1,7 +1,7 @@ -use std::collections::{HashMap, HashSet}; use ast::{Document, Fragment, FragmentSpread, InputValue, Operation, VariableDefinition}; -use validation::{RuleError, ValidatorContext, Visitor}; use parser::{SourcePosition, Spanning}; +use std::collections::{HashMap, HashSet}; +use validation::{RuleError, ValidatorContext, Visitor}; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Scope<'a> { @@ -302,15 +302,13 @@ mod tests { field(a: $a, b: $b, c: $c, d: $d) } "#, - &[ - RuleError::new( - &error_message("d", Some("Foo")), - &[ - SourcePosition::new(101, 2, 42), - SourcePosition::new(11, 1, 10), - ], - ), - ], + &[RuleError::new( + &error_message("d", Some("Foo")), + &[ + SourcePosition::new(101, 2, 42), + SourcePosition::new(11, 1, 10), + ], + )], ); } @@ -323,15 +321,13 @@ mod tests { field(a: $a) } "#, - &[ - RuleError::new( - &error_message("a", None), - &[ - SourcePosition::new(34, 2, 21), - SourcePosition::new(11, 1, 10), - ], - ), - ], + &[RuleError::new( + &error_message("a", None), + &[ + SourcePosition::new(34, 2, 21), + SourcePosition::new(11, 1, 10), + ], + )], ); } @@ -375,15 +371,13 @@ mod tests { field(a: $a) } "#, - &[ - RuleError::new( - &error_message("a", None), - &[ - SourcePosition::new(102, 5, 21), - SourcePosition::new(11, 1, 10), - ], - ), - ], + &[RuleError::new( + &error_message("a", None), + &[ + SourcePosition::new(102, 5, 21), + SourcePosition::new(11, 1, 10), + ], + )], ); } @@ -409,15 +403,13 @@ mod tests { field(c: $c) } "#, - &[ - RuleError::new( - &error_message("c", Some("Foo")), - &[ - SourcePosition::new(358, 15, 21), - SourcePosition::new(11, 1, 10), - ], - ), - ], + &[RuleError::new( + &error_message("c", Some("Foo")), + &[ + SourcePosition::new(358, 15, 21), + SourcePosition::new(11, 1, 10), + ], + )], ); } diff --git a/juniper/src/validation/rules/no_unused_fragments.rs b/juniper/src/validation/rules/no_unused_fragments.rs index 2fadefc9..0242fec0 100644 --- a/juniper/src/validation/rules/no_unused_fragments.rs +++ b/juniper/src/validation/rules/no_unused_fragments.rs @@ -1,8 +1,8 @@ use std::collections::{HashMap, HashSet}; use ast::{Definition, Document, Fragment, FragmentSpread, Operation}; -use validation::{ValidatorContext, Visitor}; use parser::Spanning; +use validation::{ValidatorContext, Visitor}; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Scope<'a> { @@ -270,9 +270,10 @@ mod tests { name } "#, - &[ - RuleError::new(&error_message("foo"), &[SourcePosition::new(107, 6, 10)]), - ], + &[RuleError::new( + &error_message("foo"), + &[SourcePosition::new(107, 6, 10)], + )], ); } } diff --git a/juniper/src/validation/rules/no_unused_variables.rs b/juniper/src/validation/rules/no_unused_variables.rs index 7573f9da..8e7caa6f 100644 --- a/juniper/src/validation/rules/no_unused_variables.rs +++ b/juniper/src/validation/rules/no_unused_variables.rs @@ -1,7 +1,7 @@ -use std::collections::{HashMap, HashSet}; use ast::{Document, Fragment, FragmentSpread, InputValue, Operation, VariableDefinition}; -use validation::{RuleError, ValidatorContext, Visitor}; use parser::Spanning; +use std::collections::{HashMap, HashSet}; +use validation::{RuleError, ValidatorContext, Visitor}; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Scope<'a> { @@ -274,9 +274,10 @@ mod tests { field(a: $a, b: $b) } "#, - &[ - RuleError::new(&error_message("c", None), &[SourcePosition::new(42, 1, 41)]), - ], + &[RuleError::new( + &error_message("c", None), + &[SourcePosition::new(42, 1, 41)], + )], ); } @@ -324,12 +325,10 @@ mod tests { field } "#, - &[ - RuleError::new( - &error_message("c", Some("Foo")), - &[SourcePosition::new(45, 1, 44)], - ), - ], + &[RuleError::new( + &error_message("c", Some("Foo")), + &[SourcePosition::new(45, 1, 44)], + )], ); } @@ -383,12 +382,10 @@ mod tests { field(b: $b) } "#, - &[ - RuleError::new( - &error_message("b", Some("Foo")), - &[SourcePosition::new(21, 1, 20)], - ), - ], + &[RuleError::new( + &error_message("b", Some("Foo")), + &[SourcePosition::new(21, 1, 20)], + )], ); } diff --git a/juniper/src/validation/rules/overlapping_fields_can_be_merged.rs b/juniper/src/validation/rules/overlapping_fields_can_be_merged.rs index 9920440f..1ddeab94 100644 --- a/juniper/src/validation/rules/overlapping_fields_can_be_merged.rs +++ b/juniper/src/validation/rules/overlapping_fields_can_be_merged.rs @@ -1,11 +1,11 @@ -use std::collections::HashMap; -use std::cell::RefCell; -use std::hash::Hash; -use std::borrow::Borrow; use ast::{Arguments, Definition, Document, Field, Fragment, FragmentSpread, Selection, Type}; -use validation::{ValidatorContext, Visitor}; use parser::{SourcePosition, Spanning}; use schema::meta::{Field as FieldType, MetaType}; +use std::borrow::Borrow; +use std::cell::RefCell; +use std::collections::HashMap; +use std::hash::Hash; +use validation::{ValidatorContext, Visitor}; #[derive(Debug)] struct Conflict(ConflictReason, Vec<SourcePosition>, Vec<SourcePosition>); @@ -708,13 +708,13 @@ fn format_reason(reason: &ConflictReasonMessage) -> String { #[cfg(test)] mod tests { - use super::{error_message, factory, ConflictReason}; use super::ConflictReasonMessage::*; + use super::{error_message, factory, ConflictReason}; - use types::base::GraphQLType; use executor::Registry; - use types::scalars::ID; use schema::meta::MetaType; + use types::base::GraphQLType; + use types::scalars::ID; use parser::SourcePosition; use validation::{expect_fails_rule, expect_fails_rule_with_schema, expect_passes_rule, @@ -821,18 +821,16 @@ mod tests { fido: nickname } "#, - &[ - RuleError::new( - &error_message( - "fido", - &Message("name and nickname are different fields".to_owned()), - ), - &[ - SourcePosition::new(78, 2, 12), - SourcePosition::new(101, 3, 12), - ], + &[RuleError::new( + &error_message( + "fido", + &Message("name and nickname are different fields".to_owned()), ), - ], + &[ + SourcePosition::new(78, 2, 12), + SourcePosition::new(101, 3, 12), + ], + )], ); } @@ -863,18 +861,16 @@ mod tests { name } "#, - &[ - RuleError::new( - &error_message( - "name", - &Message("nickname and name are different fields".to_owned()), - ), - &[ - SourcePosition::new(71, 2, 12), - SourcePosition::new(98, 3, 12), - ], + &[RuleError::new( + &error_message( + "name", + &Message("nickname and name are different fields".to_owned()), ), - ], + &[ + SourcePosition::new(71, 2, 12), + SourcePosition::new(98, 3, 12), + ], + )], ); } @@ -888,18 +884,16 @@ mod tests { doesKnowCommand(dogCommand: HEEL) } "#, - &[ - RuleError::new( - &error_message( - "doesKnowCommand", - &Message("they have differing arguments".to_owned()), - ), - &[ - SourcePosition::new(57, 2, 12), - SourcePosition::new(85, 3, 12), - ], + &[RuleError::new( + &error_message( + "doesKnowCommand", + &Message("they have differing arguments".to_owned()), ), - ], + &[ + SourcePosition::new(57, 2, 12), + SourcePosition::new(85, 3, 12), + ], + )], ); } @@ -913,18 +907,16 @@ mod tests { doesKnowCommand } "#, - &[ - RuleError::new( - &error_message( - "doesKnowCommand", - &Message("they have differing arguments".to_owned()), - ), - &[ - SourcePosition::new(57, 2, 12), - SourcePosition::new(102, 3, 12), - ], + &[RuleError::new( + &error_message( + "doesKnowCommand", + &Message("they have differing arguments".to_owned()), ), - ], + &[ + SourcePosition::new(57, 2, 12), + SourcePosition::new(102, 3, 12), + ], + )], ); } @@ -938,18 +930,16 @@ mod tests { doesKnowCommand(dogCommand: HEEL) } "#, - &[ - RuleError::new( - &error_message( - "doesKnowCommand", - &Message("they have differing arguments".to_owned()), - ), - &[ - SourcePosition::new(57, 2, 12), - SourcePosition::new(102, 3, 12), - ], + &[RuleError::new( + &error_message( + "doesKnowCommand", + &Message("they have differing arguments".to_owned()), ), - ], + &[ + SourcePosition::new(57, 2, 12), + SourcePosition::new(102, 3, 12), + ], + )], ); } @@ -986,15 +976,13 @@ mod tests { x: b } "#, - &[ - RuleError::new( - &error_message("x", &Message("a and b are different fields".to_owned())), - &[ - SourcePosition::new(102, 6, 12), - SourcePosition::new(162, 9, 12), - ], - ), - ], + &[RuleError::new( + &error_message("x", &Message("a and b are different fields".to_owned())), + &[ + SourcePosition::new(102, 6, 12), + SourcePosition::new(162, 9, 12), + ], + )], ); } @@ -1065,25 +1053,21 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message( - "field", - &Nested(vec![ - ConflictReason( - "x".to_owned(), - Message("a and b are different fields".to_owned()), - ), - ]), - ), - &[ - SourcePosition::new(25, 2, 12), - SourcePosition::new(47, 3, 14), - SourcePosition::new(79, 5, 12), - SourcePosition::new(101, 6, 14), - ], + &[RuleError::new( + &error_message( + "field", + &Nested(vec![ConflictReason( + "x".to_owned(), + Message("a and b are different fields".to_owned()), + )]), ), - ], + &[ + SourcePosition::new(25, 2, 12), + SourcePosition::new(47, 3, 14), + SourcePosition::new(79, 5, 12), + SourcePosition::new(101, 6, 14), + ], + )], ); } @@ -1103,31 +1087,29 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message( - "field", - &Nested(vec![ - ConflictReason( - "x".to_owned(), - Message("a and b are different fields".to_owned()), - ), - ConflictReason( - "y".to_owned(), - Message("c and d are different fields".to_owned()), - ), - ]), - ), - &[ - SourcePosition::new(25, 2, 12), - SourcePosition::new(47, 3, 14), - SourcePosition::new(66, 4, 14), - SourcePosition::new(98, 6, 12), - SourcePosition::new(120, 7, 14), - SourcePosition::new(139, 8, 14), - ], + &[RuleError::new( + &error_message( + "field", + &Nested(vec![ + ConflictReason( + "x".to_owned(), + Message("a and b are different fields".to_owned()), + ), + ConflictReason( + "y".to_owned(), + Message("c and d are different fields".to_owned()), + ), + ]), ), - ], + &[ + SourcePosition::new(25, 2, 12), + SourcePosition::new(47, 3, 14), + SourcePosition::new(66, 4, 14), + SourcePosition::new(98, 6, 12), + SourcePosition::new(120, 7, 14), + SourcePosition::new(139, 8, 14), + ], + )], ); } @@ -1149,32 +1131,26 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message( - "field", - &Nested(vec![ - ConflictReason( - "deepField".to_owned(), - Nested(vec![ - ConflictReason( - "x".to_owned(), - Message("a and b are different fields".to_owned()), - ), - ]), - ), - ]), - ), - &[ - SourcePosition::new(25, 2, 12), - SourcePosition::new(47, 3, 14), - SourcePosition::new(75, 4, 16), - SourcePosition::new(123, 7, 12), - SourcePosition::new(145, 8, 14), - SourcePosition::new(173, 9, 16), - ], + &[RuleError::new( + &error_message( + "field", + &Nested(vec![ConflictReason( + "deepField".to_owned(), + Nested(vec![ConflictReason( + "x".to_owned(), + Message("a and b are different fields".to_owned()), + )]), + )]), ), - ], + &[ + SourcePosition::new(25, 2, 12), + SourcePosition::new(47, 3, 14), + SourcePosition::new(75, 4, 16), + SourcePosition::new(123, 7, 12), + SourcePosition::new(145, 8, 14), + SourcePosition::new(173, 9, 16), + ], + )], ); } @@ -1199,25 +1175,21 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message( - "deepField", - &Nested(vec![ - ConflictReason( - "x".to_owned(), - Message("a and b are different fields".to_owned()), - ), - ]), - ), - &[ - SourcePosition::new(47, 3, 14), - SourcePosition::new(75, 4, 16), - SourcePosition::new(110, 6, 14), - SourcePosition::new(138, 7, 16), - ], + &[RuleError::new( + &error_message( + "deepField", + &Nested(vec![ConflictReason( + "x".to_owned(), + Message("a and b are different fields".to_owned()), + )]), ), - ], + &[ + SourcePosition::new(47, 3, 14), + SourcePosition::new(75, 4, 16), + SourcePosition::new(110, 6, 14), + SourcePosition::new(138, 7, 16), + ], + )], ); } @@ -1250,25 +1222,21 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message( - "deeperField", - &Nested(vec![ - ConflictReason( - "x".to_owned(), - Message("a and b are different fields".to_owned()), - ), - ]), - ), - &[ - SourcePosition::new(197, 11, 14), - SourcePosition::new(227, 12, 16), - SourcePosition::new(262, 14, 14), - SourcePosition::new(292, 15, 16), - ], + &[RuleError::new( + &error_message( + "deeperField", + &Nested(vec![ConflictReason( + "x".to_owned(), + Message("a and b are different fields".to_owned()), + )]), ), - ], + &[ + SourcePosition::new(197, 11, 14), + SourcePosition::new(227, 12, 16), + SourcePosition::new(262, 14, 14), + SourcePosition::new(292, 15, 16), + ], + )], ); } @@ -1300,31 +1268,29 @@ mod tests { x: b } "#, - &[ - RuleError::new( - &error_message( - "field", - &Nested(vec![ - ConflictReason( - "x".to_owned(), - Message("a and b are different fields".to_owned()), - ), - ConflictReason( - "y".to_owned(), - Message("c and d are different fields".to_owned()), - ), - ]), - ), - &[ - SourcePosition::new(25, 2, 12), - SourcePosition::new(171, 10, 12), - SourcePosition::new(245, 14, 12), - SourcePosition::new(78, 5, 12), - SourcePosition::new(376, 21, 12), - SourcePosition::new(302, 17, 12), - ], + &[RuleError::new( + &error_message( + "field", + &Nested(vec![ + ConflictReason( + "x".to_owned(), + Message("a and b are different fields".to_owned()), + ), + ConflictReason( + "y".to_owned(), + Message("c and d are different fields".to_owned()), + ), + ]), ), - ], + &[ + SourcePosition::new(25, 2, 12), + SourcePosition::new(171, 10, 12), + SourcePosition::new(245, 14, 12), + SourcePosition::new(78, 5, 12), + SourcePosition::new(376, 21, 12), + SourcePosition::new(302, 17, 12), + ], + )], ); } @@ -1594,18 +1560,16 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message( - "scalar", - &Message("they return conflicting types Int and String!".to_owned()), - ), - &[ - SourcePosition::new(88, 4, 18), - SourcePosition::new(173, 7, 18), - ], + &[RuleError::new( + &error_message( + "scalar", + &Message("they return conflicting types Int and String!".to_owned()), ), - ], + &[ + SourcePosition::new(88, 4, 18), + SourcePosition::new(173, 7, 18), + ], + )], ); } @@ -1650,18 +1614,16 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message( - "scalar", - &Message("they return conflicting types Int and String".to_owned()), - ), - &[ - SourcePosition::new(89, 4, 18), - SourcePosition::new(167, 7, 18), - ], + &[RuleError::new( + &error_message( + "scalar", + &Message("they return conflicting types Int and String".to_owned()), ), - ], + &[ + SourcePosition::new(89, 4, 18), + SourcePosition::new(167, 7, 18), + ], + )], ); } @@ -1714,27 +1676,21 @@ mod tests { scalar: unrelatedField } "#, - &[ - RuleError::new( - &error_message( - "other", - &Nested(vec![ - ConflictReason( - "scalar".to_owned(), - Message( - "scalar and unrelatedField are different fields".to_owned(), - ), - ), - ]), - ), - &[ - SourcePosition::new(703, 30, 14), - SourcePosition::new(889, 38, 14), - SourcePosition::new(771, 33, 14), - SourcePosition::new(960, 41, 14), - ], + &[RuleError::new( + &error_message( + "other", + &Nested(vec![ConflictReason( + "scalar".to_owned(), + Message("scalar and unrelatedField are different fields".to_owned()), + )]), ), - ], + &[ + SourcePosition::new(703, 30, 14), + SourcePosition::new(889, 38, 14), + SourcePosition::new(771, 33, 14), + SourcePosition::new(960, 41, 14), + ], + )], ); } @@ -1755,18 +1711,16 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message( - "scalar", - &Message("they return conflicting types String! and String".to_owned()), - ), - &[ - SourcePosition::new(100, 4, 18), - SourcePosition::new(178, 7, 18), - ], + &[RuleError::new( + &error_message( + "scalar", + &Message("they return conflicting types String! and String".to_owned()), ), - ], + &[ + SourcePosition::new(100, 4, 18), + SourcePosition::new(178, 7, 18), + ], + )], ); } @@ -1791,20 +1745,16 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message( - "box", - &Message( - "they return conflicting types [StringBox] and StringBox".to_owned(), - ), - ), - &[ - SourcePosition::new(89, 4, 18), - SourcePosition::new(228, 9, 18), - ], + &[RuleError::new( + &error_message( + "box", + &Message("they return conflicting types [StringBox] and StringBox".to_owned()), ), - ], + &[ + SourcePosition::new(89, 4, 18), + SourcePosition::new(228, 9, 18), + ], + )], ); expect_fails_rule_with_schema( @@ -1826,20 +1776,16 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message( - "box", - &Message( - "they return conflicting types StringBox and [StringBox]".to_owned(), - ), - ), - &[ - SourcePosition::new(89, 4, 18), - SourcePosition::new(224, 9, 18), - ], + &[RuleError::new( + &error_message( + "box", + &Message("they return conflicting types StringBox and [StringBox]".to_owned()), ), - ], + &[ + SourcePosition::new(89, 4, 18), + SourcePosition::new(224, 9, 18), + ], + )], ); } @@ -1865,18 +1811,16 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message( - "val", - &Message("scalar and unrelatedField are different fields".to_owned()), - ), - &[ - SourcePosition::new(126, 5, 20), - SourcePosition::new(158, 6, 20), - ], + &[RuleError::new( + &error_message( + "val", + &Message("scalar and unrelatedField are different fields".to_owned()), ), - ], + &[ + SourcePosition::new(126, 5, 20), + SourcePosition::new(158, 6, 20), + ], + )], ); } @@ -1901,25 +1845,21 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message( - "box", - &Nested(vec![ - ConflictReason( - "scalar".to_owned(), - Message("they return conflicting types String and Int".to_owned()), - ), - ]), - ), - &[ - SourcePosition::new(89, 4, 18), - SourcePosition::new(126, 5, 20), - SourcePosition::new(224, 9, 18), - SourcePosition::new(258, 10, 20), - ], + &[RuleError::new( + &error_message( + "box", + &Nested(vec![ConflictReason( + "scalar".to_owned(), + Message("they return conflicting types String and Int".to_owned()), + )]), ), - ], + &[ + SourcePosition::new(89, 4, 18), + SourcePosition::new(126, 5, 20), + SourcePosition::new(224, 9, 18), + SourcePosition::new(258, 10, 20), + ], + )], ); } @@ -2004,32 +1944,26 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message( - "edges", - &Nested(vec![ - ConflictReason( - "node".to_owned(), - Nested(vec![ - ConflictReason( - "id".to_owned(), - Message("name and id are different fields".to_owned()), - ), - ]), - ), - ]), - ), - &[ - SourcePosition::new(84, 4, 16), - SourcePosition::new(110, 5, 18), - SourcePosition::new(137, 6, 20), - SourcePosition::new(273, 13, 14), - SourcePosition::new(297, 14, 16), - SourcePosition::new(322, 15, 18), - ], + &[RuleError::new( + &error_message( + "edges", + &Nested(vec![ConflictReason( + "node".to_owned(), + Nested(vec![ConflictReason( + "id".to_owned(), + Message("name and id are different fields".to_owned()), + )]), + )]), ), - ], + &[ + SourcePosition::new(84, 4, 16), + SourcePosition::new(110, 5, 18), + SourcePosition::new(137, 6, 20), + SourcePosition::new(273, 13, 14), + SourcePosition::new(297, 14, 16), + SourcePosition::new(322, 15, 18), + ], + )], ); } diff --git a/juniper/src/validation/rules/possible_fragment_spreads.rs b/juniper/src/validation/rules/possible_fragment_spreads.rs index baa5d7bb..b455b3ac 100644 --- a/juniper/src/validation/rules/possible_fragment_spreads.rs +++ b/juniper/src/validation/rules/possible_fragment_spreads.rs @@ -1,8 +1,8 @@ -use std::collections::HashMap; use ast::{Definition, Document, FragmentSpread, InlineFragment}; -use validation::{ValidatorContext, Visitor}; use parser::Spanning; use schema::meta::MetaType; +use std::collections::HashMap; +use validation::{ValidatorContext, Visitor}; pub struct PossibleFragmentSpreads<'a> { fragment_types: HashMap<&'a str, &'a MetaType<'a>>, @@ -223,12 +223,10 @@ mod tests { fragment invalidObjectWithinObject on Cat { ...dogFragment } fragment dogFragment on Dog { barkVolume } "#, - &[ - RuleError::new( - &error_message(Some("dogFragment"), "Cat", "Dog"), - &[SourcePosition::new(55, 1, 54)], - ), - ], + &[RuleError::new( + &error_message(Some("dogFragment"), "Cat", "Dog"), + &[SourcePosition::new(55, 1, 54)], + )], ); } @@ -241,12 +239,10 @@ mod tests { ... on Dog { barkVolume } } "#, - &[ - RuleError::new( - &error_message(None, "Cat", "Dog"), - &[SourcePosition::new(71, 2, 12)], - ), - ], + &[RuleError::new( + &error_message(None, "Cat", "Dog"), + &[SourcePosition::new(71, 2, 12)], + )], ); } @@ -258,12 +254,10 @@ mod tests { fragment invalidObjectWithinInterface on Pet { ...humanFragment } fragment humanFragment on Human { pets { name } } "#, - &[ - RuleError::new( - &error_message(Some("humanFragment"), "Pet", "Human"), - &[SourcePosition::new(58, 1, 57)], - ), - ], + &[RuleError::new( + &error_message(Some("humanFragment"), "Pet", "Human"), + &[SourcePosition::new(58, 1, 57)], + )], ); } @@ -275,12 +269,10 @@ mod tests { fragment invalidObjectWithinUnion on CatOrDog { ...humanFragment } fragment humanFragment on Human { pets { name } } "#, - &[ - RuleError::new( - &error_message(Some("humanFragment"), "CatOrDog", "Human"), - &[SourcePosition::new(59, 1, 58)], - ), - ], + &[RuleError::new( + &error_message(Some("humanFragment"), "CatOrDog", "Human"), + &[SourcePosition::new(59, 1, 58)], + )], ); } @@ -292,12 +284,10 @@ mod tests { fragment invalidUnionWithinObject on Human { ...catOrDogFragment } fragment catOrDogFragment on CatOrDog { __typename } "#, - &[ - RuleError::new( - &error_message(Some("catOrDogFragment"), "Human", "CatOrDog"), - &[SourcePosition::new(56, 1, 55)], - ), - ], + &[RuleError::new( + &error_message(Some("catOrDogFragment"), "Human", "CatOrDog"), + &[SourcePosition::new(56, 1, 55)], + )], ); } @@ -309,12 +299,10 @@ mod tests { fragment invalidUnionWithinInterface on Pet { ...humanOrAlienFragment } fragment humanOrAlienFragment on HumanOrAlien { __typename } "#, - &[ - RuleError::new( - &error_message(Some("humanOrAlienFragment"), "Pet", "HumanOrAlien"), - &[SourcePosition::new(57, 1, 56)], - ), - ], + &[RuleError::new( + &error_message(Some("humanOrAlienFragment"), "Pet", "HumanOrAlien"), + &[SourcePosition::new(57, 1, 56)], + )], ); } @@ -326,12 +314,10 @@ mod tests { fragment invalidUnionWithinUnion on CatOrDog { ...humanOrAlienFragment } fragment humanOrAlienFragment on HumanOrAlien { __typename } "#, - &[ - RuleError::new( - &error_message(Some("humanOrAlienFragment"), "CatOrDog", "HumanOrAlien"), - &[SourcePosition::new(58, 1, 57)], - ), - ], + &[RuleError::new( + &error_message(Some("humanOrAlienFragment"), "CatOrDog", "HumanOrAlien"), + &[SourcePosition::new(58, 1, 57)], + )], ); } @@ -343,12 +329,10 @@ mod tests { fragment invalidInterfaceWithinObject on Cat { ...intelligentFragment } fragment intelligentFragment on Intelligent { iq } "#, - &[ - RuleError::new( - &error_message(Some("intelligentFragment"), "Cat", "Intelligent"), - &[SourcePosition::new(58, 1, 57)], - ), - ], + &[RuleError::new( + &error_message(Some("intelligentFragment"), "Cat", "Intelligent"), + &[SourcePosition::new(58, 1, 57)], + )], ); } @@ -362,12 +346,10 @@ mod tests { } fragment intelligentFragment on Intelligent { iq } "#, - &[ - RuleError::new( - &error_message(Some("intelligentFragment"), "Pet", "Intelligent"), - &[SourcePosition::new(73, 2, 12)], - ), - ], + &[RuleError::new( + &error_message(Some("intelligentFragment"), "Pet", "Intelligent"), + &[SourcePosition::new(73, 2, 12)], + )], ); } @@ -380,12 +362,10 @@ mod tests { ...on Intelligent { iq } } "#, - &[ - RuleError::new( - &error_message(None, "Pet", "Intelligent"), - &[SourcePosition::new(77, 2, 12)], - ), - ], + &[RuleError::new( + &error_message(None, "Pet", "Intelligent"), + &[SourcePosition::new(77, 2, 12)], + )], ); } @@ -397,12 +377,10 @@ mod tests { fragment invalidInterfaceWithinUnion on HumanOrAlien { ...petFragment } fragment petFragment on Pet { name } "#, - &[ - RuleError::new( - &error_message(Some("petFragment"), "HumanOrAlien", "Pet"), - &[SourcePosition::new(66, 1, 65)], - ), - ], + &[RuleError::new( + &error_message(Some("petFragment"), "HumanOrAlien", "Pet"), + &[SourcePosition::new(66, 1, 65)], + )], ); } diff --git a/juniper/src/validation/rules/provided_non_null_arguments.rs b/juniper/src/validation/rules/provided_non_null_arguments.rs index f7575f9f..8b2f2cb3 100644 --- a/juniper/src/validation/rules/provided_non_null_arguments.rs +++ b/juniper/src/validation/rules/provided_non_null_arguments.rs @@ -1,8 +1,8 @@ use ast::{Directive, Field}; -use validation::{ValidatorContext, Visitor}; use parser::Spanning; use schema::meta::Field as FieldType; use schema::model::DirectiveType; +use validation::{ValidatorContext, Visitor}; pub struct ProvidedNonNullArguments {} @@ -262,12 +262,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &field_error_message("multipleReqs", "req1", "Int!"), - &[SourcePosition::new(63, 3, 16)], - ), - ], + &[RuleError::new( + &field_error_message("multipleReqs", "req1", "Int!"), + &[SourcePosition::new(63, 3, 16)], + )], ); } @@ -306,12 +304,10 @@ mod tests { } } "#, - &[ - RuleError::new( - &field_error_message("multipleReqs", "req2", "Int!"), - &[SourcePosition::new(63, 3, 16)], - ), - ], + &[RuleError::new( + &field_error_message("multipleReqs", "req2", "Int!"), + &[SourcePosition::new(63, 3, 16)], + )], ); } diff --git a/juniper/src/validation/rules/scalar_leafs.rs b/juniper/src/validation/rules/scalar_leafs.rs index 3311996e..2357c799 100644 --- a/juniper/src/validation/rules/scalar_leafs.rs +++ b/juniper/src/validation/rules/scalar_leafs.rs @@ -1,6 +1,6 @@ use ast::Field; -use validation::{RuleError, ValidatorContext, Visitor}; use parser::Spanning; +use validation::{RuleError, ValidatorContext, Visitor}; pub struct ScalarLeafs {} @@ -77,12 +77,10 @@ mod tests { human } "#, - &[ - RuleError::new( - &required_error_message("human", "Human"), - &[SourcePosition::new(67, 2, 12)], - ), - ], + &[RuleError::new( + &required_error_message("human", "Human"), + &[SourcePosition::new(67, 2, 12)], + )], ); } @@ -95,12 +93,10 @@ mod tests { human { pets } } "#, - &[ - RuleError::new( - &required_error_message("pets", "[Pet]"), - &[SourcePosition::new(33, 2, 20)], - ), - ], + &[RuleError::new( + &required_error_message("pets", "[Pet]"), + &[SourcePosition::new(33, 2, 20)], + )], ); } @@ -125,12 +121,10 @@ mod tests { barks { sinceWhen } } "#, - &[ - RuleError::new( - &no_allowed_error_message("barks", "Boolean"), - &[SourcePosition::new(77, 2, 12)], - ), - ], + &[RuleError::new( + &no_allowed_error_message("barks", "Boolean"), + &[SourcePosition::new(77, 2, 12)], + )], ); } @@ -143,12 +137,10 @@ mod tests { furColor { inHexdec } } "#, - &[ - RuleError::new( - &no_allowed_error_message("furColor", "FurColor"), - &[SourcePosition::new(74, 2, 12)], - ), - ], + &[RuleError::new( + &no_allowed_error_message("furColor", "FurColor"), + &[SourcePosition::new(74, 2, 12)], + )], ); } @@ -161,12 +153,10 @@ mod tests { doesKnowCommand(dogCommand: SIT) { sinceWhen } } "#, - &[ - RuleError::new( - &no_allowed_error_message("doesKnowCommand", "Boolean"), - &[SourcePosition::new(76, 2, 12)], - ), - ], + &[RuleError::new( + &no_allowed_error_message("doesKnowCommand", "Boolean"), + &[SourcePosition::new(76, 2, 12)], + )], ); } @@ -179,12 +169,10 @@ mod tests { name @include(if: true) { isAlsoHumanName } } "#, - &[ - RuleError::new( - &no_allowed_error_message("name", "String"), - &[SourcePosition::new(82, 2, 12)], - ), - ], + &[RuleError::new( + &no_allowed_error_message("name", "String"), + &[SourcePosition::new(82, 2, 12)], + )], ); } @@ -197,12 +185,10 @@ mod tests { doesKnowCommand(dogCommand: SIT) @include(if: true) { sinceWhen } } "#, - &[ - RuleError::new( - &no_allowed_error_message("doesKnowCommand", "Boolean"), - &[SourcePosition::new(89, 2, 12)], - ), - ], + &[RuleError::new( + &no_allowed_error_message("doesKnowCommand", "Boolean"), + &[SourcePosition::new(89, 2, 12)], + )], ); } diff --git a/juniper/src/validation/rules/unique_argument_names.rs b/juniper/src/validation/rules/unique_argument_names.rs index 8691d7ef..e31585ba 100644 --- a/juniper/src/validation/rules/unique_argument_names.rs +++ b/juniper/src/validation/rules/unique_argument_names.rs @@ -1,8 +1,8 @@ use std::collections::hash_map::{Entry, HashMap}; use ast::{Directive, Field, InputValue}; -use validation::{ValidatorContext, Visitor}; use parser::{SourcePosition, Spanning}; +use validation::{ValidatorContext, Visitor}; pub struct UniqueArgumentNames<'a> { known_names: HashMap<&'a str, SourcePosition>, @@ -171,15 +171,13 @@ mod tests { field(arg1: "value", arg1: "value") } "#, - &[ - RuleError::new( - &error_message("arg1"), - &[ - SourcePosition::new(31, 2, 18), - SourcePosition::new(46, 2, 33), - ], - ), - ], + &[RuleError::new( + &error_message("arg1"), + &[ + SourcePosition::new(31, 2, 18), + SourcePosition::new(46, 2, 33), + ], + )], ); } @@ -220,15 +218,13 @@ mod tests { field @directive(arg1: "value", arg1: "value") } "#, - &[ - RuleError::new( - &error_message("arg1"), - &[ - SourcePosition::new(42, 2, 29), - SourcePosition::new(57, 2, 44), - ], - ), - ], + &[RuleError::new( + &error_message("arg1"), + &[ + SourcePosition::new(42, 2, 29), + SourcePosition::new(57, 2, 44), + ], + )], ); } diff --git a/juniper/src/validation/rules/unique_fragment_names.rs b/juniper/src/validation/rules/unique_fragment_names.rs index 3babebfb..21873c88 100644 --- a/juniper/src/validation/rules/unique_fragment_names.rs +++ b/juniper/src/validation/rules/unique_fragment_names.rs @@ -143,15 +143,13 @@ mod tests { fieldB } "#, - &[ - RuleError::new( - &duplicate_message("fragA"), - &[ - SourcePosition::new(65, 4, 19), - SourcePosition::new(131, 7, 19), - ], - ), - ], + &[RuleError::new( + &duplicate_message("fragA"), + &[ + SourcePosition::new(65, 4, 19), + SourcePosition::new(131, 7, 19), + ], + )], ); } @@ -167,15 +165,13 @@ mod tests { fieldB } "#, - &[ - RuleError::new( - &duplicate_message("fragA"), - &[ - SourcePosition::new(20, 1, 19), - SourcePosition::new(86, 4, 19), - ], - ), - ], + &[RuleError::new( + &duplicate_message("fragA"), + &[ + SourcePosition::new(20, 1, 19), + SourcePosition::new(86, 4, 19), + ], + )], ); } } diff --git a/juniper/src/validation/rules/unique_input_field_names.rs b/juniper/src/validation/rules/unique_input_field_names.rs index 810909a5..cd1e2530 100644 --- a/juniper/src/validation/rules/unique_input_field_names.rs +++ b/juniper/src/validation/rules/unique_input_field_names.rs @@ -1,8 +1,8 @@ use std::collections::hash_map::{Entry, HashMap}; use ast::InputValue; -use validation::{ValidatorContext, Visitor}; use parser::{SourcePosition, Spanning}; +use validation::{ValidatorContext, Visitor}; pub struct UniqueInputFieldNames<'a> { known_name_stack: Vec<HashMap<&'a str, SourcePosition>>, @@ -128,15 +128,13 @@ mod tests { field(arg: { f1: "value", f1: "value" }) } "#, - &[ - RuleError::new( - &error_message("f1"), - &[ - SourcePosition::new(38, 2, 25), - SourcePosition::new(51, 2, 38), - ], - ), - ], + &[RuleError::new( + &error_message("f1"), + &[ + SourcePosition::new(38, 2, 25), + SourcePosition::new(51, 2, 38), + ], + )], ); } diff --git a/juniper/src/validation/rules/unique_operation_names.rs b/juniper/src/validation/rules/unique_operation_names.rs index 8a87950d..3ca6ac8d 100644 --- a/juniper/src/validation/rules/unique_operation_names.rs +++ b/juniper/src/validation/rules/unique_operation_names.rs @@ -142,15 +142,13 @@ mod tests { fieldB } "#, - &[ - RuleError::new( - &error_message("Foo"), - &[ - SourcePosition::new(11, 1, 10), - SourcePosition::new(64, 4, 10), - ], - ), - ], + &[RuleError::new( + &error_message("Foo"), + &[ + SourcePosition::new(11, 1, 10), + SourcePosition::new(64, 4, 10), + ], + )], ); } @@ -166,15 +164,13 @@ mod tests { fieldB } "#, - &[ - RuleError::new( - &error_message("Foo"), - &[ - SourcePosition::new(11, 1, 10), - SourcePosition::new(64, 4, 10), - ], - ), - ], + &[RuleError::new( + &error_message("Foo"), + &[ + SourcePosition::new(11, 1, 10), + SourcePosition::new(64, 4, 10), + ], + )], ); } } diff --git a/juniper/src/validation/rules/variables_in_allowed_position.rs b/juniper/src/validation/rules/variables_in_allowed_position.rs index 38a8f11c..0bffb346 100644 --- a/juniper/src/validation/rules/variables_in_allowed_position.rs +++ b/juniper/src/validation/rules/variables_in_allowed_position.rs @@ -383,15 +383,13 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("intArg", "Int", "Int!"), - &[ - SourcePosition::new(23, 1, 22), - SourcePosition::new(117, 3, 48), - ], - ), - ], + &[RuleError::new( + &error_message("intArg", "Int", "Int!"), + &[ + SourcePosition::new(23, 1, 22), + SourcePosition::new(117, 3, 48), + ], + )], ); } @@ -410,15 +408,13 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("intArg", "Int", "Int!"), - &[ - SourcePosition::new(154, 5, 22), - SourcePosition::new(110, 2, 46), - ], - ), - ], + &[RuleError::new( + &error_message("intArg", "Int", "Int!"), + &[ + SourcePosition::new(154, 5, 22), + SourcePosition::new(110, 2, 46), + ], + )], ); } @@ -441,15 +437,13 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("intArg", "Int", "Int!"), - &[ - SourcePosition::new(255, 9, 22), - SourcePosition::new(211, 6, 46), - ], - ), - ], + &[RuleError::new( + &error_message("intArg", "Int", "Int!"), + &[ + SourcePosition::new(255, 9, 22), + SourcePosition::new(211, 6, 46), + ], + )], ); } @@ -464,15 +458,13 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("stringVar", "String", "Boolean"), - &[ - SourcePosition::new(23, 1, 22), - SourcePosition::new(117, 3, 42), - ], - ), - ], + &[RuleError::new( + &error_message("stringVar", "String", "Boolean"), + &[ + SourcePosition::new(23, 1, 22), + SourcePosition::new(117, 3, 42), + ], + )], ); } @@ -487,15 +479,13 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("stringVar", "String", "[String]"), - &[ - SourcePosition::new(23, 1, 22), - SourcePosition::new(123, 3, 48), - ], - ), - ], + &[RuleError::new( + &error_message("stringVar", "String", "[String]"), + &[ + SourcePosition::new(23, 1, 22), + SourcePosition::new(123, 3, 48), + ], + )], ); } @@ -508,15 +498,13 @@ mod tests { dog @include(if: $boolVar) } "#, - &[ - RuleError::new( - &error_message("boolVar", "Boolean", "Boolean!"), - &[ - SourcePosition::new(23, 1, 22), - SourcePosition::new(73, 2, 29), - ], - ), - ], + &[RuleError::new( + &error_message("boolVar", "Boolean", "Boolean!"), + &[ + SourcePosition::new(23, 1, 22), + SourcePosition::new(73, 2, 29), + ], + )], ); } @@ -529,15 +517,13 @@ mod tests { dog @include(if: $stringVar) } "#, - &[ - RuleError::new( - &error_message("stringVar", "String", "Boolean!"), - &[ - SourcePosition::new(23, 1, 22), - SourcePosition::new(74, 2, 29), - ], - ), - ], + &[RuleError::new( + &error_message("stringVar", "String", "Boolean!"), + &[ + SourcePosition::new(23, 1, 22), + SourcePosition::new(74, 2, 29), + ], + )], ); } } diff --git a/juniper/src/validation/test_harness.rs b/juniper/src/validation/test_harness.rs index 1ba848c7..47331b0c 100644 --- a/juniper/src/validation/test_harness.rs +++ b/juniper/src/validation/test_harness.rs @@ -1,10 +1,10 @@ -use parser::parse_document_source; use ast::{FromInputValue, InputValue}; -use types::base::GraphQLType; use executor::Registry; -use types::scalars::{EmptyMutation, ID}; -use schema::model::{DirectiveLocation, DirectiveType, RootNode}; +use parser::parse_document_source; use schema::meta::{EnumValue, MetaType}; +use schema::model::{DirectiveLocation, DirectiveType, RootNode}; +use types::base::GraphQLType; +use types::scalars::{EmptyMutation, ID}; use validation::{visit, MultiVisitor, MultiVisitorNil, RuleError, ValidatorContext, Visitor}; struct Being; @@ -60,11 +60,9 @@ impl GraphQLType for Being { } fn meta<'r>(i: &(), registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry - .field::<Option<String>>("name", i) - .argument(registry.arg::<Option<bool>>("surname", i)), - ]; + let fields = &[registry + .field::<Option<String>>("name", i) + .argument(registry.arg::<Option<bool>>("surname", i))]; registry.build_interface_type::<Self>(i, fields).into_meta() } @@ -79,11 +77,9 @@ impl GraphQLType for Pet { } fn meta<'r>(i: &(), registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry - .field::<Option<String>>("name", i) - .argument(registry.arg::<Option<bool>>("surname", i)), - ]; + let fields = &[registry + .field::<Option<String>>("name", i) + .argument(registry.arg::<Option<bool>>("surname", i))]; registry.build_interface_type::<Self>(i, fields).into_meta() } @@ -98,11 +94,9 @@ impl GraphQLType for Canine { } fn meta<'r>(i: &(), registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry - .field::<Option<String>>("name", i) - .argument(registry.arg::<Option<bool>>("surname", i)), - ]; + let fields = &[registry + .field::<Option<String>>("name", i) + .argument(registry.arg::<Option<bool>>("surname", i))]; registry.build_interface_type::<Self>(i, fields).into_meta() } diff --git a/juniper/src/validation/visitor.rs b/juniper/src/validation/visitor.rs index 884ebc94..fccfd34e 100644 --- a/juniper/src/validation/visitor.rs +++ b/juniper/src/validation/visitor.rs @@ -3,8 +3,8 @@ use std::borrow::Cow; use ast::{Arguments, Definition, Directive, Document, Field, Fragment, FragmentSpread, InlineFragment, InputValue, Operation, OperationType, Selection, Type, VariableDefinitions}; -use schema::meta::Argument; use parser::Spanning; +use schema::meta::Argument; use validation::{ValidatorContext, Visitor}; #[doc(hidden)] diff --git a/juniper/src/value.rs b/juniper/src/value.rs index d5cbc579..001d8145 100644 --- a/juniper/src/value.rs +++ b/juniper/src/value.rs @@ -1,8 +1,8 @@ use indexmap::IndexMap; use std::hash::Hash; -use parser::Spanning; use ast::{InputValue, ToInputValue}; +use parser::Spanning; /// Serializable value returned from query and field execution. /// @@ -276,7 +276,7 @@ mod tests { Value::object( vec![("key", Value::int(123)), ("next", Value::boolean(true))] .into_iter() - .collect() + .collect(), ) ); } From 61f0c7d337894ebcae073bc54263568dcc7bd9cd Mon Sep 17 00:00:00 2001 From: theduke <reg@theduke.at> Date: Thu, 10 May 2018 06:43:28 +0200 Subject: [PATCH 09/18] Update uuid version range Allow 0.5 and 0.6 --- juniper/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/juniper/Cargo.toml b/juniper/Cargo.toml index 2fda1bc1..0176fcd4 100644 --- a/juniper/Cargo.toml +++ b/juniper/Cargo.toml @@ -42,7 +42,7 @@ serde_derive = {version="1.0.2" } chrono = { version = "0.4.0", optional = true } serde_json = { version="1.0.2", optional = true } url = { version = "1.5.1", optional = true } -uuid = { version = "0.5.1", optional = true } +uuid = { version = "> 0.4, < 0.7", optional = true } [dev-dependencies] bencher = "0.1.2" From dd99914fbebeacee46f36ff072d5eea161e507b0 Mon Sep 17 00:00:00 2001 From: Georg Semmler <georg_semmler_05@web.de> Date: Fri, 26 Jan 2018 15:03:29 +0100 Subject: [PATCH 10/18] Add a basic lookahead functionality --- juniper/src/executor/look_ahead.rs | 1106 ++++++++++++++++++++++++++++ juniper/src/executor/mod.rs | 21 + juniper/src/lib.rs | 1 + juniper/src/value.rs | 2 +- 4 files changed, 1129 insertions(+), 1 deletion(-) create mode 100644 juniper/src/executor/look_ahead.rs diff --git a/juniper/src/executor/look_ahead.rs b/juniper/src/executor/look_ahead.rs new file mode 100644 index 00000000..f5fa87fc --- /dev/null +++ b/juniper/src/executor/look_ahead.rs @@ -0,0 +1,1106 @@ +use ast::{Directive, Fragment, InputValue, Selection}; +use parser::Spanning; + +use std::collections::HashMap; + +use super::Variables; + +#[derive(Debug, Clone, PartialEq)] +pub enum Applies<'a> { + All, + OnlyType(&'a str), +} + +#[derive(Debug, Clone, PartialEq)] +pub enum LookAheadValue<'a> { + Null, + Int(i32), + Float(f64), + String(&'a str), + Boolean(bool), + // TODO: improve + Enum(&'a str), + List(Vec<LookAheadValue<'a>>), + Object(Vec<(&'a str, LookAheadValue<'a>)>), +} + +impl<'a> LookAheadValue<'a> { + fn from_input_value(input_value: &'a InputValue, vars: &'a Variables) -> Self { + match *input_value { + InputValue::Null => LookAheadValue::Null, + InputValue::Int(i) => LookAheadValue::Int(i), + InputValue::Float(f) => LookAheadValue::Float(f), + InputValue::String(ref s) => LookAheadValue::String(s), + InputValue::Boolean(b) => LookAheadValue::Boolean(b), + InputValue::Enum(ref e) => LookAheadValue::Enum(e), + InputValue::Variable(ref v) => Self::from_input_value(vars.get(v).unwrap(), vars), + InputValue::List(ref l) => LookAheadValue::List( + l.iter() + .map(|i| LookAheadValue::from_input_value(&i.item, vars)) + .collect(), + ), + InputValue::Object(ref o) => LookAheadValue::Object( + o.iter() + .map(|&(ref n, ref i)| { + ( + &n.item as &str, + LookAheadValue::from_input_value(&i.item, vars), + ) + }) + .collect(), + ), + } + } +} + +#[derive(Debug, Clone, PartialEq)] +pub struct LookAheadArgument<'a> { + name: &'a str, + value: LookAheadValue<'a>, +} + +impl<'a> LookAheadArgument<'a> { + fn new( + &(ref name, ref value): &'a (Spanning<&'a str>, Spanning<InputValue>), + vars: &'a Variables, + ) -> Self { + LookAheadArgument { + name: name.item, + value: LookAheadValue::from_input_value(&value.item, vars), + } + } +} + +#[derive(Debug, Clone, PartialEq)] +pub struct ChildSelection<'a> { + pub(super) inner: LookAheadSelection<'a>, + pub(super) applies_for: Applies<'a>, +} + +#[derive(Debug, Clone, PartialEq)] +pub struct LookAheadSelection<'a> { + pub(super) name: &'a str, + pub(super) alias: Option<&'a str>, + pub(super) arguments: Vec<LookAheadArgument<'a>>, + pub(super) childs: Vec<ChildSelection<'a>>, +} + +impl<'a> LookAheadSelection<'a> { + fn should_include(directives: Option<&Vec<Spanning<Directive>>>, vars: &Variables) -> bool { + directives + .map(|d| { + d.iter().all(|d| { + let d = &d.item; + let arguments = &d.arguments; + match (d.name.item, arguments) { + ("include", &Some(ref a)) => a.item + .items + .iter() + .find(|item| item.0.item == "if") + .map(|&(_, ref v)| { + if let LookAheadValue::Boolean(b) = + LookAheadValue::from_input_value(&v.item, vars) + { + b + } else { + false + } + }) + .unwrap_or(false), + ("skip", &Some(ref a)) => a.item + .items + .iter() + .find(|item| item.0.item == "if") + .map(|&(_, ref v)| { + if let LookAheadValue::Boolean(b) = + LookAheadValue::from_input_value(&v.item, vars) + { + !b + } else { + false + } + }) + .unwrap_or(false), + ("skip", &None) => false, + ("include", &None) => true, + (_, _) => unreachable!(), + } + }) + }) + .unwrap_or(true) + } + + pub(super) fn build_from_selection( + s: &'a Selection<'a>, + vars: &'a Variables, + fragments: &'a HashMap<&'a str, &'a Fragment<'a>>, + ) -> LookAheadSelection<'a> { + Self::build_from_selection_with_parent(s, None, vars, fragments).unwrap() + } + + fn build_from_selection_with_parent( + s: &'a Selection<'a>, + parent: Option<&mut Self>, + vars: &'a Variables, + fragments: &'a HashMap<&'a str, &'a Fragment<'a>>, + ) -> Option<LookAheadSelection<'a>> { + let empty: &[Selection] = &[]; + match *s { + Selection::Field(ref field) => { + let field = &field.item; + let include = Self::should_include(field.directives.as_ref(), vars); + if !include { + return None; + } + let name = field.name.item; + let alias = field.alias.as_ref().map(|a| a.item); + let arguments = field + .arguments + .as_ref() + .map(|a| &a.item) + .map(|a| { + a.items + .iter() + .map(|p| LookAheadArgument::new(p, vars)) + .collect() + }) + .unwrap_or_else(Vec::new); + let mut ret = LookAheadSelection { + name, + alias, + arguments, + childs: Vec::new(), + }; + for c in field + .selection_set + .as_ref() + .map(|s| s as &[_]) + .unwrap_or_else(|| empty) + .iter() + { + let s = LookAheadSelection::build_from_selection_with_parent( + c, + Some(&mut ret), + vars, + fragments, + ); + assert!(s.is_none()); + } + if let Some(p) = parent { + p.childs.push(ChildSelection { + inner: ret, + applies_for: Applies::All, + }); + None + } else { + Some(ret) + } + } + Selection::FragmentSpread(ref fragment) if parent.is_some() => { + let include = Self::should_include(fragment.item.directives.as_ref(), vars); + if !include { + return None; + } + let parent = parent.unwrap(); + let f = fragments.get(&fragment.item.name.item).unwrap(); + for c in f.selection_set.iter() { + let s = LookAheadSelection::build_from_selection_with_parent( + c, + Some(parent), + vars, + fragments, + ); + assert!(s.is_none()); + } + None + } + Selection::InlineFragment(ref inline) if parent.is_some() => { + let include = Self::should_include(inline.item.directives.as_ref(), vars); + if !include { + return None; + } + let parent = parent.unwrap(); + for c in inline.item.selection_set.iter() { + let s = LookAheadSelection::build_from_selection_with_parent( + c, + Some(parent), + vars, + fragments, + ); + assert!(s.is_none()); + if let Some(ref c) = inline.item.type_condition.as_ref().map(|t| t.item) { + if let Some(p) = parent.childs.last_mut() { + p.applies_for = Applies::OnlyType(c); + } + } + } + None + } + _ => unimplemented!(), + } + } + + pub fn for_explicit_type(&self, type_name: &str) -> ConcreteLookAheadSelection<'a> { + ConcreteLookAheadSelection { + childs: self.childs + .iter() + .filter_map(|c| match c.applies_for { + Applies::OnlyType(ref t) if *t == type_name => { + Some(c.inner.for_explicit_type(type_name)) + } + Applies::All => Some(c.inner.for_explicit_type(type_name)), + Applies::OnlyType(_) => None, + }) + .collect(), + name: self.name, + alias: self.alias, + arguments: self.arguments.clone(), + } + } +} + +#[derive(Debug, PartialEq)] +pub struct ConcreteLookAheadSelection<'a> { + name: &'a str, + alias: Option<&'a str>, + arguments: Vec<LookAheadArgument<'a>>, + childs: Vec<ConcreteLookAheadSelection<'a>>, +} + +pub trait LookAheadMethods { + fn field_name(&self) -> &str; + + fn select_child(&self, name: &str) -> Option<&Self>; + + fn has_child(&self, name: &str) -> bool { + self.select_child(name).is_some() + } +} + +impl<'a> LookAheadMethods for ConcreteLookAheadSelection<'a> { + fn field_name(&self) -> &str { + self.alias.unwrap_or(self.name) + } + + fn select_child(&self, name: &str) -> Option<&Self> { + self.childs.iter().find(|c| c.name == name) + } +} + +impl<'a> LookAheadMethods for LookAheadSelection<'a> { + fn field_name(&self) -> &str { + self.alias.unwrap_or(self.name) + } + + fn select_child(&self, name: &str) -> Option<&Self> { + self.childs.iter().find(|c| c.inner.name == name).map(|s| &s.inner) + } +} + +#[cfg(test)] +mod tests { + use std::collections::HashMap; + use super::*; + use ast::Document; + + fn extract_fragments<'a>(doc: &'a Document) -> HashMap<&'a str, &'a Fragment<'a>> { + let mut fragments = HashMap::new(); + for d in doc { + if let ::ast::Definition::Fragment(ref f) = *d { + let f = &f.item; + fragments.insert(f.name.item, f); + } + } + fragments + } + + #[test] + fn check_simple_query() { + let docs = ::parse_document_source( + " +query Hero { + hero { + id + name + } +} +", + ).unwrap(); + let fragments = extract_fragments(&docs); + + if let ::ast::Definition::Operation(ref op) = docs[0] { + let vars = Variables::default(); + let look_ahead = LookAheadSelection::build_from_selection( + &op.item.selection_set[0], + &vars, + &fragments, + ); + let expected = LookAheadSelection { + name: "hero", + alias: None, + arguments: Vec::new(), + childs: vec![ + ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ], + }; + assert_eq!(look_ahead, expected); + } else { + panic!("No Operation found"); + } + } + + #[test] + fn check_query_with_alias() { + let docs = ::parse_document_source( + " +query Hero { + custom_hero: hero { + id + my_name: name + } +} +", + ).unwrap(); + let fragments = extract_fragments(&docs); + + if let ::ast::Definition::Operation(ref op) = docs[0] { + let vars = Variables::default(); + let look_ahead = LookAheadSelection::build_from_selection( + &op.item.selection_set[0], + &vars, + &fragments, + ); + let expected = LookAheadSelection { + name: "hero", + alias: Some("custom_hero"), + arguments: Vec::new(), + childs: vec![ + ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: Some("my_name"), + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ], + }; + assert_eq!(look_ahead, expected); + } else { + panic!("No Operation found"); + } + } + + #[test] + fn check_query_with_child() { + let docs = ::parse_document_source( + " +query Hero { + hero { + id + name + friends { + name + id + } + } +} +", + ).unwrap(); + let fragments = extract_fragments(&docs); + + if let ::ast::Definition::Operation(ref op) = docs[0] { + let vars = Variables::default(); + let look_ahead = LookAheadSelection::build_from_selection( + &op.item.selection_set[0], + &vars, + &fragments, + ); + let expected = LookAheadSelection { + name: "hero", + alias: None, + arguments: Vec::new(), + childs: vec![ + ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "friends", + alias: None, + arguments: Vec::new(), + childs: vec![ + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ], + }, + applies_for: Applies::All, + }, + ], + }; + assert_eq!(look_ahead, expected); + } else { + panic!("No Operation found"); + } + } + + #[test] + fn check_query_with_argument() { + let docs = ::parse_document_source( + " +query Hero { + hero(episode: EMPIRE) { + id + name(uppercase: true) + } +} +", + ).unwrap(); + let fragments = extract_fragments(&docs); + + if let ::ast::Definition::Operation(ref op) = docs[0] { + let vars = Variables::default(); + let look_ahead = LookAheadSelection::build_from_selection( + &op.item.selection_set[0], + &vars, + &fragments, + ); + let expected = LookAheadSelection { + name: "hero", + alias: None, + arguments: vec![ + LookAheadArgument { + name: "episode", + value: LookAheadValue::Enum("EMPIRE"), + }, + ], + childs: vec![ + ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: vec![ + LookAheadArgument { + name: "uppercase", + value: LookAheadValue::Boolean(true), + }, + ], + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ], + }; + assert_eq!(look_ahead, expected); + } else { + panic!("No Operation found"); + } + } + + #[test] + fn check_query_with_variable() { + let docs = ::parse_document_source( + " +query Hero($episode: Episode) { + hero(episode: $episode) { + id + name + } +} +", + ).unwrap(); + let fragments = extract_fragments(&docs); + + if let ::ast::Definition::Operation(ref op) = docs[0] { + let mut vars = Variables::default(); + vars.insert("episode".into(), InputValue::Enum("JEDI".into())); + let look_ahead = LookAheadSelection::build_from_selection( + &op.item.selection_set[0], + &vars, + &fragments, + ); + let expected = LookAheadSelection { + name: "hero", + alias: None, + arguments: vec![ + LookAheadArgument { + name: "episode", + value: LookAheadValue::Enum("JEDI"), + }, + ], + childs: vec![ + ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ], + }; + assert_eq!(look_ahead, expected); + } else { + panic!("No Operation found"); + } + } + + #[test] + fn check_query_with_fragment() { + let docs = ::parse_document_source( + " +query Hero { + hero { + id + ...commonFields + } +} + +fragment commonFields on Character { + name + appearsIn +} +", + ).unwrap(); + let fragments = extract_fragments(&docs); + + if let ::ast::Definition::Operation(ref op) = docs[0] { + let vars = Variables::default(); + let look_ahead = LookAheadSelection::build_from_selection( + &op.item.selection_set[0], + &vars, + &fragments, + ); + let expected = LookAheadSelection { + name: "hero", + alias: None, + arguments: Vec::new(), + childs: vec![ + ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "appearsIn", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ], + }; + assert_eq!(look_ahead, expected); + } else { + panic!("No Operation found"); + } + } + + #[test] + fn check_query_with_directives() { + let docs = ::parse_document_source( + " +query Hero { + hero { + id @include(if: true) + name @include(if: false) + appearsIn @skip(if: true) + height @skip(if: false) + } +}", + ).unwrap(); + let fragments = extract_fragments(&docs); + + if let ::ast::Definition::Operation(ref op) = docs[0] { + let vars = Variables::default(); + let look_ahead = LookAheadSelection::build_from_selection( + &op.item.selection_set[0], + &vars, + &fragments, + ); + let expected = LookAheadSelection { + name: "hero", + alias: None, + arguments: Vec::new(), + childs: vec![ + ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "height", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ], + }; + assert_eq!(look_ahead, expected); + } else { + panic!("No Operation found"); + } + } + + #[test] + fn check_query_with_inline_fragments() { + let docs = ::parse_document_source( + " +query Hero { + hero { + name + ... on Droid { + primaryFunction + } + ... on Human { + height + } + } +}", + ).unwrap(); + let fragments = extract_fragments(&docs); + + if let ::ast::Definition::Operation(ref op) = docs[0] { + let vars = Variables::default(); + let look_ahead = LookAheadSelection::build_from_selection( + &op.item.selection_set[0], + &vars, + &fragments, + ); + let expected = LookAheadSelection { + name: "hero", + alias: None, + arguments: Vec::new(), + childs: vec![ + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "primaryFunction", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::OnlyType("Droid"), + }, + ChildSelection { + inner: LookAheadSelection { + name: "height", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::OnlyType("Human"), + }, + ], + }; + assert_eq!(look_ahead, expected); + } else { + panic!("No Operation found"); + } + } + + #[test] + fn check_complex_query() { + let docs = ::parse_document_source( + " +query HeroNameAndFriends($id: Integer!, $withFriends: Boolean! = true) { + hero(id: $id) { + id + ... comparisonFields + friends @include(if: $withFriends) { + ... comparisonFields + ... on Human @skip(if: true) { mass } + } + } +} + +fragment comparisonFields on Character { + __typename + name + appearsIn + ... on Droid { primaryFunction } + ... on Human { height } +}", + ).unwrap(); + let fragments = extract_fragments(&docs); + + if let ::ast::Definition::Operation(ref op) = docs[0] { + let mut vars = Variables::default(); + vars.insert("id".into(), InputValue::Int(42)); + // This will normally be there + vars.insert("withFriends".into(), InputValue::Boolean(true)); + let look_ahead = LookAheadSelection::build_from_selection( + &op.item.selection_set[0], + &vars, + &fragments, + ); + let expected = LookAheadSelection { + name: "hero", + alias: None, + arguments: vec![ + LookAheadArgument { + name: "id", + value: LookAheadValue::Int(42), + }, + ], + childs: vec![ + ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "__typename", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "appearsIn", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "primaryFunction", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::OnlyType("Droid"), + }, + ChildSelection { + inner: LookAheadSelection { + name: "height", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::OnlyType("Human"), + }, + ChildSelection { + inner: LookAheadSelection { + name: "friends", + alias: None, + arguments: Vec::new(), + childs: vec![ + ChildSelection { + inner: LookAheadSelection { + name: "__typename", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "appearsIn", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "primaryFunction", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::OnlyType("Droid"), + }, + ChildSelection { + inner: LookAheadSelection { + name: "height", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::OnlyType("Human"), + }, + ], + }, + applies_for: Applies::All, + }, + ], + }; + assert_eq!(look_ahead, expected); + } else { + panic!("No Operation found"); + } + } + + #[test] + fn check_resolve_concrete_type() { + let docs = ::parse_document_source( + " +query Hero { + hero { + name + ... on Droid { + primaryFunction + } + ... on Human { + height + } + } +}", + ).unwrap(); + let fragments = extract_fragments(&docs); + + if let ::ast::Definition::Operation(ref op) = docs[0] { + let vars = Variables::default(); + let look_ahead = LookAheadSelection::build_from_selection( + &op.item.selection_set[0], + &vars, + &fragments, + ).for_explicit_type("Human"); + let expected = ConcreteLookAheadSelection { + name: "hero", + alias: None, + arguments: Vec::new(), + childs: vec![ + ConcreteLookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + ConcreteLookAheadSelection { + name: "height", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + ], + }; + assert_eq!(look_ahead, expected); + } else { + panic!("No Operation found"); + } + } + + #[test] + fn check_select_child() { + let lookahead = LookAheadSelection{ + name: "hero", + alias: None, + arguments: Vec::new(), + childs: vec![ + ChildSelection{ + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "friends", + alias: None, + arguments: Vec::new(), + childs: vec![ + ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All + }, + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All + } + ], + }, + applies_for: Applies::All + } + ] + }; + let concret_query = lookahead.for_explicit_type("does not matter"); + + let id = lookahead.select_child("id"); + let concrete_id = concret_query.select_child("id"); + let expected = LookAheadSelection{name: "id", alias: None, arguments: Vec::new(), childs: Vec::new()}; + assert_eq!(id, Some(&expected)); + assert_eq!(concrete_id, Some(&expected.for_explicit_type("does not matter"))); + + let friends = lookahead.select_child("friends"); + let concrete_friends = concret_query.select_child("friends"); + let expected = LookAheadSelection { + name: "friends", + alias: None, + arguments: Vec::new(), + childs: vec![ + ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All + }, + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All + } + ], + }; + assert_eq!(friends, Some(&expected)); + assert_eq!(concrete_friends, Some(&expected.for_explicit_type("does not matter"))); + } + +} diff --git a/juniper/src/executor/mod.rs b/juniper/src/executor/mod.rs index 414cf5f1..b935bb50 100644 --- a/juniper/src/executor/mod.rs +++ b/juniper/src/executor/mod.rs @@ -19,6 +19,10 @@ use schema::model::{RootNode, SchemaType, TypeType}; use types::base::GraphQLType; use types::name::Name; +mod look_ahead; + +pub use self::look_ahead::{Applies, LookAheadArgument, LookAheadSelection, LookAheadValue, LookAheadMethods, ChildSelection}; + /// A type registry used to build schemas /// /// The registry gathers metadata for all types in a schema. It provides @@ -51,6 +55,7 @@ where context: &'a CtxT, errors: &'a RwLock<Vec<ExecutionError>>, field_path: FieldPath<'a>, + type_name: &'a str, } /// Error type for errors that occur during query execution @@ -319,6 +324,7 @@ impl<'a, CtxT> Executor<'a, CtxT> { context: ctx, errors: self.errors, field_path: self.field_path.clone(), + type_name: self.type_name, } } @@ -345,6 +351,7 @@ impl<'a, CtxT> Executor<'a, CtxT> { context: self.context, errors: self.errors, field_path: FieldPath::Field(field_alias, location, &self.field_path), + type_name: self.type_name } } @@ -366,6 +373,7 @@ impl<'a, CtxT> Executor<'a, CtxT> { context: self.context, errors: self.errors, field_path: self.field_path.clone(), + type_name: type_name.unwrap(), } } @@ -421,6 +429,18 @@ impl<'a, CtxT> Executor<'a, CtxT> { error: error, }); } + + pub fn look_ahead(&self) -> LookAheadSelection { + LookAheadSelection{ + name: self.type_name, + alias: None, + arguments: Vec::new(), + childs: self.current_selection_set.map(|s| s.iter().map(|s| ChildSelection { + inner: LookAheadSelection::build_from_selection(s, self.variables, self.fragments), + applies_for: Applies::All + }).collect()).unwrap_or_else(Vec::new) + } + } } impl<'a> FieldPath<'a> { @@ -553,6 +573,7 @@ where context: context, errors: &errors, field_path: FieldPath::Root(op.start), + type_name: &op.item.name.map(|n| n.item).unwrap_or(""), }; value = match op.item.operation_type { diff --git a/juniper/src/lib.rs b/juniper/src/lib.rs index 28b90da0..356f02f3 100644 --- a/juniper/src/lib.rs +++ b/juniper/src/lib.rs @@ -153,6 +153,7 @@ use validation::{validate_input_values, visit_all_rules, ValidatorContext}; pub use ast::{FromInputValue, InputValue, Selection, ToInputValue, Type}; pub use executor::{Context, ExecutionError, ExecutionResult, Executor, FieldError, FieldResult, FromContext, IntoResolvable, Registry, Variables}; +pub use executor::{Applies, LookAheadArgument, LookAheadSelection, LookAheadValue, LookAheadMethods}; pub use schema::model::RootNode; pub use types::base::{Arguments, GraphQLType, TypeKind}; pub use types::scalars::{EmptyMutation, ID}; diff --git a/juniper/src/value.rs b/juniper/src/value.rs index 001d8145..ececbfb6 100644 --- a/juniper/src/value.rs +++ b/juniper/src/value.rs @@ -13,7 +13,7 @@ use parser::Spanning; /// values or variables. Also, lists and objects do not contain any location /// information since they are generated by resolving fields and values rather /// than parsing a source query. -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] #[allow(missing_docs)] pub enum Value { Null, From 61c07b95fcac6965aa454bccf2e4020cc4875edc Mon Sep 17 00:00:00 2001 From: Georg Semmler <georg_semmler_05@web.de> Date: Thu, 15 Mar 2018 15:43:16 +0100 Subject: [PATCH 11/18] Small improvements + rustfmt --- juniper/src/executor/look_ahead.rs | 1186 +++++++++++++--------------- juniper/src/executor/mod.rs | 35 +- 2 files changed, 590 insertions(+), 631 deletions(-) diff --git a/juniper/src/executor/look_ahead.rs b/juniper/src/executor/look_ahead.rs index f5fa87fc..8c8e9159 100644 --- a/juniper/src/executor/look_ahead.rs +++ b/juniper/src/executor/look_ahead.rs @@ -34,21 +34,22 @@ impl<'a> LookAheadValue<'a> { InputValue::Boolean(b) => LookAheadValue::Boolean(b), InputValue::Enum(ref e) => LookAheadValue::Enum(e), InputValue::Variable(ref v) => Self::from_input_value(vars.get(v).unwrap(), vars), - InputValue::List(ref l) => LookAheadValue::List( - l.iter() - .map(|i| LookAheadValue::from_input_value(&i.item, vars)) - .collect(), - ), - InputValue::Object(ref o) => LookAheadValue::Object( - o.iter() - .map(|&(ref n, ref i)| { - ( - &n.item as &str, - LookAheadValue::from_input_value(&i.item, vars), - ) - }) - .collect(), - ), + InputValue::List(ref l) => { + LookAheadValue::List(l.iter() + .map(|i| { + LookAheadValue::from_input_value(&i.item, vars) + }) + .collect()) + } + InputValue::Object(ref o) => { + LookAheadValue::Object(o.iter() + .map(|&(ref n, ref i)| { + (&n.item as &str, + LookAheadValue::from_input_value(&i.item, + vars)) + }) + .collect()) + } } } } @@ -60,15 +61,18 @@ pub struct LookAheadArgument<'a> { } impl<'a> LookAheadArgument<'a> { - fn new( - &(ref name, ref value): &'a (Spanning<&'a str>, Spanning<InputValue>), - vars: &'a Variables, - ) -> Self { + pub(super) fn new(&(ref name, ref value): &'a (Spanning<&'a str>, Spanning<InputValue>), + vars: &'a Variables) + -> Self { LookAheadArgument { name: name.item, value: LookAheadValue::from_input_value(&value.item, vars), } } + + pub fn value(&'a self) -> &LookAheadValue<'a> { + &self.value + } } #[derive(Debug, Clone, PartialEq)] @@ -89,61 +93,58 @@ impl<'a> LookAheadSelection<'a> { fn should_include(directives: Option<&Vec<Spanning<Directive>>>, vars: &Variables) -> bool { directives .map(|d| { - d.iter().all(|d| { - let d = &d.item; - let arguments = &d.arguments; - match (d.name.item, arguments) { - ("include", &Some(ref a)) => a.item - .items - .iter() - .find(|item| item.0.item == "if") - .map(|&(_, ref v)| { - if let LookAheadValue::Boolean(b) = - LookAheadValue::from_input_value(&v.item, vars) - { - b - } else { - false - } - }) - .unwrap_or(false), - ("skip", &Some(ref a)) => a.item - .items - .iter() - .find(|item| item.0.item == "if") - .map(|&(_, ref v)| { - if let LookAheadValue::Boolean(b) = - LookAheadValue::from_input_value(&v.item, vars) - { - !b - } else { - false - } - }) - .unwrap_or(false), - ("skip", &None) => false, - ("include", &None) => true, - (_, _) => unreachable!(), - } - }) + d.iter() + .all(|d| { + let d = &d.item; + let arguments = &d.arguments; + match (d.name.item, arguments) { + ("include", &Some(ref a)) => { + a.item + .items + .iter() + .find(|item| item.0.item == "if") + .map(|&(_, ref v)| if let LookAheadValue::Boolean(b) = + LookAheadValue::from_input_value(&v.item, vars) { + b + } else { + false + }) + .unwrap_or(false) + } + ("skip", &Some(ref a)) => { + a.item + .items + .iter() + .find(|item| item.0.item == "if") + .map(|&(_, ref v)| if let LookAheadValue::Boolean(b) = + LookAheadValue::from_input_value(&v.item, vars) { + !b + } else { + false + }) + .unwrap_or(false) + } + ("skip", &None) => false, + ("include", &None) => true, + (_, _) => unreachable!(), + } + }) }) .unwrap_or(true) } - pub(super) fn build_from_selection( - s: &'a Selection<'a>, - vars: &'a Variables, - fragments: &'a HashMap<&'a str, &'a Fragment<'a>>, - ) -> LookAheadSelection<'a> { + pub(super) fn build_from_selection(s: &'a Selection<'a>, + vars: &'a Variables, + fragments: &'a HashMap<&'a str, &'a Fragment<'a>>) + -> LookAheadSelection<'a> { Self::build_from_selection_with_parent(s, None, vars, fragments).unwrap() } - fn build_from_selection_with_parent( - s: &'a Selection<'a>, - parent: Option<&mut Self>, - vars: &'a Variables, - fragments: &'a HashMap<&'a str, &'a Fragment<'a>>, - ) -> Option<LookAheadSelection<'a>> { + fn build_from_selection_with_parent(s: &'a Selection<'a>, + parent: Option<&mut Self>, + vars: &'a Variables, + fragments: &'a HashMap<&'a str, &'a Fragment<'a>>) + -> Option<LookAheadSelection<'a>> { let empty: &[Selection] = &[]; match *s { Selection::Field(ref field) => { @@ -159,11 +160,11 @@ impl<'a> LookAheadSelection<'a> { .as_ref() .map(|a| &a.item) .map(|a| { - a.items - .iter() - .map(|p| LookAheadArgument::new(p, vars)) - .collect() - }) + a.items + .iter() + .map(|p| LookAheadArgument::new(p, vars)) + .collect() + }) .unwrap_or_else(Vec::new); let mut ret = LookAheadSelection { name, @@ -172,25 +173,23 @@ impl<'a> LookAheadSelection<'a> { childs: Vec::new(), }; for c in field - .selection_set - .as_ref() - .map(|s| s as &[_]) - .unwrap_or_else(|| empty) - .iter() - { - let s = LookAheadSelection::build_from_selection_with_parent( - c, - Some(&mut ret), - vars, - fragments, - ); + .selection_set + .as_ref() + .map(|s| s as &[_]) + .unwrap_or_else(|| empty) + .iter() { + let s = LookAheadSelection::build_from_selection_with_parent(c, + Some(&mut ret), + vars, + fragments); assert!(s.is_none()); } if let Some(p) = parent { - p.childs.push(ChildSelection { - inner: ret, - applies_for: Applies::All, - }); + p.childs + .push(ChildSelection { + inner: ret, + applies_for: Applies::All, + }); None } else { Some(ret) @@ -204,12 +203,10 @@ impl<'a> LookAheadSelection<'a> { let parent = parent.unwrap(); let f = fragments.get(&fragment.item.name.item).unwrap(); for c in f.selection_set.iter() { - let s = LookAheadSelection::build_from_selection_with_parent( - c, - Some(parent), - vars, - fragments, - ); + let s = LookAheadSelection::build_from_selection_with_parent(c, + Some(parent), + vars, + fragments); assert!(s.is_none()); } None @@ -221,12 +218,10 @@ impl<'a> LookAheadSelection<'a> { } let parent = parent.unwrap(); for c in inline.item.selection_set.iter() { - let s = LookAheadSelection::build_from_selection_with_parent( - c, - Some(parent), - vars, - fragments, - ); + let s = LookAheadSelection::build_from_selection_with_parent(c, + Some(parent), + vars, + fragments); assert!(s.is_none()); if let Some(ref c) = inline.item.type_condition.as_ref().map(|t| t.item) { if let Some(p) = parent.childs.last_mut() { @@ -245,18 +240,26 @@ impl<'a> LookAheadSelection<'a> { childs: self.childs .iter() .filter_map(|c| match c.applies_for { - Applies::OnlyType(ref t) if *t == type_name => { - Some(c.inner.for_explicit_type(type_name)) - } - Applies::All => Some(c.inner.for_explicit_type(type_name)), - Applies::OnlyType(_) => None, - }) + Applies::OnlyType(ref t) if *t == type_name => { + Some(c.inner.for_explicit_type(type_name)) + } + Applies::All => Some(c.inner.for_explicit_type(type_name)), + Applies::OnlyType(_) => None, + }) .collect(), name: self.name, alias: self.alias, arguments: self.arguments.clone(), } } + + pub fn arguments(&self) -> &[LookAheadArgument] { + &self.arguments + } + + pub fn argument(&self, name: &str) -> Option<&LookAheadArgument> { + self.arguments.iter().find(|a| a.name == name) + } } #[derive(Debug, PartialEq)] @@ -283,7 +286,7 @@ impl<'a> LookAheadMethods for ConcreteLookAheadSelection<'a> { } fn select_child(&self, name: &str) -> Option<&Self> { - self.childs.iter().find(|c| c.name == name) + self.childs.iter().find(|c| c.name == name) } } @@ -293,7 +296,10 @@ impl<'a> LookAheadMethods for LookAheadSelection<'a> { } fn select_child(&self, name: &str) -> Option<&Self> { - self.childs.iter().find(|c| c.inner.name == name).map(|s| &s.inner) + self.childs + .iter() + .find(|c| c.inner.name == name) + .map(|s| &s.inner) } } @@ -316,49 +322,44 @@ mod tests { #[test] fn check_simple_query() { - let docs = ::parse_document_source( - " + let docs = ::parse_document_source(" query Hero { hero { id name } } -", - ).unwrap(); +") + .unwrap(); let fragments = extract_fragments(&docs); if let ::ast::Definition::Operation(ref op) = docs[0] { let vars = Variables::default(); - let look_ahead = LookAheadSelection::build_from_selection( - &op.item.selection_set[0], - &vars, - &fragments, - ); + let look_ahead = LookAheadSelection::build_from_selection(&op.item.selection_set[0], + &vars, + &fragments); let expected = LookAheadSelection { name: "hero", alias: None, arguments: Vec::new(), - childs: vec![ - ChildSelection { - inner: LookAheadSelection { - name: "id", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ChildSelection { - inner: LookAheadSelection { - name: "name", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ], + childs: vec![ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }], }; assert_eq!(look_ahead, expected); } else { @@ -368,49 +369,44 @@ query Hero { #[test] fn check_query_with_alias() { - let docs = ::parse_document_source( - " + let docs = ::parse_document_source(" query Hero { custom_hero: hero { id my_name: name } } -", - ).unwrap(); +") + .unwrap(); let fragments = extract_fragments(&docs); if let ::ast::Definition::Operation(ref op) = docs[0] { let vars = Variables::default(); - let look_ahead = LookAheadSelection::build_from_selection( - &op.item.selection_set[0], - &vars, - &fragments, - ); + let look_ahead = LookAheadSelection::build_from_selection(&op.item.selection_set[0], + &vars, + &fragments); let expected = LookAheadSelection { name: "hero", alias: Some("custom_hero"), arguments: Vec::new(), - childs: vec![ - ChildSelection { - inner: LookAheadSelection { - name: "id", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ChildSelection { - inner: LookAheadSelection { - name: "name", - alias: Some("my_name"), - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ], + childs: vec![ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: Some("my_name"), + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }], }; assert_eq!(look_ahead, expected); } else { @@ -420,8 +416,7 @@ query Hero { #[test] fn check_query_with_child() { - let docs = ::parse_document_source( - " + let docs = ::parse_document_source(" query Hero { hero { id @@ -432,69 +427,63 @@ query Hero { } } } -", - ).unwrap(); +") + .unwrap(); let fragments = extract_fragments(&docs); if let ::ast::Definition::Operation(ref op) = docs[0] { let vars = Variables::default(); - let look_ahead = LookAheadSelection::build_from_selection( - &op.item.selection_set[0], - &vars, - &fragments, - ); + let look_ahead = LookAheadSelection::build_from_selection(&op.item.selection_set[0], + &vars, + &fragments); let expected = LookAheadSelection { name: "hero", alias: None, arguments: Vec::new(), - childs: vec![ - ChildSelection { - inner: LookAheadSelection { - name: "id", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ChildSelection { - inner: LookAheadSelection { - name: "name", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ChildSelection { - inner: LookAheadSelection { - name: "friends", - alias: None, - arguments: Vec::new(), - childs: vec![ - ChildSelection { - inner: LookAheadSelection { - name: "name", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ChildSelection { - inner: LookAheadSelection { - name: "id", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ], - }, - applies_for: Applies::All, - }, - ], + childs: vec![ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "friends", + alias: None, + arguments: Vec::new(), + childs: vec![ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }], + }, + applies_for: Applies::All, + }], }; assert_eq!(look_ahead, expected); } else { @@ -504,59 +493,50 @@ query Hero { #[test] fn check_query_with_argument() { - let docs = ::parse_document_source( - " + let docs = ::parse_document_source(" query Hero { hero(episode: EMPIRE) { id name(uppercase: true) } } -", - ).unwrap(); +") + .unwrap(); let fragments = extract_fragments(&docs); if let ::ast::Definition::Operation(ref op) = docs[0] { let vars = Variables::default(); - let look_ahead = LookAheadSelection::build_from_selection( - &op.item.selection_set[0], - &vars, - &fragments, - ); + let look_ahead = LookAheadSelection::build_from_selection(&op.item.selection_set[0], + &vars, + &fragments); let expected = LookAheadSelection { name: "hero", alias: None, - arguments: vec![ - LookAheadArgument { - name: "episode", - value: LookAheadValue::Enum("EMPIRE"), - }, - ], - childs: vec![ - ChildSelection { - inner: LookAheadSelection { - name: "id", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ChildSelection { - inner: LookAheadSelection { - name: "name", - alias: None, - arguments: vec![ - LookAheadArgument { - name: "uppercase", - value: LookAheadValue::Boolean(true), - }, - ], - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ], + arguments: vec![LookAheadArgument { + name: "episode", + value: LookAheadValue::Enum("EMPIRE"), + }], + childs: vec![ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: vec![LookAheadArgument { + name: "uppercase", + value: LookAheadValue::Boolean(true), + }], + childs: Vec::new(), + }, + applies_for: Applies::All, + }], }; assert_eq!(look_ahead, expected); } else { @@ -566,55 +546,48 @@ query Hero { #[test] fn check_query_with_variable() { - let docs = ::parse_document_source( - " + let docs = ::parse_document_source(" query Hero($episode: Episode) { hero(episode: $episode) { id name } } -", - ).unwrap(); +") + .unwrap(); let fragments = extract_fragments(&docs); if let ::ast::Definition::Operation(ref op) = docs[0] { let mut vars = Variables::default(); vars.insert("episode".into(), InputValue::Enum("JEDI".into())); - let look_ahead = LookAheadSelection::build_from_selection( - &op.item.selection_set[0], - &vars, - &fragments, - ); + let look_ahead = LookAheadSelection::build_from_selection(&op.item.selection_set[0], + &vars, + &fragments); let expected = LookAheadSelection { name: "hero", alias: None, - arguments: vec![ - LookAheadArgument { - name: "episode", - value: LookAheadValue::Enum("JEDI"), - }, - ], - childs: vec![ - ChildSelection { - inner: LookAheadSelection { - name: "id", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ChildSelection { - inner: LookAheadSelection { - name: "name", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ], + arguments: vec![LookAheadArgument { + name: "episode", + value: LookAheadValue::Enum("JEDI"), + }], + childs: vec![ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }], }; assert_eq!(look_ahead, expected); } else { @@ -624,8 +597,7 @@ query Hero($episode: Episode) { #[test] fn check_query_with_fragment() { - let docs = ::parse_document_source( - " + let docs = ::parse_document_source(" query Hero { hero { id @@ -637,50 +609,46 @@ fragment commonFields on Character { name appearsIn } -", - ).unwrap(); +") + .unwrap(); let fragments = extract_fragments(&docs); if let ::ast::Definition::Operation(ref op) = docs[0] { let vars = Variables::default(); - let look_ahead = LookAheadSelection::build_from_selection( - &op.item.selection_set[0], - &vars, - &fragments, - ); + let look_ahead = LookAheadSelection::build_from_selection(&op.item.selection_set[0], + &vars, + &fragments); let expected = LookAheadSelection { name: "hero", alias: None, arguments: Vec::new(), - childs: vec![ - ChildSelection { - inner: LookAheadSelection { - name: "id", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ChildSelection { - inner: LookAheadSelection { - name: "name", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ChildSelection { - inner: LookAheadSelection { - name: "appearsIn", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ], + childs: vec![ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "appearsIn", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }], }; assert_eq!(look_ahead, expected); } else { @@ -690,8 +658,7 @@ fragment commonFields on Character { #[test] fn check_query_with_directives() { - let docs = ::parse_document_source( - " + let docs = ::parse_document_source(" query Hero { hero { id @include(if: true) @@ -699,41 +666,37 @@ query Hero { appearsIn @skip(if: true) height @skip(if: false) } -}", - ).unwrap(); +}") + .unwrap(); let fragments = extract_fragments(&docs); if let ::ast::Definition::Operation(ref op) = docs[0] { let vars = Variables::default(); - let look_ahead = LookAheadSelection::build_from_selection( - &op.item.selection_set[0], - &vars, - &fragments, - ); + let look_ahead = LookAheadSelection::build_from_selection(&op.item.selection_set[0], + &vars, + &fragments); let expected = LookAheadSelection { name: "hero", alias: None, arguments: Vec::new(), - childs: vec![ - ChildSelection { - inner: LookAheadSelection { - name: "id", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ChildSelection { - inner: LookAheadSelection { - name: "height", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ], + childs: vec![ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "height", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }], }; assert_eq!(look_ahead, expected); } else { @@ -743,8 +706,7 @@ query Hero { #[test] fn check_query_with_inline_fragments() { - let docs = ::parse_document_source( - " + let docs = ::parse_document_source(" query Hero { hero { name @@ -755,50 +717,46 @@ query Hero { height } } -}", - ).unwrap(); +}") + .unwrap(); let fragments = extract_fragments(&docs); if let ::ast::Definition::Operation(ref op) = docs[0] { let vars = Variables::default(); - let look_ahead = LookAheadSelection::build_from_selection( - &op.item.selection_set[0], - &vars, - &fragments, - ); + let look_ahead = LookAheadSelection::build_from_selection(&op.item.selection_set[0], + &vars, + &fragments); let expected = LookAheadSelection { name: "hero", alias: None, arguments: Vec::new(), - childs: vec![ - ChildSelection { - inner: LookAheadSelection { - name: "name", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ChildSelection { - inner: LookAheadSelection { - name: "primaryFunction", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::OnlyType("Droid"), - }, - ChildSelection { - inner: LookAheadSelection { - name: "height", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::OnlyType("Human"), - }, - ], + childs: vec![ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "primaryFunction", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::OnlyType("Droid"), + }, + ChildSelection { + inner: LookAheadSelection { + name: "height", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::OnlyType("Human"), + }], }; assert_eq!(look_ahead, expected); } else { @@ -808,8 +766,7 @@ query Hero { #[test] fn check_complex_query() { - let docs = ::parse_document_source( - " + let docs = ::parse_document_source(" query HeroNameAndFriends($id: Integer!, $withFriends: Boolean! = true) { hero(id: $id) { id @@ -827,8 +784,8 @@ fragment comparisonFields on Character { appearsIn ... on Droid { primaryFunction } ... on Human { height } -}", - ).unwrap(); +}") + .unwrap(); let fragments = extract_fragments(&docs); if let ::ast::Definition::Operation(ref op) = docs[0] { @@ -836,131 +793,123 @@ fragment comparisonFields on Character { vars.insert("id".into(), InputValue::Int(42)); // This will normally be there vars.insert("withFriends".into(), InputValue::Boolean(true)); - let look_ahead = LookAheadSelection::build_from_selection( - &op.item.selection_set[0], - &vars, - &fragments, - ); + let look_ahead = LookAheadSelection::build_from_selection(&op.item.selection_set[0], + &vars, + &fragments); let expected = LookAheadSelection { name: "hero", alias: None, - arguments: vec![ - LookAheadArgument { - name: "id", - value: LookAheadValue::Int(42), - }, - ], - childs: vec![ - ChildSelection { - inner: LookAheadSelection { - name: "id", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ChildSelection { - inner: LookAheadSelection { - name: "__typename", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ChildSelection { - inner: LookAheadSelection { - name: "name", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ChildSelection { - inner: LookAheadSelection { - name: "appearsIn", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ChildSelection { - inner: LookAheadSelection { - name: "primaryFunction", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::OnlyType("Droid"), - }, - ChildSelection { - inner: LookAheadSelection { - name: "height", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::OnlyType("Human"), - }, - ChildSelection { - inner: LookAheadSelection { - name: "friends", - alias: None, - arguments: Vec::new(), - childs: vec![ - ChildSelection { - inner: LookAheadSelection { - name: "__typename", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ChildSelection { - inner: LookAheadSelection { - name: "name", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ChildSelection { - inner: LookAheadSelection { - name: "appearsIn", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ChildSelection { - inner: LookAheadSelection { - name: "primaryFunction", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::OnlyType("Droid"), - }, - ChildSelection { - inner: LookAheadSelection { - name: "height", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::OnlyType("Human"), - }, - ], - }, - applies_for: Applies::All, - }, - ], + arguments: vec![LookAheadArgument { + name: "id", + value: LookAheadValue::Int(42), + }], + childs: vec![ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "__typename", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "appearsIn", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "primaryFunction", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::OnlyType("Droid"), + }, + ChildSelection { + inner: LookAheadSelection { + name: "height", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::OnlyType("Human"), + }, + ChildSelection { + inner: LookAheadSelection { + name: "friends", + alias: None, + arguments: Vec::new(), + childs: vec![ChildSelection { + inner: LookAheadSelection { + name: "__typename", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "appearsIn", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "primaryFunction", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::OnlyType("Droid"), + }, + ChildSelection { + inner: LookAheadSelection { + name: "height", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::OnlyType("Human"), + }], + }, + applies_for: Applies::All, + }], }; assert_eq!(look_ahead, expected); } else { @@ -970,8 +919,7 @@ fragment comparisonFields on Character { #[test] fn check_resolve_concrete_type() { - let docs = ::parse_document_source( - " + let docs = ::parse_document_source(" query Hero { hero { name @@ -982,35 +930,32 @@ query Hero { height } } -}", - ).unwrap(); +}") + .unwrap(); let fragments = extract_fragments(&docs); if let ::ast::Definition::Operation(ref op) = docs[0] { let vars = Variables::default(); - let look_ahead = LookAheadSelection::build_from_selection( - &op.item.selection_set[0], - &vars, - &fragments, - ).for_explicit_type("Human"); + let look_ahead = LookAheadSelection::build_from_selection(&op.item.selection_set[0], + &vars, + &fragments) + .for_explicit_type("Human"); let expected = ConcreteLookAheadSelection { name: "hero", alias: None, arguments: Vec::new(), - childs: vec![ - ConcreteLookAheadSelection { - name: "name", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - ConcreteLookAheadSelection { - name: "height", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - ], + childs: vec![ConcreteLookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + ConcreteLookAheadSelection { + name: "height", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }], }; assert_eq!(look_ahead, expected); } else { @@ -1020,87 +965,88 @@ query Hero { #[test] fn check_select_child() { - let lookahead = LookAheadSelection{ + let lookahead = LookAheadSelection { name: "hero", alias: None, arguments: Vec::new(), - childs: vec![ - ChildSelection{ - inner: LookAheadSelection { - name: "id", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All, - }, - ChildSelection { - inner: LookAheadSelection { - name: "friends", - alias: None, - arguments: Vec::new(), - childs: vec![ - ChildSelection { - inner: LookAheadSelection { - name: "id", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All - }, - ChildSelection { - inner: LookAheadSelection { - name: "name", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All - } - ], - }, - applies_for: Applies::All - } - ] + childs: vec![ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "friends", + alias: None, + arguments: Vec::new(), + childs: vec![ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }], + }, + applies_for: Applies::All, + }], }; let concret_query = lookahead.for_explicit_type("does not matter"); let id = lookahead.select_child("id"); let concrete_id = concret_query.select_child("id"); - let expected = LookAheadSelection{name: "id", alias: None, arguments: Vec::new(), childs: Vec::new()}; + let expected = LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }; assert_eq!(id, Some(&expected)); - assert_eq!(concrete_id, Some(&expected.for_explicit_type("does not matter"))); + assert_eq!(concrete_id, + Some(&expected.for_explicit_type("does not matter"))); let friends = lookahead.select_child("friends"); let concrete_friends = concret_query.select_child("friends"); - let expected = LookAheadSelection { - name: "friends", - alias: None, - arguments: Vec::new(), - childs: vec![ - ChildSelection { - inner: LookAheadSelection { - name: "id", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All - }, - ChildSelection { - inner: LookAheadSelection { - name: "name", - alias: None, - arguments: Vec::new(), - childs: Vec::new(), - }, - applies_for: Applies::All - } - ], - }; + let expected = LookAheadSelection { + name: "friends", + alias: None, + arguments: Vec::new(), + childs: vec![ChildSelection { + inner: LookAheadSelection { + name: "id", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }, + ChildSelection { + inner: LookAheadSelection { + name: "name", + alias: None, + arguments: Vec::new(), + childs: Vec::new(), + }, + applies_for: Applies::All, + }], + }; assert_eq!(friends, Some(&expected)); - assert_eq!(concrete_friends, Some(&expected.for_explicit_type("does not matter"))); + assert_eq!(concrete_friends, + Some(&expected.for_explicit_type("does not matter"))); } } diff --git a/juniper/src/executor/mod.rs b/juniper/src/executor/mod.rs index b935bb50..1da04903 100644 --- a/juniper/src/executor/mod.rs +++ b/juniper/src/executor/mod.rs @@ -11,6 +11,10 @@ use ast::{Definition, Document, Fragment, FromInputValue, InputValue, OperationT use parser::SourcePosition; use value::Value; use GraphQLError; +use ast::{Definition, Document, Fragment, FromInputValue, InputValue, OperationType, + Selection, ToInputValue, Type}; +use value::Value; +use parser::SourcePosition; use schema::meta::{Argument, EnumMeta, EnumValue, Field, InputObjectMeta, InterfaceMeta, ListMeta, MetaType, NullableMeta, ObjectMeta, PlaceholderMeta, ScalarMeta, UnionMeta}; @@ -50,6 +54,7 @@ where fragments: &'a HashMap<&'a str, &'a Fragment<'a>>, variables: &'a Variables, current_selection_set: Option<&'a [Selection<'a>]>, + parent_selection_set: Option<&'a [Selection<'a>]>, current_type: TypeType<'a>, schema: &'a SchemaType<'a>, context: &'a CtxT, @@ -319,6 +324,7 @@ impl<'a, CtxT> Executor<'a, CtxT> { fragments: self.fragments, variables: self.variables, current_selection_set: self.current_selection_set, + parent_selection_set: self.parent_selection_set, current_type: self.current_type.clone(), schema: self.schema, context: ctx, @@ -340,6 +346,7 @@ impl<'a, CtxT> Executor<'a, CtxT> { fragments: self.fragments, variables: self.variables, current_selection_set: selection_set, + parent_selection_set: self.current_selection_set, current_type: self.schema.make_type( &self.current_type .innermost_concrete() @@ -351,7 +358,7 @@ impl<'a, CtxT> Executor<'a, CtxT> { context: self.context, errors: self.errors, field_path: FieldPath::Field(field_alias, location, &self.field_path), - type_name: self.type_name + type_name: self.type_name, } } @@ -365,6 +372,7 @@ impl<'a, CtxT> Executor<'a, CtxT> { fragments: self.fragments, variables: self.variables, current_selection_set: selection_set, + parent_selection_set: self.current_selection_set, current_type: match type_name { Some(type_name) => self.schema.type_by_name(type_name).expect("Type not found"), None => self.current_type.clone(), @@ -430,16 +438,20 @@ impl<'a, CtxT> Executor<'a, CtxT> { }); } - pub fn look_ahead(&self) -> LookAheadSelection { - LookAheadSelection{ - name: self.type_name, - alias: None, - arguments: Vec::new(), - childs: self.current_selection_set.map(|s| s.iter().map(|s| ChildSelection { - inner: LookAheadSelection::build_from_selection(s, self.variables, self.fragments), - applies_for: Applies::All - }).collect()).unwrap_or_else(Vec::new) - } + pub fn look_ahead(&'a self) -> LookAheadSelection<'a> { + self.parent_selection_set.map(|p| { + LookAheadSelection::build_from_selection(&p[0], self.variables, self.fragments) + }).unwrap_or_else(||{ + LookAheadSelection{ + name: self.current_type.innermost_concrete().name().unwrap_or(""), + alias: None, + arguments: Vec::new(), + childs: self.current_selection_set.map(|s| s.iter().map(|s| ChildSelection { + inner: LookAheadSelection::build_from_selection(s, self.variables, self.fragments), + applies_for: Applies::All + }).collect()).unwrap_or_else(Vec::new) + } + }) } } @@ -568,6 +580,7 @@ where .collect(), variables: final_vars, current_selection_set: Some(&op.item.selection_set[..]), + parent_selection_set: None, current_type: root_type, schema: &root_node.schema, context: context, From da9c21ccfe47179f48bd6594bf180ef09c3ed766 Mon Sep 17 00:00:00 2001 From: Georg Semmler <georg_semmler_05@web.de> Date: Thu, 19 Apr 2018 15:09:00 +0200 Subject: [PATCH 12/18] Add some documentation to the lookahead feature --- juniper/src/executor/look_ahead.rs | 43 +++++++++++++++++++++++------- juniper/src/executor/mod.rs | 6 ++++- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/juniper/src/executor/look_ahead.rs b/juniper/src/executor/look_ahead.rs index 8c8e9159..6b27ff98 100644 --- a/juniper/src/executor/look_ahead.rs +++ b/juniper/src/executor/look_ahead.rs @@ -5,20 +5,28 @@ use std::collections::HashMap; use super::Variables; +/// An enum that describes if a field is available in all types of the interface +/// or only in a certain subtype #[derive(Debug, Clone, PartialEq)] pub enum Applies<'a> { + /// The field is available independent from the type All, + /// The field is only available for a given typename OnlyType(&'a str), } +/// A JSON-like value that can is used as argument in the query execution +/// +/// In contrast to `InputValue` these values do only contain constants, +/// meaning that variables are already resolved. #[derive(Debug, Clone, PartialEq)] +#[allow(missing_docs)] pub enum LookAheadValue<'a> { Null, Int(i32), Float(f64), String(&'a str), Boolean(bool), - // TODO: improve Enum(&'a str), List(Vec<LookAheadValue<'a>>), Object(Vec<(&'a str, LookAheadValue<'a>)>), @@ -54,6 +62,7 @@ impl<'a> LookAheadValue<'a> { } } +/// An argument passed into the query #[derive(Debug, Clone, PartialEq)] pub struct LookAheadArgument<'a> { name: &'a str, @@ -70,6 +79,7 @@ impl<'a> LookAheadArgument<'a> { } } + /// The value of the argument pub fn value(&'a self) -> &LookAheadValue<'a> { &self.value } @@ -81,6 +91,7 @@ pub struct ChildSelection<'a> { pub(super) applies_for: Applies<'a>, } +/// A selection performed by a query #[derive(Debug, Clone, PartialEq)] pub struct LookAheadSelection<'a> { pub(super) name: &'a str, @@ -235,6 +246,7 @@ impl<'a> LookAheadSelection<'a> { } } + /// Convert a eventually type independent selection into one for a concrete type pub fn for_explicit_type(&self, type_name: &str) -> ConcreteLookAheadSelection<'a> { ConcreteLookAheadSelection { childs: self.childs @@ -252,16 +264,9 @@ impl<'a> LookAheadSelection<'a> { arguments: self.arguments.clone(), } } - - pub fn arguments(&self) -> &[LookAheadArgument] { - &self.arguments - } - - pub fn argument(&self, name: &str) -> Option<&LookAheadArgument> { - self.arguments.iter().find(|a| a.name == name) - } } +/// A selection performed by a query on a concrete type #[derive(Debug, PartialEq)] pub struct ConcreteLookAheadSelection<'a> { name: &'a str, @@ -270,14 +275,26 @@ pub struct ConcreteLookAheadSelection<'a> { childs: Vec<ConcreteLookAheadSelection<'a>>, } +/// A set of common methods for `ConcreteLookAheadSelection` and `LookAheadSelection` pub trait LookAheadMethods { + /// Get the name of the field represented by the current selection fn field_name(&self) -> &str; + /// Get the the child selection for a given field fn select_child(&self, name: &str) -> Option<&Self>; + /// Check if a given field exists fn has_child(&self, name: &str) -> bool { self.select_child(name).is_some() } + + /// Get the top level arguments for the current selection + fn arguments(&self) -> &[LookAheadArgument]; + + /// Get the top level argument with a given name from the current selection + fn argument(&self, name: &str) -> Option<&LookAheadArgument> { + self.arguments().iter().find(|a| a.name == name) + } } impl<'a> LookAheadMethods for ConcreteLookAheadSelection<'a> { @@ -288,6 +305,10 @@ impl<'a> LookAheadMethods for ConcreteLookAheadSelection<'a> { fn select_child(&self, name: &str) -> Option<&Self> { self.childs.iter().find(|c| c.name == name) } + + fn arguments(&self) -> &[LookAheadArgument] { + &self.arguments + } } impl<'a> LookAheadMethods for LookAheadSelection<'a> { @@ -301,6 +322,10 @@ impl<'a> LookAheadMethods for LookAheadSelection<'a> { .find(|c| c.inner.name == name) .map(|s| &s.inner) } + + fn arguments(&self) -> &[LookAheadArgument] { + &self.arguments + } } #[cfg(test)] diff --git a/juniper/src/executor/mod.rs b/juniper/src/executor/mod.rs index 1da04903..efeb56aa 100644 --- a/juniper/src/executor/mod.rs +++ b/juniper/src/executor/mod.rs @@ -25,7 +25,7 @@ use types::name::Name; mod look_ahead; -pub use self::look_ahead::{Applies, LookAheadArgument, LookAheadSelection, LookAheadValue, LookAheadMethods, ChildSelection}; +pub use self::look_ahead::{Applies, LookAheadArgument, LookAheadSelection, LookAheadValue, LookAheadMethods, ChildSelection, ConcreteLookAheadSelection}; /// A type registry used to build schemas /// @@ -438,6 +438,10 @@ impl<'a, CtxT> Executor<'a, CtxT> { }); } + /// Construct a lookahead selection for the current selection + /// + /// This allows to see the whole selection and preform operations + /// affecting the childs pub fn look_ahead(&'a self) -> LookAheadSelection<'a> { self.parent_selection_set.map(|p| { LookAheadSelection::build_from_selection(&p[0], self.variables, self.fragments) From cfc31091091a9130760c6d7174aaf5d00d7e050b Mon Sep 17 00:00:00 2001 From: Georg Semmler <georg_semmler_05@web.de> Date: Thu, 19 Apr 2018 15:15:22 +0200 Subject: [PATCH 13/18] Rename childs to children --- juniper/src/executor/look_ahead.rs | 124 ++++++++++++++--------------- juniper/src/executor/mod.rs | 2 +- 2 files changed, 63 insertions(+), 63 deletions(-) diff --git a/juniper/src/executor/look_ahead.rs b/juniper/src/executor/look_ahead.rs index 6b27ff98..44744716 100644 --- a/juniper/src/executor/look_ahead.rs +++ b/juniper/src/executor/look_ahead.rs @@ -97,7 +97,7 @@ pub struct LookAheadSelection<'a> { pub(super) name: &'a str, pub(super) alias: Option<&'a str>, pub(super) arguments: Vec<LookAheadArgument<'a>>, - pub(super) childs: Vec<ChildSelection<'a>>, + pub(super) children: Vec<ChildSelection<'a>>, } impl<'a> LookAheadSelection<'a> { @@ -181,7 +181,7 @@ impl<'a> LookAheadSelection<'a> { name, alias, arguments, - childs: Vec::new(), + children: Vec::new(), }; for c in field .selection_set @@ -196,7 +196,7 @@ impl<'a> LookAheadSelection<'a> { assert!(s.is_none()); } if let Some(p) = parent { - p.childs + p.children .push(ChildSelection { inner: ret, applies_for: Applies::All, @@ -235,7 +235,7 @@ impl<'a> LookAheadSelection<'a> { fragments); assert!(s.is_none()); if let Some(ref c) = inline.item.type_condition.as_ref().map(|t| t.item) { - if let Some(p) = parent.childs.last_mut() { + if let Some(p) = parent.children.last_mut() { p.applies_for = Applies::OnlyType(c); } } @@ -249,7 +249,7 @@ impl<'a> LookAheadSelection<'a> { /// Convert a eventually type independent selection into one for a concrete type pub fn for_explicit_type(&self, type_name: &str) -> ConcreteLookAheadSelection<'a> { ConcreteLookAheadSelection { - childs: self.childs + children: self.children .iter() .filter_map(|c| match c.applies_for { Applies::OnlyType(ref t) if *t == type_name => { @@ -272,7 +272,7 @@ pub struct ConcreteLookAheadSelection<'a> { name: &'a str, alias: Option<&'a str>, arguments: Vec<LookAheadArgument<'a>>, - childs: Vec<ConcreteLookAheadSelection<'a>>, + children: Vec<ConcreteLookAheadSelection<'a>>, } /// A set of common methods for `ConcreteLookAheadSelection` and `LookAheadSelection` @@ -303,7 +303,7 @@ impl<'a> LookAheadMethods for ConcreteLookAheadSelection<'a> { } fn select_child(&self, name: &str) -> Option<&Self> { - self.childs.iter().find(|c| c.name == name) + self.children.iter().find(|c| c.name == name) } fn arguments(&self) -> &[LookAheadArgument] { @@ -317,7 +317,7 @@ impl<'a> LookAheadMethods for LookAheadSelection<'a> { } fn select_child(&self, name: &str) -> Option<&Self> { - self.childs + self.children .iter() .find(|c| c.inner.name == name) .map(|s| &s.inner) @@ -367,12 +367,12 @@ query Hero { name: "hero", alias: None, arguments: Vec::new(), - childs: vec![ChildSelection { + children: vec![ChildSelection { inner: LookAheadSelection { name: "id", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }, @@ -381,7 +381,7 @@ query Hero { name: "name", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }], @@ -414,12 +414,12 @@ query Hero { name: "hero", alias: Some("custom_hero"), arguments: Vec::new(), - childs: vec![ChildSelection { + children: vec![ChildSelection { inner: LookAheadSelection { name: "id", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }, @@ -428,7 +428,7 @@ query Hero { name: "name", alias: Some("my_name"), arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }], @@ -465,12 +465,12 @@ query Hero { name: "hero", alias: None, arguments: Vec::new(), - childs: vec![ChildSelection { + children: vec![ChildSelection { inner: LookAheadSelection { name: "id", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }, @@ -479,7 +479,7 @@ query Hero { name: "name", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }, @@ -488,12 +488,12 @@ query Hero { name: "friends", alias: None, arguments: Vec::new(), - childs: vec![ChildSelection { + children: vec![ChildSelection { inner: LookAheadSelection { name: "name", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }, @@ -502,7 +502,7 @@ query Hero { name: "id", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }], @@ -541,12 +541,12 @@ query Hero { name: "episode", value: LookAheadValue::Enum("EMPIRE"), }], - childs: vec![ChildSelection { + children: vec![ChildSelection { inner: LookAheadSelection { name: "id", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }, @@ -558,7 +558,7 @@ query Hero { name: "uppercase", value: LookAheadValue::Boolean(true), }], - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }], @@ -595,12 +595,12 @@ query Hero($episode: Episode) { name: "episode", value: LookAheadValue::Enum("JEDI"), }], - childs: vec![ChildSelection { + children: vec![ChildSelection { inner: LookAheadSelection { name: "id", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }, @@ -609,7 +609,7 @@ query Hero($episode: Episode) { name: "name", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }], @@ -647,12 +647,12 @@ fragment commonFields on Character { name: "hero", alias: None, arguments: Vec::new(), - childs: vec![ChildSelection { + children: vec![ChildSelection { inner: LookAheadSelection { name: "id", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }, @@ -661,7 +661,7 @@ fragment commonFields on Character { name: "name", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }, @@ -670,7 +670,7 @@ fragment commonFields on Character { name: "appearsIn", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }], @@ -704,12 +704,12 @@ query Hero { name: "hero", alias: None, arguments: Vec::new(), - childs: vec![ChildSelection { + children: vec![ChildSelection { inner: LookAheadSelection { name: "id", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }, @@ -718,7 +718,7 @@ query Hero { name: "height", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }], @@ -755,12 +755,12 @@ query Hero { name: "hero", alias: None, arguments: Vec::new(), - childs: vec![ChildSelection { + children: vec![ChildSelection { inner: LookAheadSelection { name: "name", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }, @@ -769,7 +769,7 @@ query Hero { name: "primaryFunction", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::OnlyType("Droid"), }, @@ -778,7 +778,7 @@ query Hero { name: "height", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::OnlyType("Human"), }], @@ -828,12 +828,12 @@ fragment comparisonFields on Character { name: "id", value: LookAheadValue::Int(42), }], - childs: vec![ChildSelection { + children: vec![ChildSelection { inner: LookAheadSelection { name: "id", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }, @@ -842,7 +842,7 @@ fragment comparisonFields on Character { name: "__typename", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }, @@ -851,7 +851,7 @@ fragment comparisonFields on Character { name: "name", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }, @@ -860,7 +860,7 @@ fragment comparisonFields on Character { name: "appearsIn", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }, @@ -869,7 +869,7 @@ fragment comparisonFields on Character { name: "primaryFunction", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::OnlyType("Droid"), }, @@ -878,7 +878,7 @@ fragment comparisonFields on Character { name: "height", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::OnlyType("Human"), }, @@ -887,12 +887,12 @@ fragment comparisonFields on Character { name: "friends", alias: None, arguments: Vec::new(), - childs: vec![ChildSelection { + children: vec![ChildSelection { inner: LookAheadSelection { name: "__typename", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }, @@ -901,7 +901,7 @@ fragment comparisonFields on Character { name: "name", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }, @@ -910,7 +910,7 @@ fragment comparisonFields on Character { name: "appearsIn", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }, @@ -919,7 +919,7 @@ fragment comparisonFields on Character { name: "primaryFunction", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::OnlyType("Droid"), }, @@ -928,7 +928,7 @@ fragment comparisonFields on Character { name: "height", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::OnlyType("Human"), }], @@ -969,17 +969,17 @@ query Hero { name: "hero", alias: None, arguments: Vec::new(), - childs: vec![ConcreteLookAheadSelection { + children: vec![ConcreteLookAheadSelection { name: "name", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, ConcreteLookAheadSelection { name: "height", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }], }; assert_eq!(look_ahead, expected); @@ -994,12 +994,12 @@ query Hero { name: "hero", alias: None, arguments: Vec::new(), - childs: vec![ChildSelection { + children: vec![ChildSelection { inner: LookAheadSelection { name: "id", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }, @@ -1008,12 +1008,12 @@ query Hero { name: "friends", alias: None, arguments: Vec::new(), - childs: vec![ChildSelection { + children: vec![ChildSelection { inner: LookAheadSelection { name: "id", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }, @@ -1022,7 +1022,7 @@ query Hero { name: "name", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }], @@ -1038,7 +1038,7 @@ query Hero { name: "id", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }; assert_eq!(id, Some(&expected)); assert_eq!(concrete_id, @@ -1050,12 +1050,12 @@ query Hero { name: "friends", alias: None, arguments: Vec::new(), - childs: vec![ChildSelection { + children: vec![ChildSelection { inner: LookAheadSelection { name: "id", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }, @@ -1064,7 +1064,7 @@ query Hero { name: "name", alias: None, arguments: Vec::new(), - childs: Vec::new(), + children: Vec::new(), }, applies_for: Applies::All, }], diff --git a/juniper/src/executor/mod.rs b/juniper/src/executor/mod.rs index efeb56aa..55c5b39e 100644 --- a/juniper/src/executor/mod.rs +++ b/juniper/src/executor/mod.rs @@ -450,7 +450,7 @@ impl<'a, CtxT> Executor<'a, CtxT> { name: self.current_type.innermost_concrete().name().unwrap_or(""), alias: None, arguments: Vec::new(), - childs: self.current_selection_set.map(|s| s.iter().map(|s| ChildSelection { + children: self.current_selection_set.map(|s| s.iter().map(|s| ChildSelection { inner: LookAheadSelection::build_from_selection(s, self.variables, self.fragments), applies_for: Applies::All }).collect()).unwrap_or_else(Vec::new) From 19e76865c9440c07c7b5bad1bc51ffd3269ea703 Mon Sep 17 00:00:00 2001 From: Georg Semmler <georg_semmler_05@web.de> Date: Thu, 19 Apr 2018 16:25:33 +0200 Subject: [PATCH 14/18] Remove unused type_name field to fix tests --- juniper/src/executor/mod.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/juniper/src/executor/mod.rs b/juniper/src/executor/mod.rs index 55c5b39e..b997a0b3 100644 --- a/juniper/src/executor/mod.rs +++ b/juniper/src/executor/mod.rs @@ -60,7 +60,6 @@ where context: &'a CtxT, errors: &'a RwLock<Vec<ExecutionError>>, field_path: FieldPath<'a>, - type_name: &'a str, } /// Error type for errors that occur during query execution @@ -330,7 +329,6 @@ impl<'a, CtxT> Executor<'a, CtxT> { context: ctx, errors: self.errors, field_path: self.field_path.clone(), - type_name: self.type_name, } } @@ -358,7 +356,6 @@ impl<'a, CtxT> Executor<'a, CtxT> { context: self.context, errors: self.errors, field_path: FieldPath::Field(field_alias, location, &self.field_path), - type_name: self.type_name, } } @@ -381,7 +378,6 @@ impl<'a, CtxT> Executor<'a, CtxT> { context: self.context, errors: self.errors, field_path: self.field_path.clone(), - type_name: type_name.unwrap(), } } @@ -590,7 +586,6 @@ where context: context, errors: &errors, field_path: FieldPath::Root(op.start), - type_name: &op.item.name.map(|n| n.item).unwrap_or(""), }; value = match op.item.operation_type { From 34391855af65f57a2ac01b0a2fcab9354443368b Mon Sep 17 00:00:00 2001 From: Georg Semmler <georg_semmler_05@web.de> Date: Wed, 9 May 2018 14:42:37 +0200 Subject: [PATCH 15/18] Fix imports --- juniper/src/executor/mod.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/juniper/src/executor/mod.rs b/juniper/src/executor/mod.rs index b997a0b3..e70acfa0 100644 --- a/juniper/src/executor/mod.rs +++ b/juniper/src/executor/mod.rs @@ -8,13 +8,9 @@ use fnv::FnvHashMap; use ast::{Definition, Document, Fragment, FromInputValue, InputValue, OperationType, Selection, ToInputValue, Type}; -use parser::SourcePosition; -use value::Value; use GraphQLError; -use ast::{Definition, Document, Fragment, FromInputValue, InputValue, OperationType, - Selection, ToInputValue, Type}; -use value::Value; use parser::SourcePosition; +use value::Value; use schema::meta::{Argument, EnumMeta, EnumValue, Field, InputObjectMeta, InterfaceMeta, ListMeta, MetaType, NullableMeta, ObjectMeta, PlaceholderMeta, ScalarMeta, UnionMeta}; From 69db4c247ba54731c1d036bae0af7493156872d8 Mon Sep 17 00:00:00 2001 From: Paul Colomiets <paul@colomiets.name> Date: Tue, 8 May 2018 10:13:49 +0300 Subject: [PATCH 16/18] Deserialize large integers as InputValue::float (fixes #178) --- changelog/master.md | 10 +++++++++ juniper/src/integrations/serde.rs | 35 +++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/changelog/master.md b/changelog/master.md index 3f74cba6..5aa87418 100644 --- a/changelog/master.md +++ b/changelog/master.md @@ -6,3 +6,13 @@ **Note:** while this is not a Rust breaking change, if you relied on the serialization format (perhaps by storing serialized data in a database or making asumptions in your client code written in another language) it could be a breaking change for your application. [#151](https://github.com/graphql-rust/juniper/pull/151) + +* Large integers (> signed 32bit) are now deserialized as floats. Previously, + they produced the "integer out of range" error. For languages that do not + have distinction between integer and floating point types (including + javascript), this means large floating point values which do not have + fractional part could not be decoded (because they are represented without + a decimal part `.0`). + + [#179](https://github.com/graphql-rust/juniper/pull/179) + diff --git a/juniper/src/integrations/serde.rs b/juniper/src/integrations/serde.rs index 72b96ef8..72048c79 100644 --- a/juniper/src/integrations/serde.rs +++ b/juniper/src/integrations/serde.rs @@ -79,7 +79,12 @@ impl<'de> de::Deserialize<'de> for InputValue { if value >= i64::from(i32::min_value()) && value <= i64::from(i32::max_value()) { Ok(InputValue::int(value as i32)) } else { - Err(E::custom("integer out of range")) + // Browser's JSON.stringify serialize all numbers having no + // fractional part as integers (no decimal point), so we + // must parse large integers as floating point otherwise + // we would error on transferring large floating point + // numbers. + Ok(InputValue::float(value as f64)) } } @@ -90,7 +95,12 @@ impl<'de> de::Deserialize<'de> for InputValue { if value <= i32::max_value() as u64 { self.visit_i64(value as i64) } else { - Err(E::custom("integer out of range")) + // Browser's JSON.stringify serialize all numbers having no + // fractional part as integers (no decimal point), so we + // must parse large integers as floating point otherwise + // we would error on transferring large floating point + // numbers. + Ok(InputValue::float(value as f64)) } } @@ -247,3 +257,24 @@ impl ser::Serialize for Value { } } } + +#[cfg(test)] +mod tests { + use serde_json::from_str; + use ast::InputValue; + + #[test] + fn int() { + assert_eq!(from_str::<InputValue>("1235").unwrap(), + InputValue::int(1235)); + } + + #[test] + fn float() { + assert_eq!(from_str::<InputValue>("2.0").unwrap(), + InputValue::float(2.0)); + // large value without a decimal part is also float + assert_eq!(from_str::<InputValue>("123567890123").unwrap(), + InputValue::float(123567890123.0)); + } +} From 9080448da23a991568062541cb3250ee7d261a42 Mon Sep 17 00:00:00 2001 From: piperRyan <35411044+piperRyan@users.noreply.github.com> Date: Wed, 23 May 2018 01:25:20 -0600 Subject: [PATCH 17/18] Add Compile Time Check For "Invalid" Names (#170) --- changelog/master.md | 8 ++++++-- juniper_codegen/Cargo.toml | 2 ++ juniper_codegen/src/derive_enum.rs | 18 ++++++++++++++---- juniper_codegen/src/derive_input_object.rs | 18 ++++++++++++++---- juniper_codegen/src/derive_object.rs | 18 ++++++++++++++---- juniper_codegen/src/lib.rs | 3 +++ juniper_codegen/src/util.rs | 22 ++++++++++++++++++++++ juniper_tests/src/codegen/derive_enum.rs | 7 +++---- 8 files changed, 78 insertions(+), 18 deletions(-) diff --git a/changelog/master.md b/changelog/master.md index 5aa87418..d64d5c74 100644 --- a/changelog/master.md +++ b/changelog/master.md @@ -7,6 +7,11 @@ [#151](https://github.com/graphql-rust/juniper/pull/151) +* The `GraphQLObject`, `GraphQLInputObject`, and `GraphQLEnum` custom derives will reject + invalid [names](http://facebook.github.io/graphql/October2016/#Name) at compile time. + + [#170](https://github.com/graphql-rust/juniper/pull/170) + * Large integers (> signed 32bit) are now deserialized as floats. Previously, they produced the "integer out of range" error. For languages that do not have distinction between integer and floating point types (including @@ -14,5 +19,4 @@ fractional part could not be decoded (because they are represented without a decimal part `.0`). - [#179](https://github.com/graphql-rust/juniper/pull/179) - + [#179](https://github.com/graphql-rust/juniper/pull/179) \ No newline at end of file diff --git a/juniper_codegen/Cargo.toml b/juniper_codegen/Cargo.toml index 13dbd08d..0695bc8f 100644 --- a/juniper_codegen/Cargo.toml +++ b/juniper_codegen/Cargo.toml @@ -16,6 +16,8 @@ proc-macro = true [dependencies] syn = { version = "0.13.*", features = ["full", "extra-traits"] } quote = "0.5.*" +regex = "0.2.10" +lazy_static = "1.0.0" [badges] travis-ci = { repository = "graphql-rust/juniper" } diff --git a/juniper_codegen/src/derive_enum.rs b/juniper_codegen/src/derive_enum.rs index 83b9bf78..90ad866b 100644 --- a/juniper_codegen/src/derive_enum.rs +++ b/juniper_codegen/src/derive_enum.rs @@ -32,8 +32,13 @@ impl EnumAttrs { if let Some(items) = get_graphl_attr(&input.attrs) { for item in items { if let Some(val) = keyed_item_value(&item, "name", true) { - res.name = Some(val); - continue; + if is_valid_name(&*val) { + res.name = Some(val); + continue; + } else { + panic!("Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but \"{}\" does not", + &*val); + } } if let Some(val) = keyed_item_value(&item, "description", true) { res.description = Some(val); @@ -73,8 +78,13 @@ impl EnumVariantAttrs { if let Some(items) = get_graphl_attr(&variant.attrs) { for item in items { if let Some(val) = keyed_item_value(&item, "name", true) { - res.name = Some(val); - continue; + if is_valid_name(&*val) { + res.name = Some(val); + continue; + } else { + panic!("Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but \"{}\" does not", + &*val); + } } if let Some(val) = keyed_item_value(&item, "description", true) { res.description = Some(val); diff --git a/juniper_codegen/src/derive_input_object.rs b/juniper_codegen/src/derive_input_object.rs index f645a3ec..c0f30eed 100644 --- a/juniper_codegen/src/derive_input_object.rs +++ b/juniper_codegen/src/derive_input_object.rs @@ -29,8 +29,13 @@ impl ObjAttrs { if let Some(items) = get_graphl_attr(&input.attrs) { for item in items { if let Some(val) = keyed_item_value(&item, "name", true) { - res.name = Some(val); - continue; + if is_valid_name(&*val) { + res.name = Some(val); + continue; + } else { + panic!("Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but \"{}\" does not", + &*val); + } } if let Some(val) = keyed_item_value(&item, "description", true) { res.description = Some(val); @@ -71,8 +76,13 @@ impl ObjFieldAttrs { if let Some(items) = get_graphl_attr(&variant.attrs) { for item in items { if let Some(val) = keyed_item_value(&item, "name", true) { - res.name = Some(val); - continue; + if is_valid_name(&*val) { + res.name = Some(val); + continue; + } else { + panic!("Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but \"{}\" does not", + &*val); + } } if let Some(val) = keyed_item_value(&item, "description", true) { res.description = Some(val); diff --git a/juniper_codegen/src/derive_object.rs b/juniper_codegen/src/derive_object.rs index 67133201..78417b60 100644 --- a/juniper_codegen/src/derive_object.rs +++ b/juniper_codegen/src/derive_object.rs @@ -23,8 +23,13 @@ impl ObjAttrs { if let Some(items) = get_graphl_attr(&input.attrs) { for item in items { if let Some(val) = keyed_item_value(&item, "name", true) { - res.name = Some(val); - continue; + if is_valid_name(&*val) { + res.name = Some(val); + continue; + } else { + panic!("Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but \"{}\" does not", + &*val); + } } if let Some(val) = keyed_item_value(&item, "description", true) { res.description = Some(val); @@ -55,8 +60,13 @@ impl ObjFieldAttrs { if let Some(items) = get_graphl_attr(&variant.attrs) { for item in items { if let Some(val) = keyed_item_value(&item, "name", true) { - res.name = Some(val); - continue; + if is_valid_name(&*val) { + res.name = Some(val); + continue; + } else { + panic!("Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but \"{}\" does not", + &*val); + } } if let Some(val) = keyed_item_value(&item, "description", true) { res.description = Some(val); diff --git a/juniper_codegen/src/lib.rs b/juniper_codegen/src/lib.rs index 55d7045f..97b6ddfd 100644 --- a/juniper_codegen/src/lib.rs +++ b/juniper_codegen/src/lib.rs @@ -10,6 +10,9 @@ extern crate proc_macro; #[macro_use] extern crate quote; extern crate syn; +#[macro_use] +extern crate lazy_static; +extern crate regex; mod util; mod derive_enum; diff --git a/juniper_codegen/src/util.rs b/juniper_codegen/src/util.rs index ac1afefd..21f4fc66 100644 --- a/juniper_codegen/src/util.rs +++ b/juniper_codegen/src/util.rs @@ -4,6 +4,7 @@ use syn::{ NestedMeta, Lit, }; +use regex::Regex; // Get the nested items of a a #[graphql(...)] attribute. pub fn get_graphl_attr(attrs: &Vec<Attribute>) -> Option<Vec<NestedMeta>> { @@ -111,3 +112,24 @@ fn test_to_upper_snake_case() { assert_eq!(to_upper_snake_case("someINpuT"), "SOME_INPU_T"); assert_eq!(to_upper_snake_case("some_INpuT"), "SOME_INPU_T"); } + +#[doc(hidden)] +pub fn is_valid_name(field_name: &str) -> bool { + lazy_static!{ + static ref CAMELCASE: Regex = Regex::new("^[_A-Za-z][_0-9A-Za-z]*$").unwrap(); + } + CAMELCASE.is_match(field_name) +} + +#[test] +fn test_is_valid_name(){ + assert_eq!(is_valid_name("yesItIs"), true); + assert_eq!(is_valid_name("NoitIsnt"), true); + assert_eq!(is_valid_name("iso6301"), true); + assert_eq!(is_valid_name("thisIsATest"), true); + assert_eq!(is_valid_name("i6Op"), true); + assert_eq!(is_valid_name("i!"), false); + assert_eq!(is_valid_name(""), false); + assert_eq!(is_valid_name("aTest"), true); + assert_eq!(is_valid_name("__Atest90"), true); +} diff --git a/juniper_tests/src/codegen/derive_enum.rs b/juniper_tests/src/codegen/derive_enum.rs index 6277ce09..2e1ea626 100644 --- a/juniper_tests/src/codegen/derive_enum.rs +++ b/juniper_tests/src/codegen/derive_enum.rs @@ -8,8 +8,7 @@ use juniper::{self, FromInputValue, GraphQLType, InputValue, ToInputValue}; #[graphql(name = "Some", description = "enum descr")] enum SomeEnum { Regular, - - #[graphql(name = "full", description = "field descr", deprecated = "depr")] Full, + #[graphql(name = "FULL", description = "field descr", deprecated = "depr")] Full, } #[test] @@ -37,10 +36,10 @@ fn test_derived_enum() { // Test FULL variant. assert_eq!( SomeEnum::Full.to_input_value(), - InputValue::String("full".into()) + InputValue::String("FULL".into()) ); assert_eq!( - FromInputValue::from_input_value(&InputValue::String("full".into())), + FromInputValue::from_input_value(&InputValue::String("FULL".into())), Some(SomeEnum::Full) ); } From 7933bf92a521884264c44525bf0303b5a7f574c6 Mon Sep 17 00:00:00 2001 From: Christian Legnitto <LegNeato@users.noreply.github.com> Date: Wed, 23 May 2018 00:49:23 -0700 Subject: [PATCH 18/18] Rename variable to be more descriptive. --- juniper_codegen/src/util.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/juniper_codegen/src/util.rs b/juniper_codegen/src/util.rs index 21f4fc66..784e664e 100644 --- a/juniper_codegen/src/util.rs +++ b/juniper_codegen/src/util.rs @@ -116,9 +116,9 @@ fn test_to_upper_snake_case() { #[doc(hidden)] pub fn is_valid_name(field_name: &str) -> bool { lazy_static!{ - static ref CAMELCASE: Regex = Regex::new("^[_A-Za-z][_0-9A-Za-z]*$").unwrap(); + static ref GRAPHQL_NAME_SPEC: Regex = Regex::new("^[_A-Za-z][_0-9A-Za-z]*$").unwrap(); } - CAMELCASE.is_match(field_name) + GRAPHQL_NAME_SPEC.is_match(field_name) } #[test]