diff --git a/.travis.yml b/.travis.yml index d1ae2804..ccf04956 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,53 +10,13 @@ rust: - 1.17.0 - 1.18.0 -matrix: - allow_failures: - - rust: nightly - env: global: - secure: "SsepHEYRmW9ee3RhxPpqGuPigZINFfA/yOwUJFseQt4t+Zs90r1xdl3Q8eDfPlnvBsL7Rd0QQrFDO7JUaimVLlgQkUnrl62o0CYzkodp+qtocyAHS00W6WTqi8Y6E6KBxPshCl03dRLaySUfx5TqTLTIHkJ0G6vDW35k7hRrA3221lRphs5rrpvAZ21pqsDsNLH3HVo792L6A0kOtBa3ocw1pgHLxnBbArIViu2htUuFvY/TgsmVbAdlow0efw/xkcJ/p0/r5q7igLek6Iqk8udfRc7CktvoiFQ2vUnhtNtQu/zYll3Q7OUx5d+w5lhbzz2QINmsezBEisH9k1haL7dMviLPp0pn4WZed60KovO0Iqfgjy1utTaKvJVfNWYsgkfU8c9a/z2rcZOKwXNKQW2ptBrtVjaB9dk7eMoyuFCDZwNtKqvG+ZKmvMpun+R8mmx+buOmN8Vlf5ygIoGxz3nbEtlLYGVTXHfdXXqRkFIwtiYVJEO7SLRKT9pbx1E++ARsi2+y8bXJT4e4z0osYMq9EsiFUpw3J2gcshrgseqkB7UgCZ3SXuitJnJNfDAU3a3nwwS/JiAunZMNnC4rKUBbl7WbTB4Cpw7EgVOlCqcyyzlkNl3xabLzTFzLOfSHLTVX5FmGNsD21vBoS5/8ejftx9wuV3rGHxuO3i3+A3k=" script: - # Build and run tests for main juniper crate with certain features. - - cd juniper - - cargo build --verbose - - cargo build --verbose --features iron-handlers - - | - if [ "$TRAVIS_RUST_VERSION" = "nightly" ]; then - cargo build --verbose --features rocket-handlers - fi - - # Build example binaries; first Iron, then Rocket examples - - cargo build --verbose --example server --features "iron-handlers expose-test-schema" - - | - if [ "TRAVIS_RUST_VERSION" = "nightly" ]; then - cargo build --verbose --example rocket-server --features "rocket-handlers expose-test-schema" - fi - - # Run all tests for the base library and available integrations - - export TEST_FEATURES="iron-handlers expose-test-schema" - - | - if [ "$TRAVIS_RUST_VERSION" = "nightly" ]; then - export TEST_FEATURES="$TEST_FEATURES rocket-handlers rocket/testing" - fi - - - cargo test --verbose --features "$TEST_FEATURES" - - cd .. - - # Build juniper_codegen and run tests. - - cd juniper_codegen - - cargo build --verbose - - cargo test - - cd .. - - # Build and run integration tests. - - cd juniper_tests - - cargo build --verbose - - cargo test - - + - cargo install -f --debug cargo-make + - cargo make ci-flow before_deploy: - rm -rf target/package/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b52a256..740682b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,7 +40,7 @@ Tiny release to fix broken crate metadata on crates.io. * A new `rocket-handlers` feature now includes some tools to use the [Rocket](https://rocket.rs) framework. [A simple - example](examples/rocket-server.rs) has been added to the examples folder. + example](juniper_rocket/examples/rocket-server.rs) has been added to the examples folder. ## Bugfixes diff --git a/Cargo.toml b/Cargo.toml index cc833d78..d6e64937 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,4 +3,6 @@ members = [ "juniper", "juniper_codegen", "juniper_tests", + "juniper_iron", + "juniper_rocket", ] diff --git a/README.md b/README.md index e4162bb6..6faecd79 100644 --- a/README.md +++ b/README.md @@ -30,20 +30,22 @@ Add Juniper to your Cargo.toml: juniper = "0.8.1" ``` -If you want the Iron integration enabled, you need to enable the `iron-handlers` +If you want Iron integration, you need to depend on the `juniper_iron` crate. feature flag: ```toml [dependencies] -juniper = { version = "0.8.1", features = ["iron-handlers"] } +juniper = { version = "0.8.1" } +juniper_iron = { git = "https://github.com/mhallin/juniper" } + ``` -If you want the Rocket integration enabled, you need to use the nightly Rust -compiler and enable the `rocket-handlers` feature flag: +If you want Rocket integration, you need to depend on the `juniper_rocket` crate. ```toml [dependencies] -juniper = { version = "0.8.1", features = ["rocket-handlers"] } +juniper = { version = "0.8.1" } +juniper_rocket = { git = "https://github.com/mhallin/juniper" } ``` ## Building schemas @@ -160,5 +162,5 @@ as well. [graphql_spec]: http://facebook.github.io/graphql [test_schema_rs]: src/tests/schema.rs [tokio]: https://github.com/tokio-rs/tokio -[examples]: examples/ +[examples]: juniper_rocket/examples/ [Rocket]: https://rocket.rs diff --git a/appveyor.yml b/appveyor.yml index 2923889d..0fc876d2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -32,7 +32,7 @@ environment: - TARGET: x86_64-pc-windows-msvc CHANNEL: nightly -# Install Rust and Cargo +# Install Rust ,Cargo and cargo-make. # (Based on from https://github.com/rust-lang/libc/blob/master/appveyor.yml) install: - curl -sSf -o rustup-init.exe https://win.rustup.rs @@ -40,6 +40,7 @@ install: - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin - rustc -Vv - cargo -V + - cargo install --debug cargo-make # 'cargo test' takes care of building for us, so disable Appveyor's build stage. This prevents @@ -48,30 +49,9 @@ install: build: false test_script: - # Build and test main juniper crate with certain features. - - cd juniper - - cargo build --verbose --features iron-handlers - - IF "%CHANNEL%"=="nightly" (cargo build --verbose --features rocket-handlers) - - # Build example binaries; first Iron, then Rocket examples - - cargo build --verbose --example server --features "iron-handlers expose-test-schema" - - IF "%CHANNEL%"=="nightly" (cargo build --verbose --example rocket-server --features "rocket-handlers expose-test-schema") - - # Run all tests for the base library and available integrations - - set TEST_FEATURES=iron-handlers expose-test-schema - - IF "%CHANNEL%"=="nightly" (set TEST_FEATURES=%TEST_FEATURES% rocket-handlers rocket/testing) - - - cargo test --verbose --features "%TEST_FEATURES%" - - cd .. - - # Build juniper_codegen and run tests. - - cd juniper_codegen - - cargo build --verbose - - cargo test - - cd .. - - # Build and run integration tests. - - cd juniper_tests - - cargo build --verbose - - cargo test + - cd juniper && cargo build --verbose && cargo test --verbose && cd .. + - cd juniper_codegen && cargo build --verbose && cargo test --verbose && cd .. + - cd juniper_iron && cargo build --verbose && cargo test --verbose && cd .. + - cd juniper_tests && cargo build --verbose && cargo test --verbose && cd .. + - IF NOT %TARGET% == %TARGET:msvc=% ( IF %CHANNEL% == "nightly" ( cd juniper_rocket && cargo test --verbose && cargo build --verbose && cd .. ) ) diff --git a/juniper/Cargo.toml b/juniper/Cargo.toml index a9565cd2..3cfa2b9a 100644 --- a/juniper/Cargo.toml +++ b/juniper/Cargo.toml @@ -7,12 +7,9 @@ license = "BSD-2-Clause" documentation = "https://docs.rs/juniper/0.8.1/juniper/" repository = "https://github.com/mhallin/juniper" readme = "README.md" -keywords = ["graphql", "server", "iron", "web", "rocket"] +keywords = ["graphql", "server", "web", "rocket"] categories = ["web-programming"] -[package.metadata.docs.rs] -features = [ "iron-handlers" ] - [badges] travis-ci = { repository = "mhallin/juniper" } appveyor = { repository = "mhallin/juniper" } @@ -22,36 +19,15 @@ name = "bench" harness = false path = "benches/bench.rs" -[[example]] -name = "server" -required-features = ["iron-handlers", "expose-test-schema"] - -[[example]] -name = "rocket-server" -required-features = ["rocket-handlers", "expose-test-schema"] - [features] nightly = [] -iron-handlers = ["iron", "serde_json", "urlencoded"] -rocket-handlers = ["rocket", "rocket_codegen", "serde_json"] expose-test-schema = [] [dependencies] serde = { version = "^1.0.8" } serde_derive = {version="^1.0.8" } - -serde_json = { version = "^1.0.2", optional = true } - -iron = { version = "^0.5.1", optional = true } -urlencoded = { version = "^0.5.0", optional = true } - -rocket = { version = "^0.2.8", optional = true } -rocket_codegen = { version = "^0.2.8", optional = true } +serde_json = { version="^1.0.2", optional = true } [dev-dependencies] -iron = "^0.5.1" -router = "^0.5.0" -mount = "^0.3.0" -logger = "^0.3.0" -iron-test = "^0.5.0" bencher = "^0.1.2" +serde_json = { version = "^1.0.2" } \ No newline at end of file diff --git a/juniper/benches/bench.rs b/juniper/benches/bench.rs index 5d707527..e264ef81 100644 --- a/juniper/benches/bench.rs +++ b/juniper/benches/bench.rs @@ -1,4 +1,5 @@ -#[macro_use] extern crate bencher; +#[macro_use] +extern crate bencher; extern crate juniper; use bencher::Bencher; diff --git a/juniper/src/ast.rs b/juniper/src/ast.rs index c89e936c..58f79ce7 100644 --- a/juniper/src/ast.rs +++ b/juniper/src/ast.rs @@ -168,8 +168,9 @@ impl<'a> Type<'a> { /// Only applies to named types; lists will return `None`. pub fn name(&self) -> Option<&str> { match *self { - Type::Named(n) | Type::NonNullNamed(n) => Some(n), - _ => None + Type::Named(n) | + Type::NonNullNamed(n) => Some(n), + _ => None, } } @@ -178,15 +179,18 @@ impl<'a> Type<'a> { /// All type literals contain exactly one named type. pub fn innermost_name(&self) -> &str { match *self { - Type::Named(n) | Type::NonNullNamed(n) => n, - Type::List(ref l) | Type::NonNullList(ref l) => l.innermost_name(), + Type::Named(n) | + Type::NonNullNamed(n) => n, + Type::List(ref l) | + Type::NonNullList(ref l) => l.innermost_name(), } } /// Determines if a type only can represent non-null values. pub fn is_non_null(&self) -> bool { match *self { - Type::NonNullNamed(_) | Type::NonNullList(_) => true, + Type::NonNullNamed(_) | + Type::NonNullList(_) => true, _ => false, } } @@ -205,16 +209,24 @@ impl<'a> fmt::Display for Type<'a> { impl InputValue { /// Construct a null value. - pub fn null() -> InputValue { InputValue::Null } + pub fn null() -> InputValue { + InputValue::Null + } /// Construct an integer value. - pub fn int(i: i32) -> InputValue { InputValue::Int(i) } + pub fn int(i: i32) -> InputValue { + InputValue::Int(i) + } /// Construct a floating point value. - pub fn float(f: f64) -> InputValue { InputValue::Float(f) } + pub fn float(f: f64) -> InputValue { + InputValue::Float(f) + } /// Construct a boolean value. - pub fn boolean(b: bool) -> InputValue { InputValue::Boolean(b) } + pub fn boolean(b: bool) -> InputValue { + InputValue::Boolean(b) + } /// Construct a string value. pub fn string>(s: T) -> InputValue { @@ -252,12 +264,12 @@ impl InputValue { pub fn object(o: HashMap) -> InputValue where K: AsRef + Eq + Hash { - InputValue::Object( - o.into_iter() - .map(|(k, v)| - (Spanning::unlocated(k.as_ref().to_owned()), Spanning::unlocated(v))) - .collect() - ) + InputValue::Object(o.into_iter() + .map(|(k, v)| { + (Spanning::unlocated(k.as_ref().to_owned()), + Spanning::unlocated(v)) + }) + .collect()) } /// Construct a located object. @@ -268,20 +280,25 @@ impl InputValue { /// Resolve all variables to their values. pub fn into_const(self, vars: &Variables) -> InputValue { match self { - InputValue::Variable(v) => vars.get(&v) - .map_or_else(InputValue::null, Clone::clone), - InputValue::List(l) => InputValue::List( - l.into_iter().map(|s| s.map(|v| v.into_const(vars))).collect() - ), - InputValue::Object(o) => InputValue::Object( - o.into_iter().map(|(sk, sv)| (sk, sv.map(|v| v.into_const(vars)))).collect() - ), + InputValue::Variable(v) => vars.get(&v).map_or_else(InputValue::null, Clone::clone), + InputValue::List(l) => { + InputValue::List(l.into_iter() + .map(|s| s.map(|v| v.into_const(vars))) + .collect()) + } + InputValue::Object(o) => { + InputValue::Object(o.into_iter() + .map(|(sk, sv)| (sk, sv.map(|v| v.into_const(vars)))) + .collect()) + } v => v, } } /// Shorthand form of invoking `FromInputValue::from()`. - pub fn convert(&self) -> Option where T: FromInputValue { + pub fn convert(&self) -> Option + where T: FromInputValue + { ::from(self) } @@ -331,8 +348,11 @@ impl InputValue { /// and values in `self`. pub fn to_object_value(&self) -> Option> { match *self { - InputValue::Object(ref o) => Some( - o.iter().map(|&(ref sk, ref sv)| (sk.item.as_str(), &sv.item)).collect()), + InputValue::Object(ref o) => { + Some(o.iter() + .map(|&(ref sk, ref sv)| (sk.item.as_str(), &sv.item)) + .collect()) + } _ => None, } } @@ -352,8 +372,16 @@ impl InputValue { pub fn referenced_variables(&self) -> Vec<&str> { match *self { InputValue::Variable(ref name) => vec![name], - InputValue::List(ref l) => l.iter().flat_map(|v| v.item.referenced_variables()).collect(), - InputValue::Object(ref obj) => obj.iter().flat_map(|&(_, ref v)| v.item.referenced_variables()).collect(), + InputValue::List(ref l) => { + l.iter() + .flat_map(|v| v.item.referenced_variables()) + .collect() + } + InputValue::Object(ref obj) => { + obj.iter() + .flat_map(|&(_, ref v)| v.item.referenced_variables()) + .collect() + } _ => vec![], } } @@ -370,14 +398,22 @@ impl InputValue { (&Enum(ref s1), &Enum(ref s2)) | (&Variable(ref s1), &Variable(ref s2)) => s1 == s2, (&Boolean(b1), &Boolean(b2)) => b1 == b2, - (&List(ref l1), &List(ref l2)) => - l1.iter().zip(l2.iter()).all(|(v1, v2)| v1.item.unlocated_eq(&v2.item)), - (&Object(ref o1), &Object(ref o2)) => - o1.len() == o2.len() - && o1.iter() - .all(|&(ref sk1, ref sv1)| o2.iter().any( - |&(ref sk2, ref sv2)| sk1.item == sk2.item && sv1.item.unlocated_eq(&sv2.item))), - _ => false + (&List(ref l1), &List(ref l2)) => { + l1.iter() + .zip(l2.iter()) + .all(|(v1, v2)| v1.item.unlocated_eq(&v2.item)) + } + (&Object(ref o1), &Object(ref o2)) => { + o1.len() == o2.len() && + o1.iter() + .all(|&(ref sk1, ref sv1)| { + o2.iter() + .any(|&(ref sk2, ref sv2)| { + sk1.item == sk2.item && sv1.item.unlocated_eq(&sv2.item) + }) + }) + } + _ => false, } } } @@ -397,18 +433,22 @@ impl fmt::Display for InputValue { for (i, spanning) in v.iter().enumerate() { try!(spanning.item.fmt(f)); - if i < v.len() - 1 { try!(write!(f, ", ")); } + if i < v.len() - 1 { + try!(write!(f, ", ")); + } } write!(f, "]") - }, + } InputValue::Object(ref o) => { try!(write!(f, "{{")); for (i, &(ref k, ref v)) in o.iter().enumerate() { try!(write!(f, "{}: ", k.item)); try!(v.item.fmt(f)); - if i < o.len() - 1 { try!(write!(f, ", ")); } + if i < o.len() - 1 { + try!(write!(f, ", ")); + } } write!(f, "}}") @@ -481,10 +521,9 @@ mod tests { let value = InputValue::list(list); assert_eq!(format!("{}", value), "[1, 2]"); - let object = vec![ - (Spanning::unlocated("foo".to_owned()), Spanning::unlocated(InputValue::int(1))), - (Spanning::unlocated("bar".to_owned()), Spanning::unlocated(InputValue::int(2))), - ]; + let object = + vec![(Spanning::unlocated("foo".to_owned()), Spanning::unlocated(InputValue::int(1))), + (Spanning::unlocated("bar".to_owned()), Spanning::unlocated(InputValue::int(2)))]; let value = InputValue::parsed_object(object); assert_eq!(format!("{}", value), "{foo: 1, bar: 2}"); } diff --git a/juniper/src/executor.rs b/juniper/src/executor.rs index dcde70e2..07625228 100644 --- a/juniper/src/executor.rs +++ b/juniper/src/executor.rs @@ -1,14 +1,14 @@ use std::collections::HashMap; use std::sync::RwLock; -use ::GraphQLError; -use ast::{InputValue, ToInputValue, Document, Selection, Fragment, Definition, Type, FromInputValue, OperationType}; +use GraphQLError; +use ast::{InputValue, ToInputValue, Document, Selection, Fragment, Definition, Type, + FromInputValue, OperationType}; use value::Value; use parser::SourcePosition; -use schema::meta::{MetaType, ScalarMeta, ListMeta, NullableMeta, - ObjectMeta, EnumMeta, InterfaceMeta, UnionMeta, - InputObjectMeta, PlaceholderMeta, Field, Argument, +use schema::meta::{MetaType, ScalarMeta, ListMeta, NullableMeta, ObjectMeta, EnumMeta, + InterfaceMeta, UnionMeta, InputObjectMeta, PlaceholderMeta, Field, Argument, EnumValue}; use schema::model::{RootNode, SchemaType}; @@ -34,7 +34,9 @@ pub enum FieldPath<'a> { /// /// The executor helps drive the query execution in a schema. It keeps track /// of the current field stack, context, variables, and errors. -pub struct Executor<'a, CtxT> where CtxT: 'a { +pub struct Executor<'a, CtxT> + where CtxT: 'a +{ fragments: &'a HashMap<&'a str, &'a Fragment<'a>>, variables: &'a Variables, current_selection_set: Option<&'a [Selection<'a>]>, @@ -70,13 +72,17 @@ pub trait IntoResolvable<'a, T: GraphQLType, C>: Sized { fn into(self, ctx: &'a C) -> FieldResult>; } -impl<'a, T: GraphQLType, C> IntoResolvable<'a, T, C> for T where T::Context: FromContext { +impl<'a, T: GraphQLType, C> IntoResolvable<'a, T, C> for T + where T::Context: FromContext +{ fn into(self, ctx: &'a C) -> FieldResult> { Ok(Some((FromContext::from(ctx), self))) } } -impl<'a, T: GraphQLType, C> IntoResolvable<'a, T, C> for FieldResult where T::Context: FromContext { +impl<'a, T: GraphQLType, C> IntoResolvable<'a, T, C> for FieldResult + where T::Context: FromContext +{ fn into(self, ctx: &'a C) -> FieldResult> { self.map(|v| Some((FromContext::from(ctx), v))) } @@ -123,7 +129,7 @@ pub trait FromContext { } /// Marker trait for types that can act as context objects for GraphQL types. -pub trait Context { } +pub trait Context {} impl<'a, C: Context> Context for &'a C {} @@ -135,7 +141,9 @@ impl FromContext for () { } } -impl FromContext for T where T: Context { +impl FromContext for T + where T: Context +{ fn from(value: &T) -> &Self { value } @@ -143,31 +151,31 @@ impl FromContext for T where T: Context { impl<'a, CtxT> Executor<'a, CtxT> { /// Resolve a single arbitrary value, mapping the context to a new type - pub fn resolve_with_ctx>( - &self, value: &T - ) -> ExecutionResult - where NewCtxT: FromContext, + pub fn resolve_with_ctx>(&self, + value: &T) + -> ExecutionResult + where NewCtxT: FromContext { self.replaced_context(>::from(self.context)) .resolve(value) } /// Resolve a single arbitrary value into an `ExecutionResult` - pub fn resolve>(&self, value: &T) -> ExecutionResult { + pub fn resolve>(&self, value: &T) -> ExecutionResult { Ok(value.resolve(self.current_selection_set, self)) } /// Resolve a single arbitrary value into a return value /// /// If the field fails to resolve, `null` will be returned. - pub fn resolve_into_value>(&self, value: &T) -> Value { + pub fn resolve_into_value>(&self, value: &T) -> Value { match self.resolve(value) { Ok(v) => v, Err(e) => { let position = self.field_path.location().clone(); self.push_error(e, position); Value::null() - }, + } } } @@ -188,14 +196,11 @@ impl<'a, CtxT> Executor<'a, CtxT> { } #[doc(hidden)] - pub fn sub_executor( - &self, - field_name: Option<&'a str>, - location: SourcePosition, - selection_set: Option<&'a [Selection]>, - ) - -> Executor - { + pub fn sub_executor(&self, + field_name: Option<&'a str>, + location: SourcePosition, + selection_set: Option<&'a [Selection]>) + -> Executor { Executor { fragments: self.fragments, variables: self.variables, @@ -241,10 +246,10 @@ impl<'a, CtxT> Executor<'a, CtxT> { let mut errors = self.errors.write().unwrap(); errors.push(ExecutionError { - location: location, - path: path, - message: error, - }); + location: location, + path: path, + message: error, + }); } } @@ -262,7 +267,7 @@ impl<'a> FieldPath<'a> { fn location(&self) -> &SourcePosition { match *self { FieldPath::Root(ref pos) | - FieldPath::Field(_, ref pos, _) => pos + FieldPath::Field(_, ref pos, _) => pos, } } } @@ -293,16 +298,15 @@ impl ExecutionError { } } -pub fn execute_validated_query<'a, QueryT, MutationT, CtxT>( - document: Document, - operation_name: Option<&str>, - root_node: &RootNode, - variables: &Variables, - context: &CtxT -) - -> Result<(Value, Vec), GraphQLError<'a>> - where QueryT: GraphQLType, - MutationT: GraphQLType +pub fn execute_validated_query<'a, QueryT, MutationT, CtxT> + (document: Document, + operation_name: Option<&str>, + root_node: &RootNode, + variables: &Variables, + context: &CtxT) + -> Result<(Value, Vec), GraphQLError<'a>> + where QueryT: GraphQLType, + MutationT: GraphQLType { let mut fragments = vec![]; let mut operation = None; @@ -314,8 +318,8 @@ pub fn execute_validated_query<'a, QueryT, MutationT, CtxT>( return Err(GraphQLError::MultipleOperationsProvided); } - let move_op = operation_name.is_none() - || op.item.name.as_ref().map(|s| s.item.as_ref()) == operation_name; + let move_op = operation_name.is_none() || + op.item.name.as_ref().map(|s| s.item.as_ref()) == operation_name; if move_op { operation = Some(op); @@ -330,11 +334,19 @@ pub fn execute_validated_query<'a, QueryT, MutationT, CtxT>( None => return Err(GraphQLError::UnknownOperationName), }; - let default_variable_values = op.item.variable_definitions - .map(|defs| defs.item.items.iter().filter_map( - |&(ref name, ref def)| def.default_value.as_ref().map( - |i| (name.item.to_owned(), i.item.clone()))) - .collect::>()); + let default_variable_values = op.item + .variable_definitions + .map(|defs| { + defs.item + .items + .iter() + .filter_map(|&(ref name, ref def)| { + def.default_value + .as_ref() + .map(|i| (name.item.to_owned(), i.item.clone())) + }) + .collect::>() + }); let errors = RwLock::new(Vec::new()); let value; @@ -354,7 +366,10 @@ pub fn execute_validated_query<'a, QueryT, MutationT, CtxT>( } let executor = Executor { - fragments: &fragments.iter().map(|f| (f.item.name.item, &f.item)).collect(), + fragments: &fragments + .iter() + .map(|f| (f.item.name.item, &f.item)) + .collect(), variables: final_vars, current_selection_set: Some(&op.item.selection_set[..]), schema: &root_node.schema, @@ -378,16 +393,16 @@ pub fn execute_validated_query<'a, QueryT, MutationT, CtxT>( impl<'r> Registry<'r> { /// Construct a new registry pub fn new(types: HashMap>) -> Registry<'r> { - Registry { - types: types, - } + Registry { types: types } } /// Get the `Type` instance for a given GraphQL type /// /// If the registry hasn't seen a type with this name before, it will /// construct its metadata and store it. - pub fn get_type(&mut self) -> Type<'r> where T: GraphQLType { + pub fn get_type(&mut self) -> Type<'r> + where T: GraphQLType + { if let Some(name) = T::name() { if !self.types.contains_key(name) { self.insert_placeholder(name, Type::NonNullNamed(name)); @@ -395,14 +410,15 @@ impl<'r> Registry<'r> { self.types.insert(name.to_owned(), meta); } self.types[name].as_type() - } - else { + } else { T::meta(self).as_type() } } /// Create a field with the provided name - pub fn field(&mut self, name: &str) -> Field<'r> where T: GraphQLType { + pub fn field(&mut self, name: &str) -> Field<'r> + where T: GraphQLType + { Field { name: name.to_owned(), description: None, @@ -426,7 +442,9 @@ impl<'r> Registry<'r> { } /// Create an argument with the provided name - pub fn arg(&mut self, name: &str) -> Argument<'r> where T: GraphQLType + FromInputValue { + pub fn arg(&mut self, name: &str) -> Argument<'r> + where T: GraphQLType + FromInputValue + { Argument::new(name, self.get_type::()) } @@ -434,23 +452,17 @@ impl<'r> Registry<'r> { /// /// When called with type `T`, the actual argument will be given the type /// `Option`. - pub fn arg_with_default( - &mut self, - name: &str, - value: &T, - ) - -> Argument<'r> + pub fn arg_with_default(&mut self, name: &str, value: &T) -> Argument<'r> where T: GraphQLType + ToInputValue + FromInputValue { - Argument::new(name, self.get_type::>()) - .default_value(value.to()) + Argument::new(name, self.get_type::>()).default_value(value.to()) } fn insert_placeholder(&mut self, name: &str, of_type: Type<'r>) { if !self.types.contains_key(name) { - self.types.insert( - name.to_owned(), - MetaType::Placeholder(PlaceholderMeta { of_type: of_type })); + self.types + .insert(name.to_owned(), + MetaType::Placeholder(PlaceholderMeta { of_type: of_type })); } } diff --git a/juniper/src/executor_tests/directives.rs b/juniper/src/executor_tests/directives.rs index be6c1dca..54c93a93 100644 --- a/juniper/src/executor_tests/directives.rs +++ b/juniper/src/executor_tests/directives.rs @@ -22,8 +22,7 @@ fn run_variable_query(query: &str, vars: Variables, f: F) { let schema = RootNode::new(TestType, EmptyMutation::<()>::new()); - let (result, errs) = ::execute(query, None, &schema, &vars, &()) - .expect("Execution failed"); + let (result, errs) = ::execute(query, None, &schema, &vars, &()).expect("Execution failed"); assert_eq!(errs, []); @@ -42,42 +41,34 @@ fn run_query(query: &str, f: F) #[test] fn scalar_include_true() { - run_query( - "{ a, b @include(if: true) }", - |result| { - assert_eq!(result.get("a"), Some(&Value::string("a"))); - assert_eq!(result.get("b"), Some(&Value::string("b"))); - }); + run_query("{ a, b @include(if: true) }", |result| { + assert_eq!(result.get("a"), Some(&Value::string("a"))); + assert_eq!(result.get("b"), Some(&Value::string("b"))); + }); } #[test] fn scalar_include_false() { - run_query( - "{ a, b @include(if: false) }", - |result| { - assert_eq!(result.get("a"), Some(&Value::string("a"))); - assert_eq!(result.get("b"), None); - }); + run_query("{ a, b @include(if: false) }", |result| { + assert_eq!(result.get("a"), Some(&Value::string("a"))); + assert_eq!(result.get("b"), None); + }); } #[test] fn scalar_skip_false() { - run_query( - "{ a, b @skip(if: false) }", - |result| { - assert_eq!(result.get("a"), Some(&Value::string("a"))); - assert_eq!(result.get("b"), Some(&Value::string("b"))); - }); + run_query("{ a, b @skip(if: false) }", |result| { + assert_eq!(result.get("a"), Some(&Value::string("a"))); + assert_eq!(result.get("b"), Some(&Value::string("b"))); + }); } #[test] fn scalar_skip_true() { - run_query( - "{ a, b @skip(if: true) }", - |result| { - assert_eq!(result.get("a"), Some(&Value::string("a"))); - assert_eq!(result.get("b"), None); - }); + run_query("{ a, b @skip(if: true) }", |result| { + assert_eq!(result.get("a"), Some(&Value::string("a"))); + assert_eq!(result.get("b"), None); + }); } @@ -85,84 +76,74 @@ fn scalar_skip_true() { #[test] fn fragment_spread_include_true() { - run_query( - "{ a, ...Frag @include(if: true) } fragment Frag on TestType { b }", - |result| { - assert_eq!(result.get("a"), Some(&Value::string("a"))); - assert_eq!(result.get("b"), Some(&Value::string("b"))); - }); + run_query("{ a, ...Frag @include(if: true) } fragment Frag on TestType { b }", + |result| { + assert_eq!(result.get("a"), Some(&Value::string("a"))); + assert_eq!(result.get("b"), Some(&Value::string("b"))); + }); } #[test] fn fragment_spread_include_false() { - run_query( - "{ a, ...Frag @include(if: false) } fragment Frag on TestType { b }", - |result| { - assert_eq!(result.get("a"), Some(&Value::string("a"))); - assert_eq!(result.get("b"), None); - }); + run_query("{ a, ...Frag @include(if: false) } fragment Frag on TestType { b }", + |result| { + assert_eq!(result.get("a"), Some(&Value::string("a"))); + assert_eq!(result.get("b"), None); + }); } #[test] fn fragment_spread_skip_false() { - run_query( - "{ a, ...Frag @skip(if: false) } fragment Frag on TestType { b }", - |result| { - assert_eq!(result.get("a"), Some(&Value::string("a"))); - assert_eq!(result.get("b"), Some(&Value::string("b"))); - }); + run_query("{ a, ...Frag @skip(if: false) } fragment Frag on TestType { b }", + |result| { + assert_eq!(result.get("a"), Some(&Value::string("a"))); + assert_eq!(result.get("b"), Some(&Value::string("b"))); + }); } #[test] fn fragment_spread_skip_true() { - run_query( - "{ a, ...Frag @skip(if: true) } fragment Frag on TestType { b }", - |result| { - assert_eq!(result.get("a"), Some(&Value::string("a"))); - assert_eq!(result.get("b"), None); - }); + run_query("{ a, ...Frag @skip(if: true) } fragment Frag on TestType { b }", + |result| { + assert_eq!(result.get("a"), Some(&Value::string("a"))); + assert_eq!(result.get("b"), None); + }); } #[test] fn inline_fragment_include_true() { - run_query( - "{ a, ... on TestType @include(if: true) { b } }", - |result| { - assert_eq!(result.get("a"), Some(&Value::string("a"))); - assert_eq!(result.get("b"), Some(&Value::string("b"))); - }); + run_query("{ a, ... on TestType @include(if: true) { b } }", + |result| { + assert_eq!(result.get("a"), Some(&Value::string("a"))); + assert_eq!(result.get("b"), Some(&Value::string("b"))); + }); } #[test] fn inline_fragment_include_false() { - run_query( - "{ a, ... on TestType @include(if: false) { b } }", - |result| { - assert_eq!(result.get("a"), Some(&Value::string("a"))); - assert_eq!(result.get("b"), None); - }); + run_query("{ a, ... on TestType @include(if: false) { b } }", + |result| { + assert_eq!(result.get("a"), Some(&Value::string("a"))); + assert_eq!(result.get("b"), None); + }); } #[test] fn inline_fragment_skip_false() { - run_query( - "{ a, ... on TestType @skip(if: false) { b } }", - |result| { - assert_eq!(result.get("a"), Some(&Value::string("a"))); - assert_eq!(result.get("b"), Some(&Value::string("b"))); - }); + run_query("{ a, ... on TestType @skip(if: false) { b } }", |result| { + assert_eq!(result.get("a"), Some(&Value::string("a"))); + assert_eq!(result.get("b"), Some(&Value::string("b"))); + }); } #[test] fn inline_fragment_skip_true() { - run_query( - "{ a, ... on TestType @skip(if: true) { b } }", - |result| { - assert_eq!(result.get("a"), Some(&Value::string("a"))); - assert_eq!(result.get("b"), None); - }); + run_query("{ a, ... on TestType @skip(if: true) { b } }", |result| { + assert_eq!(result.get("a"), Some(&Value::string("a"))); + assert_eq!(result.get("b"), None); + }); } @@ -170,42 +151,34 @@ fn inline_fragment_skip_true() { #[test] fn anonymous_inline_fragment_include_true() { - run_query( - "{ a, ... @include(if: true) { b } }", - |result| { - assert_eq!(result.get("a"), Some(&Value::string("a"))); - assert_eq!(result.get("b"), Some(&Value::string("b"))); - }); + run_query("{ a, ... @include(if: true) { b } }", |result| { + assert_eq!(result.get("a"), Some(&Value::string("a"))); + assert_eq!(result.get("b"), Some(&Value::string("b"))); + }); } #[test] fn anonymous_inline_fragment_include_false() { - run_query( - "{ a, ... @include(if: false) { b } }", - |result| { - assert_eq!(result.get("a"), Some(&Value::string("a"))); - assert_eq!(result.get("b"), None); - }); + run_query("{ a, ... @include(if: false) { b } }", |result| { + assert_eq!(result.get("a"), Some(&Value::string("a"))); + assert_eq!(result.get("b"), None); + }); } #[test] fn anonymous_inline_fragment_skip_false() { - run_query( - "{ a, ... @skip(if: false) { b } }", - |result| { - assert_eq!(result.get("a"), Some(&Value::string("a"))); - assert_eq!(result.get("b"), Some(&Value::string("b"))); - }); + run_query("{ a, ... @skip(if: false) { b } }", |result| { + assert_eq!(result.get("a"), Some(&Value::string("a"))); + assert_eq!(result.get("b"), Some(&Value::string("b"))); + }); } #[test] fn anonymous_inline_fragment_skip_true() { - run_query( - "{ a, ... @skip(if: true) { b } }", - |result| { - assert_eq!(result.get("a"), Some(&Value::string("a"))); - assert_eq!(result.get("b"), None); - }); + run_query("{ a, ... @skip(if: true) { b } }", |result| { + assert_eq!(result.get("a"), Some(&Value::string("a"))); + assert_eq!(result.get("b"), None); + }); } @@ -213,40 +186,32 @@ fn anonymous_inline_fragment_skip_true() { #[test] fn scalar_include_true_skip_true() { - run_query( - "{ a, b @include(if: true) @skip(if: true) }", - |result| { - assert_eq!(result.get("a"), Some(&Value::string("a"))); - assert_eq!(result.get("b"), None); - }); + run_query("{ a, b @include(if: true) @skip(if: true) }", |result| { + assert_eq!(result.get("a"), Some(&Value::string("a"))); + assert_eq!(result.get("b"), None); + }); } #[test] fn scalar_include_true_skip_false() { - run_query( - "{ a, b @include(if: true) @skip(if: false) }", - |result| { - assert_eq!(result.get("a"), Some(&Value::string("a"))); - assert_eq!(result.get("b"), Some(&Value::string("b"))); - }); + run_query("{ a, b @include(if: true) @skip(if: false) }", |result| { + assert_eq!(result.get("a"), Some(&Value::string("a"))); + assert_eq!(result.get("b"), Some(&Value::string("b"))); + }); } #[test] fn scalar_include_false_skip_true() { - run_query( - "{ a, b @include(if: false) @skip(if: true) }", - |result| { - assert_eq!(result.get("a"), Some(&Value::string("a"))); - assert_eq!(result.get("b"), None); - }); + run_query("{ a, b @include(if: false) @skip(if: true) }", |result| { + assert_eq!(result.get("a"), Some(&Value::string("a"))); + assert_eq!(result.get("b"), None); + }); } #[test] fn scalar_include_false_skip_false() { - run_query( - "{ a, b @include(if: false) @skip(if: false) }", - |result| { - assert_eq!(result.get("a"), Some(&Value::string("a"))); - assert_eq!(result.get("b"), None); - }); + run_query("{ a, b @include(if: false) @skip(if: false) }", |result| { + assert_eq!(result.get("a"), Some(&Value::string("a"))); + assert_eq!(result.get("b"), None); + }); } diff --git a/juniper/src/executor_tests/enums.rs b/juniper/src/executor_tests/enums.rs index 4eab8f87..c0946b92 100644 --- a/juniper/src/executor_tests/enums.rs +++ b/juniper/src/executor_tests/enums.rs @@ -4,13 +4,17 @@ use value::Value; use ast::InputValue; use executor::Variables; use schema::model::RootNode; -use ::GraphQLError::ValidationError; +use GraphQLError::ValidationError; use validation::RuleError; use parser::SourcePosition; use types::scalars::EmptyMutation; #[derive(Debug)] -enum Color { Red, Green, Blue } +enum Color { + Red, + Green, + Blue, +} struct TestType; graphql_enum!(Color { @@ -34,8 +38,7 @@ fn run_variable_query(query: &str, vars: Variables, f: F) { let schema = RootNode::new(TestType, EmptyMutation::<()>::new()); - let (result, errs) = ::execute(query, None, &schema, &vars, &()) - .expect("Execution failed"); + let (result, errs) = ::execute(query, None, &schema, &vars, &()).expect("Execution failed"); assert_eq!(errs, []); @@ -54,24 +57,20 @@ fn run_query(query: &str, f: F) #[test] fn accepts_enum_literal() { - run_query( - "{ toString(color: RED) }", - |result| { - assert_eq!( + run_query("{ toString(color: RED) }", |result| { + assert_eq!( result.get("toString"), Some(&Value::string("Color::Red"))); - }); + }); } #[test] fn serializes_as_output() { - run_query( - "{ aColor }", - |result| { - assert_eq!( + run_query("{ aColor }", |result| { + assert_eq!( result.get("aColor"), Some(&Value::string("RED"))); - }); + }); } #[test] @@ -79,11 +78,9 @@ fn does_not_accept_string_literals() { let schema = RootNode::new(TestType, EmptyMutation::<()>::new()); let query = r#"{ toString(color: "RED") }"#; - let vars = vec![ - ].into_iter().collect(); + let vars = vec![].into_iter().collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( @@ -95,16 +92,17 @@ fn does_not_accept_string_literals() { #[test] fn accepts_strings_in_variables() { - run_variable_query( - "query q($color: Color!) { toString(color: $color) }", - vec![ + run_variable_query("query q($color: Color!) { toString(color: $color) }", + vec![ ("color".to_owned(), InputValue::string("RED")), - ].into_iter().collect(), - |result| { - assert_eq!( + ] + .into_iter() + .collect(), + |result| { + assert_eq!( result.get("toString"), Some(&Value::string("Color::Red"))); - }); + }); } #[test] @@ -114,10 +112,11 @@ fn does_not_accept_incorrect_enum_name_in_variables() { let query = r#"query q($color: Color!) { toString(color: $color) }"#; let vars = vec![ ("color".to_owned(), InputValue::string("BLURPLE")), - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( @@ -134,10 +133,11 @@ fn does_not_accept_incorrect_type_in_variables() { let query = r#"query q($color: Color!) { toString(color: $color) }"#; let vars = vec![ ("color".to_owned(), InputValue::int(123)), - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( diff --git a/juniper/src/executor_tests/executor.rs b/juniper/src/executor_tests/executor.rs index 438f650d..a134029d 100644 --- a/juniper/src/executor_tests/executor.rs +++ b/juniper/src/executor_tests/executor.rs @@ -63,10 +63,11 @@ mod field_execution { let vars = vec![ ("size".to_owned(), InputValue::int(100)) - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let (result, errs) = ::execute(doc, None, &schema, &vars, &()) - .expect("Execution failed"); + let (result, errs) = ::execute(doc, None, &schema, &vars, &()).expect("Execution failed"); assert_eq!(errs, []); @@ -137,8 +138,7 @@ mod merge_parallel_fragments { let vars = vec![].into_iter().collect(); - let (result, errs) = ::execute(doc, None, &schema, &vars, &()) - .expect("Execution failed"); + let (result, errs) = ::execute(doc, None, &schema, &vars, &()).expect("Execution failed"); assert_eq!(errs, []); @@ -187,9 +187,12 @@ mod threads_context_correctly { let vars = vec![].into_iter().collect(); - let (result, errs) = ::execute(doc, None, &schema, &vars, + let (result, errs) = ::execute(doc, + None, + &schema, + &vars, &TestContext { value: "Context value".to_owned() }) - .expect("Execution failed"); + .expect("Execution failed"); assert_eq!(errs, []); @@ -269,11 +272,12 @@ mod dynamic_context_switching { items: vec![ (0, InnerContext { value: "First value".to_owned() }), (1, InnerContext { value: "Second value".to_owned() }), - ].into_iter().collect(), + ] + .into_iter() + .collect(), }; - let (result, errs) = ::execute(doc, None, &schema, &vars, &ctx) - .expect("Execution failed"); + let (result, errs) = ::execute(doc, None, &schema, &vars, &ctx).expect("Execution failed"); assert_eq!(errs, []); @@ -305,11 +309,12 @@ mod dynamic_context_switching { items: vec![ (0, InnerContext { value: "First value".to_owned() }), (1, InnerContext { value: "Second value".to_owned() }), - ].into_iter().collect(), + ] + .into_iter() + .collect(), }; - let (result, errs) = ::execute(doc, None, &schema, &vars, &ctx) - .expect("Execution failed"); + let (result, errs) = ::execute(doc, None, &schema, &vars, &ctx).expect("Execution failed"); assert_eq!(errs, vec![ ExecutionError::new( @@ -348,11 +353,12 @@ mod dynamic_context_switching { items: vec![ (0, InnerContext { value: "First value".to_owned() }), (1, InnerContext { value: "Second value".to_owned() }), - ].into_iter().collect(), + ] + .into_iter() + .collect(), }; - let (result, errs) = ::execute(doc, None, &schema, &vars, &ctx) - .expect("Execution failed"); + let (result, errs) = ::execute(doc, None, &schema, &vars, &ctx).expect("Execution failed"); assert_eq!(errs, [ ExecutionError::new( @@ -386,11 +392,12 @@ mod dynamic_context_switching { items: vec![ (0, InnerContext { value: "First value".to_owned() }), (1, InnerContext { value: "Second value".to_owned() }), - ].into_iter().collect(), + ] + .into_iter() + .collect(), }; - let (result, errs) = ::execute(doc, None, &schema, &vars, &ctx) - .expect("Execution failed"); + let (result, errs) = ::execute(doc, None, &schema, &vars, &ctx).expect("Execution failed"); assert_eq!(errs, []); @@ -427,8 +434,7 @@ mod nulls_out_errors { let vars = vec![].into_iter().collect(); - let (result, errs) = ::execute(doc, None, &schema, &vars, &()) - .expect("Execution failed"); + let (result, errs) = ::execute(doc, None, &schema, &vars, &()).expect("Execution failed"); println!("Result: {:?}", result); @@ -455,7 +461,7 @@ mod named_operations { use value::Value; use schema::model::RootNode; use types::scalars::EmptyMutation; - use ::GraphQLError; + use GraphQLError; struct Schema; @@ -470,8 +476,7 @@ mod named_operations { let vars = vec![].into_iter().collect(); - let (result, errs) = ::execute(doc, None, &schema, &vars, &()) - .expect("Execution failed"); + let (result, errs) = ::execute(doc, None, &schema, &vars, &()).expect("Execution failed"); assert_eq!(errs, []); @@ -489,8 +494,7 @@ mod named_operations { let vars = vec![].into_iter().collect(); - let (result, errs) = ::execute(doc, None, &schema, &vars, &()) - .expect("Execution failed"); + let (result, errs) = ::execute(doc, None, &schema, &vars, &()).expect("Execution failed"); assert_eq!(errs, []); @@ -527,8 +531,7 @@ mod named_operations { let vars = vec![].into_iter().collect(); - let err = ::execute(doc, None, &schema, &vars, &()) - .unwrap_err(); + let err = ::execute(doc, None, &schema, &vars, &()).unwrap_err(); assert_eq!(err, GraphQLError::MultipleOperationsProvided); } @@ -540,8 +543,7 @@ mod named_operations { let vars = vec![].into_iter().collect(); - let err = ::execute(doc, Some("UnknownExample"), &schema, &vars, &()) - .unwrap_err(); + let err = ::execute(doc, Some("UnknownExample"), &schema, &vars, &()).unwrap_err(); assert_eq!(err, GraphQLError::UnknownOperationName); } diff --git a/juniper/src/executor_tests/interfaces_unions.rs b/juniper/src/executor_tests/interfaces_unions.rs index b3dd252c..dc53e572 100644 --- a/juniper/src/executor_tests/interfaces_unions.rs +++ b/juniper/src/executor_tests/interfaces_unions.rs @@ -6,8 +6,12 @@ mod interface { trait Pet { fn name(&self) -> &str; - fn as_dog(&self) -> Option<&Dog> { None } - fn as_cat(&self) -> Option<&Cat> { None } + fn as_dog(&self) -> Option<&Dog> { + None + } + fn as_cat(&self) -> Option<&Cat> { + None + } } graphql_interface!(<'a> &'a Pet: () as "Pet" |&self| { @@ -25,8 +29,12 @@ mod interface { } impl Pet for Dog { - fn name(&self) -> &str { &self.name } - fn as_dog(&self) -> Option<&Dog> { Some(self) } + fn name(&self) -> &str { + &self.name + } + fn as_dog(&self) -> Option<&Dog> { + Some(self) + } } graphql_object!(Dog: () |&self| { @@ -42,8 +50,12 @@ mod interface { } impl Pet for Cat { - fn name(&self) -> &str { &self.name } - fn as_cat(&self) -> Option<&Cat> { Some(self) } + fn name(&self) -> &str { + &self.name + } + fn as_cat(&self) -> Option<&Cat> { + Some(self) + } } graphql_object!(Cat: () |&self| { @@ -65,14 +77,13 @@ mod interface { #[test] fn test() { - let schema = RootNode::new( - Schema { - pets: vec![ + let schema = RootNode::new(Schema { + pets: vec![ Box::new(Dog { name: "Odie".to_owned(), woofs: true }), Box::new(Cat { name: "Garfield".to_owned(), meows: false }), ], - }, - EmptyMutation::<()>::new()); + }, + EmptyMutation::<()>::new()); let doc = r" { pets { @@ -86,11 +97,9 @@ mod interface { } }"; - let vars = vec![ - ].into_iter().collect(); + let vars = vec![].into_iter().collect(); - let (result, errs) = ::execute(doc, None, &schema, &vars, &()) - .expect("Execution failed"); + let (result, errs) = ::execute(doc, None, &schema, &vars, &()).expect("Execution failed"); assert_eq!(errs, []); @@ -122,8 +131,12 @@ mod union { use types::scalars::EmptyMutation; trait Pet { - fn as_dog(&self) -> Option<&Dog> { None } - fn as_cat(&self) -> Option<&Cat> { None } + fn as_dog(&self) -> Option<&Dog> { + None + } + fn as_cat(&self) -> Option<&Cat> { + None + } } graphql_union!(<'a> &'a Pet: () as "Pet" |&self| { @@ -139,7 +152,9 @@ mod union { } impl Pet for Dog { - fn as_dog(&self) -> Option<&Dog> { Some(self) } + fn as_dog(&self) -> Option<&Dog> { + Some(self) + } } graphql_object!(Dog: () |&self| { @@ -153,7 +168,9 @@ mod union { } impl Pet for Cat { - fn as_cat(&self) -> Option<&Cat> { Some(self) } + fn as_cat(&self) -> Option<&Cat> { + Some(self) + } } graphql_object!(Cat: () |&self| { @@ -173,14 +190,13 @@ mod union { #[test] fn test() { - let schema = RootNode::new( - Schema { - pets: vec![ + let schema = RootNode::new(Schema { + pets: vec![ Box::new(Dog { name: "Odie".to_owned(), woofs: true }), Box::new(Cat { name: "Garfield".to_owned(), meows: false }), ], - }, - EmptyMutation::<()>::new()); + }, + EmptyMutation::<()>::new()); let doc = r" { pets { @@ -195,11 +211,9 @@ mod union { } }"; - let vars = vec![ - ].into_iter().collect(); + let vars = vec![].into_iter().collect(); - let (result, errs) = ::execute(doc, None, &schema, &vars, &()) - .expect("Execution failed"); + let (result, errs) = ::execute(doc, None, &schema, &vars, &()).expect("Execution failed"); assert_eq!(errs, []); diff --git a/juniper/src/executor_tests/introspection.rs b/juniper/src/executor_tests/introspection.rs index e5f3719d..0708b922 100644 --- a/juniper/src/executor_tests/introspection.rs +++ b/juniper/src/executor_tests/introspection.rs @@ -114,9 +114,12 @@ fn enum_introspection() { println!("Result: {:?}", result); let type_info = result - .as_object_value().expect("Result is not an object") - .get("__type").expect("__type field missing") - .as_object_value().expect("__type field not an object value"); + .as_object_value() + .expect("Result is not an object") + .get("__type") + .expect("__type field missing") + .as_object_value() + .expect("__type field not an object value"); assert_eq!(type_info.get("name"), Some(&Value::string("SampleEnum"))); assert_eq!(type_info.get("kind"), Some(&Value::string("ENUM"))); @@ -127,8 +130,10 @@ fn enum_introspection() { assert_eq!(type_info.get("ofType"), Some(&Value::null())); let values = type_info - .get("enumValues").expect("enumValues field missing") - .as_list_value().expect("enumValues not a list"); + .get("enumValues") + .expect("enumValues field missing") + .as_list_value() + .expect("enumValues not a list"); assert_eq!(values.len(), 2); @@ -192,9 +197,12 @@ fn interface_introspection() { println!("Result: {:?}", result); let type_info = result - .as_object_value().expect("Result is not an object") - .get("__type").expect("__type field missing") - .as_object_value().expect("__type field not an object value"); + .as_object_value() + .expect("Result is not an object") + .get("__type") + .expect("__type field missing") + .as_object_value() + .expect("__type field not an object value"); assert_eq!(type_info.get("name"), Some(&Value::string("SampleInterface"))); assert_eq!(type_info.get("kind"), Some(&Value::string("INTERFACE"))); @@ -205,8 +213,10 @@ fn interface_introspection() { assert_eq!(type_info.get("ofType"), Some(&Value::null())); let possible_types = type_info - .get("possibleTypes").expect("possibleTypes field missing") - .as_list_value().expect("possibleTypes not a list"); + .get("possibleTypes") + .expect("possibleTypes field missing") + .as_list_value() + .expect("possibleTypes not a list"); assert_eq!(possible_types.len(), 1); @@ -215,8 +225,10 @@ fn interface_introspection() { ].into_iter().collect()))); let fields = type_info - .get("fields").expect("fields field missing") - .as_list_value().expect("fields field not an object value"); + .get("fields") + .expect("fields field missing") + .as_list_value() + .expect("fields field not an object value"); assert_eq!(fields.len(), 1); @@ -293,9 +305,12 @@ fn object_introspection() { println!("Result: {:?}", result); let type_info = result - .as_object_value().expect("Result is not an object") - .get("__type").expect("__type field missing") - .as_object_value().expect("__type field not an object value"); + .as_object_value() + .expect("Result is not an object") + .get("__type") + .expect("__type field missing") + .as_object_value() + .expect("__type field not an object value"); assert_eq!(type_info.get("name"), Some(&Value::string("Root"))); assert_eq!(type_info.get("kind"), Some(&Value::string("OBJECT"))); @@ -313,8 +328,10 @@ fn object_introspection() { assert_eq!(type_info.get("possibleTypes"), Some(&Value::null())); let fields = type_info - .get("fields").expect("fields field missing") - .as_list_value().expect("fields field not an object value"); + .get("fields") + .expect("fields field missing") + .as_list_value() + .expect("fields field not an object value"); assert_eq!(fields.len(), 2); @@ -405,8 +422,10 @@ fn scalar_introspection() { println!("Result: {:?}", result); let type_info = result - .as_object_value().expect("Result is not an object") - .get("__type").expect("__type field missing"); + .as_object_value() + .expect("Result is not an object") + .get("__type") + .expect("__type field missing"); assert_eq!(type_info, &Value::object(vec![ ("name", Value::string("SampleScalar")), diff --git a/juniper/src/executor_tests/variables.rs b/juniper/src/executor_tests/variables.rs index fb4d0b44..48b1c85c 100644 --- a/juniper/src/executor_tests/variables.rs +++ b/juniper/src/executor_tests/variables.rs @@ -4,7 +4,7 @@ use value::Value; use ast::InputValue; use executor::Variables; use schema::model::RootNode; -use ::GraphQLError::ValidationError; +use GraphQLError::ValidationError; use validation::RuleError; use parser::SourcePosition; use types::scalars::EmptyMutation; @@ -123,8 +123,7 @@ fn run_variable_query(query: &str, vars: Variables, f: F) { let schema = RootNode::new(TestType, EmptyMutation::<()>::new()); - let (result, errs) = ::execute(query, None, &schema, &vars, &()) - .expect("Execution failed"); + let (result, errs) = ::execute(query, None, &schema, &vars, &()).expect("Execution failed"); assert_eq!(errs, []); @@ -238,10 +237,11 @@ fn variable_error_on_nested_non_null() { ("b", InputValue::string("bar")), ("c", InputValue::null()), ].into_iter().collect())) - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( @@ -258,10 +258,11 @@ fn variable_error_on_incorrect_type() { let query = r#"query q($input: TestInputObject) { fieldWithObjectInput(input: $input) }"#; let vars = vec![ ("input".to_owned(), InputValue::string("foo bar")), - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( @@ -281,10 +282,11 @@ fn variable_error_on_omit_non_null() { ("a", InputValue::string("foo")), ("b", InputValue::string("bar")), ].into_iter().collect())) - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( @@ -298,17 +300,19 @@ fn variable_error_on_omit_non_null() { fn variable_multiple_errors_with_nesting() { let schema = RootNode::new(TestType, EmptyMutation::<()>::new()); - let query = r#"query q($input: TestNestedInputObject) { fieldWithNestedObjectInput(input: $input) }"#; + 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())) - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( @@ -334,10 +338,11 @@ fn variable_error_on_additional_field() { ("c", InputValue::string("baz")), ("extra", InputValue::string("dog")), ].into_iter().collect())) - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( @@ -349,35 +354,31 @@ fn variable_error_on_additional_field() { #[test] fn allow_nullable_inputs_to_be_omitted() { - run_query( - r#"{ fieldWithNullableStringInput }"#, - |result| { - assert_eq!( + run_query(r#"{ fieldWithNullableStringInput }"#, |result| { + assert_eq!( result.get("fieldWithNullableStringInput"), Some(&Value::string(r#"None"#))); - }); + }); } #[test] fn allow_nullable_inputs_to_be_omitted_in_variable() { - run_query( - r#"query q($value: String) { fieldWithNullableStringInput(input: $value) }"#, - |result| { - assert_eq!( + run_query(r#"query q($value: String) { fieldWithNullableStringInput(input: $value) }"#, + |result| { + assert_eq!( result.get("fieldWithNullableStringInput"), Some(&Value::string(r#"None"#))); - }); + }); } #[test] fn allow_nullable_inputs_to_be_explicitly_null() { - run_query( - r#"{ fieldWithNullableStringInput(input: null) }"#, - |result| { - assert_eq!( + run_query(r#"{ fieldWithNullableStringInput(input: null) }"#, + |result| { + assert_eq!( result.get("fieldWithNullableStringInput"), Some(&Value::string(r#"None"#))); - }); + }); } #[test] @@ -410,13 +411,12 @@ fn allow_nullable_inputs_to_be_set_to_value_in_variable() { #[test] fn allow_nullable_inputs_to_be_set_to_value_directly() { - run_query( - r#"{ fieldWithNullableStringInput(input: "a") }"#, - |result| { - assert_eq!( + run_query(r#"{ fieldWithNullableStringInput(input: "a") }"#, + |result| { + assert_eq!( result.get("fieldWithNullableStringInput"), Some(&Value::string(r#"Some("a")"#))); - }); + }); } #[test] @@ -424,11 +424,9 @@ fn does_not_allow_non_nullable_input_to_be_omitted_in_variable() { let schema = RootNode::new(TestType, EmptyMutation::<()>::new()); let query = r#"query q($value: String!) { fieldWithNonNullableStringInput(input: $value) }"#; - let vars = vec![ - ].into_iter().collect(); + let vars = vec![].into_iter().collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( @@ -445,10 +443,11 @@ fn does_not_allow_non_nullable_input_to_be_set_to_null_in_variable() { let query = r#"query q($value: String!) { fieldWithNonNullableStringInput(input: $value) }"#; let vars = vec![ ("value".to_owned(), InputValue::null()), - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( @@ -474,61 +473,63 @@ fn allow_non_nullable_inputs_to_be_set_to_value_in_variable() { #[test] fn allow_non_nullable_inputs_to_be_set_to_value_directly() { - run_query( - r#"{ fieldWithNonNullableStringInput(input: "a") }"#, - |result| { - assert_eq!( + run_query(r#"{ fieldWithNonNullableStringInput(input: "a") }"#, + |result| { + assert_eq!( result.get("fieldWithNonNullableStringInput"), Some(&Value::string(r#""a""#))); - }); + }); } #[test] fn allow_lists_to_be_null() { - run_variable_query( - r#"query q($input: [String]) { list(input: $input) }"#, - vec![ + run_variable_query(r#"query q($input: [String]) { list(input: $input) }"#, + vec![ ("input".to_owned(), InputValue::null()), - ].into_iter().collect(), - |result| { - assert_eq!( + ] + .into_iter() + .collect(), + |result| { + assert_eq!( result.get("list"), Some(&Value::string(r#"None"#))); - }); + }); } #[test] fn allow_lists_to_contain_values() { - run_variable_query( - r#"query q($input: [String]) { list(input: $input) }"#, - vec![ + run_variable_query(r#"query q($input: [String]) { list(input: $input) }"#, + vec![ ("input".to_owned(), InputValue::list(vec![ InputValue::string("A"), ])), - ].into_iter().collect(), - |result| { - assert_eq!( + ] + .into_iter() + .collect(), + |result| { + assert_eq!( result.get("list"), Some(&Value::string(r#"Some([Some("A")])"#))); - }); + }); } #[test] fn allow_lists_to_contain_null() { - run_variable_query( - r#"query q($input: [String]) { list(input: $input) }"#, - vec![ + 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().collect(), - |result| { - assert_eq!( + ] + .into_iter() + .collect(), + |result| { + assert_eq!( result.get("list"), Some(&Value::string(r#"Some([Some("A"), None, Some("B")])"#))); - }); + }); } #[test] @@ -538,10 +539,11 @@ fn does_not_allow_non_null_lists_to_be_null() { let query = r#"query q($input: [String]!) { nnList(input: $input) }"#; let vars = vec![ ("input".to_owned(), InputValue::null()), - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( @@ -553,65 +555,69 @@ fn does_not_allow_non_null_lists_to_be_null() { #[test] fn allow_non_null_lists_to_contain_values() { - run_variable_query( - r#"query q($input: [String]!) { nnList(input: $input) }"#, - vec![ + run_variable_query(r#"query q($input: [String]!) { nnList(input: $input) }"#, + vec![ ("input".to_owned(), InputValue::list(vec![ InputValue::string("A"), ])), - ].into_iter().collect(), - |result| { - assert_eq!( + ] + .into_iter() + .collect(), + |result| { + assert_eq!( result.get("nnList"), Some(&Value::string(r#"[Some("A")]"#))); - }); + }); } #[test] fn allow_non_null_lists_to_contain_null() { - run_variable_query( - r#"query q($input: [String]!) { nnList(input: $input) }"#, - vec![ + 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().collect(), - |result| { - assert_eq!( + ] + .into_iter() + .collect(), + |result| { + assert_eq!( result.get("nnList"), Some(&Value::string(r#"[Some("A"), None, Some("B")]"#))); - }); + }); } #[test] fn allow_lists_of_non_null_to_be_null() { - run_variable_query( - r#"query q($input: [String!]) { listNn(input: $input) }"#, - vec![ + run_variable_query(r#"query q($input: [String!]) { listNn(input: $input) }"#, + vec![ ("input".to_owned(), InputValue::null()), - ].into_iter().collect(), - |result| { - assert_eq!( + ] + .into_iter() + .collect(), + |result| { + assert_eq!( result.get("listNn"), Some(&Value::string(r#"None"#))); - }); + }); } #[test] fn allow_lists_of_non_null_to_contain_values() { - run_variable_query( - r#"query q($input: [String!]) { listNn(input: $input) }"#, - vec![ + run_variable_query(r#"query q($input: [String!]) { listNn(input: $input) }"#, + vec![ ("input".to_owned(), InputValue::list(vec![ InputValue::string("A"), ])), - ].into_iter().collect(), - |result| { - assert_eq!( + ] + .into_iter() + .collect(), + |result| { + assert_eq!( result.get("listNn"), Some(&Value::string(r#"Some(["A"])"#))); - }); + }); } #[test] @@ -625,10 +631,11 @@ fn does_not_allow_lists_of_non_null_to_contain_null() { InputValue::null(), InputValue::string("B"), ])), - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( @@ -649,10 +656,11 @@ fn does_not_allow_non_null_lists_of_non_null_to_contain_null() { InputValue::null(), InputValue::string("B"), ])), - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( @@ -669,10 +677,11 @@ fn does_not_allow_non_null_lists_of_non_null_to_be_null() { let query = r#"query q($input: [String!]!) { nnListNn(input: $input) }"#; let vars = vec![ ("value".to_owned(), InputValue::null()), - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( @@ -684,18 +693,19 @@ fn does_not_allow_non_null_lists_of_non_null_to_be_null() { #[test] fn allow_non_null_lists_of_non_null_to_contain_values() { - run_variable_query( - r#"query q($input: [String!]!) { nnListNn(input: $input) }"#, - vec![ + run_variable_query(r#"query q($input: [String!]!) { nnListNn(input: $input) }"#, + vec![ ("input".to_owned(), InputValue::list(vec![ InputValue::string("A"), ])), - ].into_iter().collect(), - |result| { - assert_eq!( + ] + .into_iter() + .collect(), + |result| { + assert_eq!( result.get("nnListNn"), Some(&Value::string(r#"["A"]"#))); - }); + }); } #[test] @@ -708,10 +718,11 @@ fn does_not_allow_invalid_types_to_be_used_as_values() { InputValue::string("A"), InputValue::string("B"), ])), - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( @@ -731,10 +742,11 @@ fn does_not_allow_unknown_types_to_be_used_as_values() { InputValue::string("A"), InputValue::string("B"), ])), - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( @@ -746,24 +758,21 @@ fn does_not_allow_unknown_types_to_be_used_as_values() { #[test] fn default_argument_when_not_provided() { - run_query( - r#"{ fieldWithDefaultArgumentValue }"#, - |result| { - assert_eq!( + run_query(r#"{ fieldWithDefaultArgumentValue }"#, |result| { + assert_eq!( result.get("fieldWithDefaultArgumentValue"), Some(&Value::string(r#""Hello World""#))); - }); + }); } #[test] fn default_argument_when_nullable_variable_not_provided() { - run_query( - r#"query q($input: String) { fieldWithDefaultArgumentValue(input: $input) }"#, - |result| { - assert_eq!( + run_query(r#"query q($input: String) { fieldWithDefaultArgumentValue(input: $input) }"#, + |result| { + assert_eq!( result.get("fieldWithDefaultArgumentValue"), Some(&Value::string(r#""Hello World""#))); - }); + }); } #[test] @@ -782,56 +791,52 @@ fn default_argument_when_nullable_variable_set_to_null() { #[test] fn nullable_input_object_arguments_successful_without_variables() { - run_query( - r#"{ exampleInput(arg: {a: "abc", b: 123}) }"#, - |result| { - assert_eq!( + run_query(r#"{ exampleInput(arg: {a: "abc", b: 123}) }"#, |result| { + assert_eq!( result.get("exampleInput"), Some(&Value::string(r#"a: Some("abc"), b: 123"#))); - }); + }); - run_query( - r#"{ exampleInput(arg: {a: null, b: 1}) }"#, - |result| { - assert_eq!( + run_query(r#"{ exampleInput(arg: {a: null, b: 1}) }"#, |result| { + assert_eq!( result.get("exampleInput"), Some(&Value::string(r#"a: None, b: 1"#))); - }); + }); } #[test] fn nullable_input_object_arguments_successful_with_variables() { - run_variable_query( - r#"query q($var: Int!) { exampleInput(arg: {b: $var}) }"#, - vec![ + run_variable_query(r#"query q($var: Int!) { exampleInput(arg: {b: $var}) }"#, + vec![ ("var".to_owned(), InputValue::int(123)), - ].into_iter().collect(), - |result| { - assert_eq!( + ] + .into_iter() + .collect(), + |result| { + assert_eq!( result.get("exampleInput"), Some(&Value::string(r#"a: None, b: 123"#))); - }); + }); - run_variable_query( - r#"query q($var: String) { exampleInput(arg: {a: $var, b: 1}) }"#, - vec![ + run_variable_query(r#"query q($var: String) { exampleInput(arg: {a: $var, b: 1}) }"#, + vec![ ("var".to_owned(), InputValue::null()), - ].into_iter().collect(), - |result| { - assert_eq!( + ] + .into_iter() + .collect(), + |result| { + assert_eq!( result.get("exampleInput"), Some(&Value::string(r#"a: None, b: 1"#))); - }); + }); - run_variable_query( - r#"query q($var: String) { exampleInput(arg: {a: $var, b: 1}) }"#, - vec![ - ].into_iter().collect(), - |result| { - assert_eq!( + run_variable_query(r#"query q($var: String) { exampleInput(arg: {a: $var, b: 1}) }"#, + vec![].into_iter().collect(), + |result| { + assert_eq!( result.get("exampleInput"), Some(&Value::string(r#"a: None, b: 1"#))); - }); + }); } #[test] @@ -839,11 +844,9 @@ fn does_not_allow_missing_required_field() { let schema = RootNode::new(TestType, EmptyMutation::<()>::new()); let query = r#"{ exampleInput(arg: {a: "abc"}) }"#; - let vars = vec![ - ].into_iter().collect(); + let vars = vec![].into_iter().collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( @@ -858,11 +861,9 @@ fn does_not_allow_null_in_required_field() { let schema = RootNode::new(TestType, EmptyMutation::<()>::new()); let query = r#"{ exampleInput(arg: {a: "abc", b: null}) }"#; - let vars = vec![ - ].into_iter().collect(); + let vars = vec![].into_iter().collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( @@ -877,11 +878,9 @@ fn does_not_allow_missing_variable_for_required_field() { let schema = RootNode::new(TestType, EmptyMutation::<()>::new()); let query = r#"query q($var: Int!) { exampleInput(arg: {b: $var}) }"#; - let vars = vec![ - ].into_iter().collect(); + let vars = vec![].into_iter().collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( @@ -898,10 +897,11 @@ fn does_not_allow_null_variable_for_required_field() { let query = r#"query q($var: Int!) { exampleInput(arg: {b: $var}) }"#; let vars = vec![ ("var".to_owned(), InputValue::null()), - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( @@ -913,45 +913,43 @@ fn does_not_allow_null_variable_for_required_field() { #[test] fn input_object_with_default_values() { - run_query( - r#"{ inputWithDefaults(arg: {a: 1}) }"#, - |result| { - assert_eq!( + run_query(r#"{ inputWithDefaults(arg: {a: 1}) }"#, |result| { + assert_eq!( result.get("inputWithDefaults"), Some(&Value::string(r#"a: 1"#))); - }); + }); - run_variable_query( - r#"query q($var: Int!) { inputWithDefaults(arg: {a: $var}) }"#, - vec![ + run_variable_query(r#"query q($var: Int!) { inputWithDefaults(arg: {a: $var}) }"#, + vec![ ("var".to_owned(), InputValue::int(1)), - ].into_iter().collect(), - |result| { - assert_eq!( + ] + .into_iter() + .collect(), + |result| { + assert_eq!( result.get("inputWithDefaults"), Some(&Value::string(r#"a: 1"#))); - }); + }); - run_variable_query( - r#"query q($var: Int = 1) { inputWithDefaults(arg: {a: $var}) }"#, - vec![ - ].into_iter().collect(), - |result| { - assert_eq!( + run_variable_query(r#"query q($var: Int = 1) { inputWithDefaults(arg: {a: $var}) }"#, + vec![].into_iter().collect(), + |result| { + assert_eq!( result.get("inputWithDefaults"), Some(&Value::string(r#"a: 1"#))); - }); + }); - run_variable_query( - r#"query q($var: Int = 1) { inputWithDefaults(arg: {a: $var}) }"#, - vec![ + run_variable_query(r#"query q($var: Int = 1) { inputWithDefaults(arg: {a: $var}) }"#, + vec![ ("var".to_owned(), InputValue::int(2)), - ].into_iter().collect(), - |result| { - assert_eq!( + ] + .into_iter() + .collect(), + |result| { + assert_eq!( result.get("inputWithDefaults"), Some(&Value::string(r#"a: 2"#))); - }); + }); } @@ -960,27 +958,29 @@ mod integers { #[test] fn positive_and_negative_should_work() { - run_variable_query( - r#"query q($var: Int!) { integerInput(value: $var) }"#, - vec![ + run_variable_query(r#"query q($var: Int!) { integerInput(value: $var) }"#, + vec![ ("var".to_owned(), InputValue::int(1)), - ].into_iter().collect(), - |result| { - assert_eq!( + ] + .into_iter() + .collect(), + |result| { + assert_eq!( result.get("integerInput"), Some(&Value::string(r#"value: 1"#))); - }); + }); - run_variable_query( - r#"query q($var: Int!) { integerInput(value: $var) }"#, - vec![ + run_variable_query(r#"query q($var: Int!) { integerInput(value: $var) }"#, + vec![ ("var".to_owned(), InputValue::int(-1)), - ].into_iter().collect(), - |result| { - assert_eq!( + ] + .into_iter() + .collect(), + |result| { + assert_eq!( result.get("integerInput"), Some(&Value::string(r#"value: -1"#))); - }); + }); } #[test] @@ -990,10 +990,11 @@ mod integers { let query = r#"query q($var: Int!) { integerInput(value: $var) }"#; let vars = vec![ ("var".to_owned(), InputValue::float(10.0)), - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( @@ -1010,10 +1011,11 @@ mod integers { let query = r#"query q($var: Int!) { integerInput(value: $var) }"#; let vars = vec![ ("var".to_owned(), InputValue::string("10")), - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( @@ -1030,30 +1032,32 @@ mod floats { #[test] fn float_values_should_work() { - run_variable_query( - r#"query q($var: Float!) { floatInput(value: $var) }"#, - vec![ + run_variable_query(r#"query q($var: Float!) { floatInput(value: $var) }"#, + vec![ ("var".to_owned(), InputValue::float(10.0)), - ].into_iter().collect(), - |result| { - assert_eq!( + ] + .into_iter() + .collect(), + |result| { + assert_eq!( result.get("floatInput"), Some(&Value::string(r#"value: 10"#))); - }); + }); } #[test] fn coercion_from_integers_should_work() { - run_variable_query( - r#"query q($var: Float!) { floatInput(value: $var) }"#, - vec![ + run_variable_query(r#"query q($var: Float!) { floatInput(value: $var) }"#, + vec![ ("var".to_owned(), InputValue::int(-1)), - ].into_iter().collect(), - |result| { - assert_eq!( + ] + .into_iter() + .collect(), + |result| { + assert_eq!( result.get("floatInput"), Some(&Value::string(r#"value: -1"#))); - }); + }); } #[test] @@ -1063,10 +1067,11 @@ mod floats { let query = r#"query q($var: Float!) { floatInput(value: $var) }"#; let vars = vec![ ("var".to_owned(), InputValue::string("10")), - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let error = ::execute(query, None, &schema, &vars, &()) - .unwrap_err(); + let error = ::execute(query, None, &schema, &vars, &()).unwrap_err(); assert_eq!(error, ValidationError(vec![ RuleError::new( diff --git a/juniper/src/graphiql.rs b/juniper/src/graphiql.rs index bffbb3ef..7e0d11c6 100644 --- a/juniper/src/graphiql.rs +++ b/juniper/src/graphiql.rs @@ -64,4 +64,4 @@ pub fn graphiql_source(graphql_endpoint_url: &str) -> String { stylesheet_source = stylesheet_source, fetcher_source = fetcher_source) -} \ No newline at end of file +} diff --git a/juniper/src/http.rs b/juniper/src/http.rs index ad87b0b7..234fe2af 100644 --- a/juniper/src/http.rs +++ b/juniper/src/http.rs @@ -3,7 +3,7 @@ use serde::ser; use serde::ser::SerializeMap; -use ::{GraphQLError, Value, Variables, GraphQLType, RootNode}; +use {GraphQLError, Value, Variables, GraphQLType, RootNode}; use ast::InputValue; use executor::ExecutionError; @@ -19,7 +19,7 @@ pub struct GraphQLRequest { query: String, #[serde(rename = "operationName")] operation_name: Option, - variables: Option + variables: Option, } impl GraphQLRequest { @@ -28,15 +28,24 @@ impl GraphQLRequest { } fn variables(&self) -> Variables { - self.variables.as_ref().and_then(|iv| { - iv.to_object_value().map(|o| { - o.into_iter().map(|(k, v)| (k.to_owned(), v.clone())).collect() - }) - }).unwrap_or_default() + self.variables + .as_ref() + .and_then(|iv| { + iv.to_object_value() + .map(|o| { + o.into_iter() + .map(|(k, v)| (k.to_owned(), v.clone())) + .collect() + }) + }) + .unwrap_or_default() } /// Construct a new GraphQL request from parts - pub fn new(query: String, operation_name: Option, variables: Option) -> GraphQLRequest { + pub fn new(query: String, + operation_name: Option, + variables: Option) + -> GraphQLRequest { GraphQLRequest { query: query, operation_name: operation_name, @@ -48,22 +57,18 @@ impl GraphQLRequest { /// /// This is a simple wrapper around the `execute` function exposed at the /// top level of this crate. - pub fn execute<'a, CtxT, QueryT, MutationT>( - &'a self, - root_node: &RootNode, - context: &CtxT, - ) - -> GraphQLResponse<'a> - where QueryT: GraphQLType, - MutationT: GraphQLType, + pub fn execute<'a, CtxT, QueryT, MutationT>(&'a self, + root_node: &RootNode, + context: &CtxT) + -> GraphQLResponse<'a> + where QueryT: GraphQLType, + MutationT: GraphQLType { - GraphQLResponse(::execute( - &self.query, - self.operation_name(), - root_node, - &self.variables(), - context, - )) + GraphQLResponse(::execute(&self.query, + self.operation_name(), + root_node, + &self.variables(), + context)) } } @@ -86,7 +91,7 @@ impl<'a> GraphQLResponse<'a> { impl<'a> ser::Serialize for GraphQLResponse<'a> { fn serialize(&self, serializer: S) -> Result - where S: ser::Serializer, + where S: ser::Serializer { match self.0 { Ok((ref res, ref err)) => { @@ -101,18 +106,18 @@ impl<'a> ser::Serialize for GraphQLResponse<'a> { } map.end() - }, + } Err(ref err) => { let mut map = try!(serializer.serialize_map(Some(1))); try!(map.serialize_key("errors")); try!(map.serialize_value(err)); map.end() - }, + } } } } -#[cfg(all(test, any(feature="iron-handlers", feature="rocket-handlers")))] +#[cfg(any(test, feature="expose-test-schema"))] pub mod tests { use serde_json::Value as Json; use serde_json; @@ -145,9 +150,11 @@ pub mod tests { } fn unwrap_json_response(response: &TestResponse) -> Json { - serde_json::from_str::( - response.body.as_ref().expect("No data returned from request") - ).expect("Could not parse JSON object") + serde_json::from_str::(response + .body + .as_ref() + .expect("No data returned from request")) + .expect("Could not parse JSON object") } fn test_simple_get(integration: &T) { @@ -215,9 +222,7 @@ pub mod tests { } fn test_simple_post(integration: &T) { - let response = integration.post( - "/", - r#"{"query": "{hero{name}}"}"#); + let response = integration.post("/", r#"{"query": "{hero{name}}"}"#); assert_eq!(response.status_code, 200); assert_eq!(response.content_type, "application/json"); diff --git a/juniper/src/integrations/mod.rs b/juniper/src/integrations/mod.rs index 42a4fb7b..82b2d094 100644 --- a/juniper/src/integrations/mod.rs +++ b/juniper/src/integrations/mod.rs @@ -1,3 +1 @@ -#[cfg(feature="iron-handlers")] pub mod iron_handlers; -#[cfg(feature="rocket-handlers")] pub mod rocket_handlers; pub mod serde; diff --git a/juniper/src/integrations/serde.rs b/juniper/src/integrations/serde.rs index 53eaf2bd..45e79327 100644 --- a/juniper/src/integrations/serde.rs +++ b/juniper/src/integrations/serde.rs @@ -3,7 +3,7 @@ use serde::ser::SerializeMap; use std::fmt; use std::collections::HashMap; -use ::{GraphQLError, Value}; +use {GraphQLError, Value}; use ast::InputValue; use executor::ExecutionError; use parser::{ParseError, Spanning, SourcePosition}; @@ -12,7 +12,7 @@ use validation::RuleError; impl ser::Serialize for ExecutionError { fn serialize(&self, serializer: S) -> Result - where S: ser::Serializer, + where S: ser::Serializer { let mut map = try!(serializer.serialize_map(Some(3))); @@ -32,27 +32,25 @@ impl ser::Serialize for ExecutionError { impl<'a> ser::Serialize for GraphQLError<'a> { fn serialize(&self, serializer: S) -> Result - where S: ser::Serializer, + where S: ser::Serializer { match *self { GraphQLError::ParseError(ref err) => vec![err].serialize(serializer), GraphQLError::ValidationError(ref errs) => errs.serialize(serializer), GraphQLError::NoOperationProvided => { serializer.serialize_str("Must provide an operation") - }, + } GraphQLError::MultipleOperationsProvided => { serializer.serialize_str("Must provide operation name if query contains multiple operations") - }, - GraphQLError::UnknownOperationName => { - serializer.serialize_str("Unknown operation") - }, + } + GraphQLError::UnknownOperationName => serializer.serialize_str("Unknown operation"), } } } impl<'de> de::Deserialize<'de> for InputValue { fn deserialize(deserializer: D) -> Result - where D: de::Deserializer<'de>, + where D: de::Deserializer<'de> { struct InputValueVisitor; @@ -68,23 +66,21 @@ impl<'de> de::Deserialize<'de> for InputValue { } fn visit_i64(self, value: i64) -> Result - where E: de::Error, + where E: de::Error { if value >= i32::min_value() as i64 && value <= i32::max_value() as i64 { Ok(InputValue::int(value as i32)) - } - else { + } else { Err(E::custom(format!("integer out of range"))) } } fn visit_u64(self, value: u64) -> Result - where E: de::Error, + where E: de::Error { if value <= i32::max_value() as u64 { self.visit_i64(value as i64) - } - else { + } else { Err(E::custom(format!("integer out of range"))) } } @@ -94,7 +90,7 @@ impl<'de> de::Deserialize<'de> for InputValue { } fn visit_str(self, value: &str) -> Result - where E: de::Error, + where E: de::Error { self.visit_string(value.into()) } @@ -112,7 +108,7 @@ impl<'de> de::Deserialize<'de> for InputValue { } fn visit_seq(self, mut visitor: V) -> Result - where V: de::SeqAccess<'de>, + where V: de::SeqAccess<'de> { let mut values = Vec::new(); @@ -124,7 +120,7 @@ impl<'de> de::Deserialize<'de> for InputValue { } fn visit_map(self, mut visitor: V) -> Result - where V: de::MapAccess<'de>, + where V: de::MapAccess<'de> { let mut values: HashMap = HashMap::new(); @@ -142,30 +138,35 @@ impl<'de> de::Deserialize<'de> for InputValue { impl ser::Serialize for InputValue { fn serialize(&self, serializer: S) -> Result - where S: ser::Serializer, + where S: ser::Serializer { match *self { - InputValue::Null | InputValue::Variable(_) => serializer.serialize_unit(), + InputValue::Null | + InputValue::Variable(_) => serializer.serialize_unit(), InputValue::Int(v) => serializer.serialize_i64(v as i64), InputValue::Float(v) => serializer.serialize_f64(v), - InputValue::String(ref v) | InputValue::Enum(ref v) => serializer.serialize_str(v), + InputValue::String(ref v) | + InputValue::Enum(ref v) => serializer.serialize_str(v), InputValue::Boolean(v) => serializer.serialize_bool(v), InputValue::List(ref v) => { - v.iter().map(|x| x.item.clone()).collect::>().serialize(serializer) - }, + v.iter() + .map(|x| x.item.clone()) + .collect::>() + .serialize(serializer) + } InputValue::Object(ref v) => { v.iter() .map(|&(ref k, ref v)| (k.item.clone(), v.item.clone())) .collect::>() .serialize(serializer) - }, + } } } } impl ser::Serialize for RuleError { fn serialize(&self, serializer: S) -> Result - where S: ser::Serializer, + where S: ser::Serializer { let mut map = try!(serializer.serialize_map(Some(2))); @@ -181,7 +182,7 @@ impl ser::Serialize for RuleError { impl ser::Serialize for SourcePosition { fn serialize(&self, serializer: S) -> Result - where S: ser::Serializer, + where S: ser::Serializer { let mut map = try!(serializer.serialize_map(Some(2))); @@ -199,7 +200,7 @@ impl ser::Serialize for SourcePosition { impl<'a> ser::Serialize for Spanning> { fn serialize(&self, serializer: S) -> Result - where S: ser::Serializer, + where S: ser::Serializer { let mut map = try!(serializer.serialize_map(Some(2))); @@ -222,7 +223,7 @@ impl<'a> ser::Serialize for Spanning> { impl ser::Serialize for Value { fn serialize(&self, serializer: S) -> Result - where S: ser::Serializer, + where S: ser::Serializer { match *self { Value::Null => serializer.serialize_unit(), diff --git a/juniper/src/lib.rs b/juniper/src/lib.rs index 1ad76b71..68f21897 100644 --- a/juniper/src/lib.rs +++ b/juniper/src/lib.rs @@ -10,14 +10,12 @@ statically verify their queries against a server without actually executing them. This library provides data types and traits to expose Rust types in a GraphQL -schema, as well as an optional integration into the [Iron framework][2] and +schema, as well as an optional integration into the [Iron framework][Iron] and [Rocket]. It tries to keep the number of dynamic operations to a minimum, and give you as the schema developer the control of the query execution path. Juniper only depends on `serde` and `serde_derive` by default, making it -lightweight and easy to drop into any project. If you enable any of the -optional framework integrations, it will naturally depend on those frameworks -too. +lightweight and easy to drop into any project. ## Exposing data types @@ -96,93 +94,18 @@ Adding per type, field, and argument documentation is possible directly from this macro. For more in-depth information on how to expose fields and types, see the [`graphql_object!`][3] macro. -## Integrating with Iron + +## Integrating with web servers The most obvious usecase is to expose the GraphQL schema over an HTTP endpoint. -To support this, the library provides optional and customizable handlers for -both Iron and Rocket. +To support this, Juniper offers additional crates that integrate with popular web frameworks. -For example, continuing from the schema created above and using Iron to expose -the schema on an HTTP endpoint supporting both GET and POST requests: - -```rust,no_run -extern crate iron; -# #[macro_use] extern crate juniper; -# use std::collections::HashMap; - -use iron::prelude::*; -use juniper::iron_handlers::GraphQLHandler; -use juniper::{Context, EmptyMutation}; - -# use juniper::FieldResult; -# -# struct User { id: String, name: String, friend_ids: Vec } -# struct QueryRoot; -# struct Database { users: HashMap } -# -# graphql_object!(User: Database |&self| { -# field id() -> FieldResult<&String> { -# Ok(&self.id) -# } -# -# field name() -> FieldResult<&String> { -# Ok(&self.name) -# } -# -# field friends(&executor) -> FieldResult> { -# Ok(self.friend_ids.iter() -# .filter_map(|id| executor.context().users.get(id)) -# .collect()) -# } -# }); -# -# graphql_object!(QueryRoot: Database |&self| { -# field user(&executor, id: String) -> FieldResult> { -# Ok(executor.context().users.get(&id)) -# } -# }); - -// This function is executed for every request. Here, we would realistically -// provide a database connection or similar. For this example, we'll be -// creating the database from scratch. -fn context_factory(_: &mut Request) -> Database { - Database { - users: vec![ - ( "1000".to_owned(), User { - id: "1000".to_owned(), name: "Robin".to_owned(), - friend_ids: vec!["1001".to_owned()] } ), - ( "1001".to_owned(), User { - id: "1001".to_owned(), name: "Max".to_owned(), - friend_ids: vec!["1000".to_owned()] } ), - ].into_iter().collect() - } -} - -impl Context for Database {} - -fn main() { - // GraphQLHandler takes a context factory function, the root object, - // and the mutation object. If we don't have any mutations to expose, we - // can use the empty tuple () to indicate absence. - let graphql_endpoint = GraphQLHandler::new( - context_factory, QueryRoot, EmptyMutation::::new()); - - // Start serving the schema at the root on port 8080. - Iron::new(graphql_endpoint).http("localhost:8080").unwrap(); -} - -``` - -See the [`iron_handlers`][4] module and the [`GraphQLHandler`][5] documentation -for more information on what request methods are supported. There's also a -built-in [GraphiQL][6] handler included. +* [juniper_iron][juniper_iron]: Handlers for [Iron][Iron] +* [juniper_rocket][juniper_rocket]: Handlers for [Rocket][Rocket] [1]: http://graphql.org -[2]: http://ironframework.io [3]: macro.graphql_object!.html -[4]: iron_handlers/index.html -[5]: iron_handlers/struct.GraphQLHandler.html -[6]: https://github.com/graphql/graphiql +[Iron]: http://ironframework.io [Rocket]: https://rocket.rs */ @@ -190,22 +113,19 @@ built-in [GraphiQL][6] handler included. #![cfg_attr(feature="nightly", feature(test))] #![warn(missing_docs)] -#![cfg_attr(feature="rocket-handlers", feature(plugin))] -#![cfg_attr(feature="rocket-handlers", plugin(rocket_codegen))] -#[cfg(feature="rocket-handlers")] extern crate rocket; - -#[cfg(feature="nightly")] extern crate test; -#[cfg(feature="iron-handlers")] #[macro_use(itry)] extern crate iron; -#[cfg(feature="iron-handlers")] extern crate urlencoded; -#[cfg(test)] extern crate iron_test; +#[cfg(feature="nightly")] +extern crate test; extern crate serde; -#[macro_use] extern crate serde_derive; +#[macro_use] +extern crate serde_derive; -#[cfg(any(feature="iron-handlers", feature="rocket-handlers"))] extern crate serde_json; +#[cfg(any(test, feature="expose-test-schema"))] +extern crate serde_json; use std::borrow::Cow; -#[macro_use] mod macros; +#[macro_use] +mod macros; mod ast; pub mod parser; mod value; @@ -216,12 +136,16 @@ mod executor; mod integrations; pub mod graphiql; pub mod http; -#[macro_use] mod result_ext; +#[macro_use] +mod result_ext; -#[cfg(all(test, not(feature="expose-test-schema")))] mod tests; -#[cfg(feature="expose-test-schema")] pub mod tests; +#[cfg(all(test, not(feature="expose-test-schema")))] +mod tests; +#[cfg(feature="expose-test-schema")] +pub mod tests; -#[cfg(test)] mod executor_tests; +#[cfg(test)] +mod executor_tests; use parser::{parse_document_source, ParseError, Spanning}; use validation::{ValidatorContext, visit_all_rules, validate_input_values}; @@ -230,11 +154,8 @@ use executor::execute_validated_query; pub use ast::{ToInputValue, FromInputValue, InputValue, Type, Selection}; pub use value::Value; pub use types::base::{Arguments, GraphQLType, TypeKind}; -pub use executor::{ - Executor, ExecutionError, Registry, - Context, FromContext, IntoResolvable, - FieldResult, ExecutionResult, Variables, -}; +pub use executor::{Executor, ExecutionError, Registry, Context, FromContext, IntoResolvable, + FieldResult, ExecutionResult, Variables}; pub use validation::RuleError; pub use types::scalars::{EmptyMutation, ID}; pub use schema::model::RootNode; @@ -242,9 +163,6 @@ pub use result_ext::ResultExt; pub use schema::meta; -#[cfg(feature="iron-handlers")] pub use integrations::iron_handlers; -#[cfg(feature="rocket-handlers")] pub use integrations::rocket_handlers; - /// An error that prevented query execution #[derive(Debug, PartialEq)] #[allow(missing_docs)] @@ -257,16 +175,15 @@ pub enum GraphQLError<'a> { } /// Execute a query in a provided schema -pub fn execute<'a, CtxT, QueryT, MutationT>( - document_source: &'a str, - operation_name: Option<&str>, - root_node: &RootNode, - variables: &Variables, - context: &CtxT, -) - -> Result<(Value, Vec), GraphQLError<'a>> - where QueryT: GraphQLType, - MutationT: GraphQLType, +pub fn execute<'a, CtxT, QueryT, MutationT> + (document_source: &'a str, + operation_name: Option<&str>, + root_node: &RootNode, + variables: &Variables, + context: &CtxT) + -> Result<(Value, Vec), GraphQLError<'a>> + where QueryT: GraphQLType, + MutationT: GraphQLType { let document = try!(parse_document_source(document_source)); @@ -304,15 +221,17 @@ pub fn to_camel_case<'a>(s: &'a str) -> Cow<'a, str> { for (i, part) in s.split('_').enumerate() { if i > 0 && part.len() == 1 { dest += Cow::Owned(part.to_uppercase()); - } - else if i > 0 && part.len() > 1 { - let first = part.chars().next().unwrap().to_uppercase().collect::(); + } else if i > 0 && part.len() > 1 { + let first = part.chars() + .next() + .unwrap() + .to_uppercase() + .collect::(); let second = &part[1..]; dest += Cow::Owned(first); dest += second; - } - else if i == 0 { + } else if i == 0 { dest = Cow::Borrowed(part); } } diff --git a/juniper/src/macros/mod.rs b/juniper/src/macros/mod.rs index cac41ddb..d62970ea 100644 --- a/juniper/src/macros/mod.rs +++ b/juniper/src/macros/mod.rs @@ -1,10 +1,19 @@ -#[macro_use] mod enums; -#[macro_use] mod object; -#[macro_use] mod interface; -#[macro_use] mod scalar; -#[macro_use] mod args; -#[macro_use] mod field; -#[macro_use] mod input_object; -#[macro_use] mod union; +#[macro_use] +mod enums; +#[macro_use] +mod object; +#[macro_use] +mod interface; +#[macro_use] +mod scalar; +#[macro_use] +mod args; +#[macro_use] +mod field; +#[macro_use] +mod input_object; +#[macro_use] +mod union; -#[cfg(test)] mod tests; +#[cfg(test)] +mod tests; diff --git a/juniper/src/macros/tests/args.rs b/juniper/src/macros/tests/args.rs index c65ee7d9..c8b81e75 100644 --- a/juniper/src/macros/tests/args.rs +++ b/juniper/src/macros/tests/args.rs @@ -110,28 +110,41 @@ fn run_args_info_query(field_name: &str, f: F) println!("Result: {:?}", result); let type_info = result - .as_object_value().expect("Result is not an object") - .get("__type").expect("__type field missing") - .as_object_value().expect("__type field not an object value"); + .as_object_value() + .expect("Result is not an object") + .get("__type") + .expect("__type field missing") + .as_object_value() + .expect("__type field not an object value"); let fields = type_info - .get("fields").expect("fields field missing") - .as_list_value().expect("fields not a list"); + .get("fields") + .expect("fields field missing") + .as_list_value() + .expect("fields not a list"); let field = fields - .into_iter().filter( - |f| f.as_object_value().expect("Field not an object") - .get("name").expect("name field missing from field") - .as_string_value().expect("name is not a string") - == field_name) - .next().expect("Field not found") - .as_object_value().expect("Field is not an object"); + .into_iter() + .filter(|f| { + f.as_object_value() + .expect("Field not an object") + .get("name") + .expect("name field missing from field") + .as_string_value() + .expect("name is not a string") == field_name + }) + .next() + .expect("Field not found") + .as_object_value() + .expect("Field is not an object"); println!("Field: {:?}", field); let args = field - .get("args").expect("args missing from field") - .as_list_value().expect("args is not a list"); + .get("args") + .expect("args missing from field") + .as_list_value() + .expect("args is not a list"); println!("Args: {:?}", args); diff --git a/juniper/src/macros/tests/enums.rs b/juniper/src/macros/tests/enums.rs index a29df66d..c992cc61 100644 --- a/juniper/src/macros/tests/enums.rs +++ b/juniper/src/macros/tests/enums.rs @@ -6,12 +6,30 @@ use schema::model::RootNode; use types::scalars::EmptyMutation; -enum DefaultName { Foo, Bar } -enum Named { Foo, Bar } -enum NoTrailingComma { Foo, Bar } -enum EnumDescription { Foo, Bar } -enum EnumValueDescription { Foo, Bar } -enum EnumDeprecation { Foo, Bar } +enum DefaultName { + Foo, + Bar, +} +enum Named { + Foo, + Bar, +} +enum NoTrailingComma { + Foo, + Bar, +} +enum EnumDescription { + Foo, + Bar, +} +enum EnumValueDescription { + Foo, + Bar, +} +enum EnumDeprecation { + Foo, + Bar, +} struct Root; @@ -68,7 +86,9 @@ graphql_object!(Root: () |&self| { field enum_deprecation() -> EnumDeprecation { EnumDeprecation::Foo } }); -fn run_type_info_query(doc: &str, f: F) where F: Fn((&HashMap, &Vec)) -> () { +fn run_type_info_query(doc: &str, f: F) + where F: Fn((&HashMap, &Vec)) -> () +{ let schema = RootNode::new(Root {}, EmptyMutation::<()>::new()); let (result, errs) = ::execute(doc, None, &schema, &Variables::new(), &()) @@ -79,13 +99,18 @@ fn run_type_info_query(doc: &str, f: F) where F: Fn((&HashMap, println!("Result: {:?}", result); let type_info = result - .as_object_value().expect("Result is not an object") - .get("__type").expect("__type field missing") - .as_object_value().expect("__type field not an object value"); + .as_object_value() + .expect("Result is not an object") + .get("__type") + .expect("__type field missing") + .as_object_value() + .expect("__type field not an object value"); let values = type_info - .get("enumValues").expect("enumValues field missing") - .as_list_value().expect("enumValues not a list"); + .get("enumValues") + .expect("enumValues field missing") + .as_list_value() + .expect("enumValues not a list"); f((type_info, values)); } diff --git a/juniper/src/macros/tests/field.rs b/juniper/src/macros/tests/field.rs index c1b2198d..86ce928c 100644 --- a/juniper/src/macros/tests/field.rs +++ b/juniper/src/macros/tests/field.rs @@ -75,32 +75,44 @@ fn run_field_info_query(type_name: &str, field_name: &str, f: F) let schema = RootNode::new(Root {}, EmptyMutation::<()>::new()); let vars = vec![ ("typeName".to_owned(), InputValue::string(type_name)), - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let (result, errs) = ::execute(doc, None, &schema, &vars, &()) - .expect("Execution failed"); + let (result, errs) = ::execute(doc, None, &schema, &vars, &()).expect("Execution failed"); assert_eq!(errs, []); println!("Result: {:?}", result); let type_info = result - .as_object_value().expect("Result is not an object") - .get("__type").expect("__type field missing") - .as_object_value().expect("__type field not an object value"); + .as_object_value() + .expect("Result is not an object") + .get("__type") + .expect("__type field missing") + .as_object_value() + .expect("__type field not an object value"); let fields = type_info - .get("fields").expect("fields field missing") - .as_list_value().expect("fields not a list"); + .get("fields") + .expect("fields field missing") + .as_list_value() + .expect("fields not a list"); let field = fields - .into_iter().filter( - |f| f.as_object_value().expect("Field not an object") - .get("name").expect("name field missing from field") - .as_string_value().expect("name is not a string") - == field_name) - .next().expect("Field not found") - .as_object_value().expect("Field is not an object"); + .into_iter() + .filter(|f| { + f.as_object_value() + .expect("Field not an object") + .get("name") + .expect("name field missing from field") + .as_string_value() + .expect("name is not a string") == field_name + }) + .next() + .expect("Field not found") + .as_object_value() + .expect("Field is not an object"); println!("Field: {:?}", field); diff --git a/juniper/src/macros/tests/input_object.rs b/juniper/src/macros/tests/input_object.rs index ab8f6647..61d8d950 100644 --- a/juniper/src/macros/tests/input_object.rs +++ b/juniper/src/macros/tests/input_object.rs @@ -103,7 +103,9 @@ graphql_object!(Root: () |&self| { } }); -fn run_type_info_query(doc: &str, f: F) where F: Fn(&HashMap, &Vec) -> () { +fn run_type_info_query(doc: &str, f: F) + where F: Fn(&HashMap, &Vec) -> () +{ let schema = RootNode::new(Root {}, EmptyMutation::<()>::new()); let (result, errs) = ::execute(doc, None, &schema, &Variables::new(), &()) @@ -114,13 +116,18 @@ fn run_type_info_query(doc: &str, f: F) where F: Fn(&HashMap, println!("Result: {:?}", result); let type_info = result - .as_object_value().expect("Result is not an object") - .get("__type").expect("__type field missing") - .as_object_value().expect("__type field not an object value"); + .as_object_value() + .expect("Result is not an object") + .get("__type") + .expect("__type field missing") + .as_object_value() + .expect("__type field not an object value"); let fields = type_info - .get("inputFields").expect("inputFields field missing") - .as_list_value().expect("inputFields not a list"); + .get("inputFields") + .expect("inputFields field missing") + .as_list_value() + .expect("inputFields not a list"); f(type_info, fields); } @@ -181,7 +188,9 @@ fn default_name_input_value() { let iv = InputValue::object(vec![ ("fieldOne", InputValue::string("number one")), ("fieldTwo", InputValue::string("number two")), - ].into_iter().collect()); + ] + .into_iter() + .collect()); let dv: Option = FromInputValue::from(&iv); diff --git a/juniper/src/macros/tests/interface.rs b/juniper/src/macros/tests/interface.rs index 5a4b3531..ce09718c 100644 --- a/juniper/src/macros/tests/interface.rs +++ b/juniper/src/macros/tests/interface.rs @@ -23,10 +23,14 @@ struct Concrete; struct CustomName; #[allow(dead_code)] -struct WithLifetime<'a> { data: PhantomData<&'a i32> } +struct WithLifetime<'a> { + data: PhantomData<&'a i32>, +} #[allow(dead_code)] -struct WithGenerics { data: T } +struct WithGenerics { + data: T, +} struct DescriptionFirst; struct FieldsFirst; @@ -146,23 +150,29 @@ fn run_type_info_query(type_name: &str, f: F) let schema = RootNode::new(Root {}, EmptyMutation::<()>::new()); let vars = vec![ ("typeName".to_owned(), InputValue::string(type_name)), - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let (result, errs) = ::execute(doc, None, &schema, &vars, &()) - .expect("Execution failed"); + let (result, errs) = ::execute(doc, None, &schema, &vars, &()).expect("Execution failed"); assert_eq!(errs, []); println!("Result: {:?}", result); let type_info = result - .as_object_value().expect("Result is not an object") - .get("__type").expect("__type field missing") - .as_object_value().expect("__type field not an object value"); + .as_object_value() + .expect("Result is not an object") + .get("__type") + .expect("__type field missing") + .as_object_value() + .expect("__type field not an object value"); let fields = type_info - .get("fields").expect("fields field missing") - .as_list_value().expect("fields field not a list value"); + .get("fields") + .expect("fields field missing") + .as_list_value() + .expect("fields field not a list value"); f(type_info, fields); } diff --git a/juniper/src/macros/tests/mod.rs b/juniper/src/macros/tests/mod.rs index b67cd409..a4d4273d 100644 --- a/juniper/src/macros/tests/mod.rs +++ b/juniper/src/macros/tests/mod.rs @@ -1,6 +1,7 @@ mod enums; mod scalar; -#[allow(dead_code)] mod input_object; +#[allow(dead_code)] +mod input_object; mod args; mod field; mod object; diff --git a/juniper/src/macros/tests/object.rs b/juniper/src/macros/tests/object.rs index 4f10a8d1..2064d50d 100644 --- a/juniper/src/macros/tests/object.rs +++ b/juniper/src/macros/tests/object.rs @@ -22,10 +22,14 @@ struct Interface; struct CustomName; #[allow(dead_code)] -struct WithLifetime<'a> { data: PhantomData<&'a i32> } +struct WithLifetime<'a> { + data: PhantomData<&'a i32>, +} #[allow(dead_code)] -struct WithGenerics { data: T } +struct WithGenerics { + data: T, +} struct DescriptionFirst; struct FieldsFirst; @@ -134,23 +138,29 @@ fn run_type_info_query(type_name: &str, f: F) let schema = RootNode::new(Root {}, EmptyMutation::<()>::new()); let vars = vec![ ("typeName".to_owned(), InputValue::string(type_name)), - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let (result, errs) = ::execute(doc, None, &schema, &vars, &()) - .expect("Execution failed"); + let (result, errs) = ::execute(doc, None, &schema, &vars, &()).expect("Execution failed"); assert_eq!(errs, []); println!("Result: {:?}", result); let type_info = result - .as_object_value().expect("Result is not an object") - .get("__type").expect("__type field missing") - .as_object_value().expect("__type field not an object value"); + .as_object_value() + .expect("Result is not an object") + .get("__type") + .expect("__type field missing") + .as_object_value() + .expect("__type field not an object value"); let fields = type_info - .get("fields").expect("fields field missing") - .as_list_value().expect("fields field not a list value"); + .get("fields") + .expect("fields field missing") + .as_list_value() + .expect("fields field not a list value"); f(type_info, fields); } diff --git a/juniper/src/macros/tests/scalar.rs b/juniper/src/macros/tests/scalar.rs index 344e2572..14625b14 100644 --- a/juniper/src/macros/tests/scalar.rs +++ b/juniper/src/macros/tests/scalar.rs @@ -70,7 +70,9 @@ graphql_object!(Root: () |&self| { field scalar_description() -> ScalarDescription { ScalarDescription(0) } }); -fn run_type_info_query(doc: &str, f: F) where F: Fn(&HashMap) -> () { +fn run_type_info_query(doc: &str, f: F) + where F: Fn(&HashMap) -> () +{ let schema = RootNode::new(Root {}, EmptyMutation::<()>::new()); let (result, errs) = ::execute(doc, None, &schema, &Variables::new(), &()) @@ -81,9 +83,12 @@ fn run_type_info_query(doc: &str, f: F) where F: Fn(&HashMap) println!("Result: {:?}", result); let type_info = result - .as_object_value().expect("Result is not an object") - .get("__type").expect("__type field missing") - .as_object_value().expect("__type field not an object value"); + .as_object_value() + .expect("Result is not an object") + .get("__type") + .expect("__type field missing") + .as_object_value() + .expect("__type field not an object value"); f(type_info); } diff --git a/juniper/src/macros/tests/union.rs b/juniper/src/macros/tests/union.rs index a03d4088..74a29f14 100644 --- a/juniper/src/macros/tests/union.rs +++ b/juniper/src/macros/tests/union.rs @@ -20,16 +20,30 @@ Syntax to validate: struct Concrete; -enum CustomName { Concrete(Concrete) } +enum CustomName { + Concrete(Concrete), +} -enum WithLifetime<'a> { Int(PhantomData<&'a i32>) } -enum WithGenerics { Generic(T) } +enum WithLifetime<'a> { + Int(PhantomData<&'a i32>), +} +enum WithGenerics { + Generic(T), +} -enum DescriptionFirst { Concrete(Concrete) } -enum ResolversFirst { Concrete(Concrete) } +enum DescriptionFirst { + Concrete(Concrete), +} +enum ResolversFirst { + Concrete(Concrete), +} -enum CommasWithTrailing { Concrete(Concrete) } -enum ResolversWithTrailingComma { Concrete(Concrete) } +enum CommasWithTrailing { + Concrete(Concrete), +} +enum ResolversWithTrailingComma { + Concrete(Concrete), +} struct Root; @@ -113,23 +127,29 @@ fn run_type_info_query(type_name: &str, f: F) let schema = RootNode::new(Root {}, EmptyMutation::<()>::new()); let vars = vec![ ("typeName".to_owned(), InputValue::string(type_name)), - ].into_iter().collect(); + ] + .into_iter() + .collect(); - let (result, errs) = ::execute(doc, None, &schema, &vars, &()) - .expect("Execution failed"); + let (result, errs) = ::execute(doc, None, &schema, &vars, &()).expect("Execution failed"); assert_eq!(errs, []); println!("Result: {:?}", result); let type_info = result - .as_object_value().expect("Result is not an object") - .get("__type").expect("__type field missing") - .as_object_value().expect("__type field not an object value"); + .as_object_value() + .expect("Result is not an object") + .get("__type") + .expect("__type field missing") + .as_object_value() + .expect("__type field not an object value"); let possible_types = type_info - .get("possibleTypes").expect("possibleTypes field missing") - .as_list_value().expect("possibleTypes field not a list value"); + .get("possibleTypes") + .expect("possibleTypes field missing") + .as_list_value() + .expect("possibleTypes field not a list value"); f(type_info, possible_types); } diff --git a/juniper/src/parser/document.rs b/juniper/src/parser/document.rs index 317ece6e..9a298e8f 100644 --- a/juniper/src/parser/document.rs +++ b/juniper/src/parser/document.rs @@ -1,9 +1,9 @@ -use ast::{Definition, Document, OperationType, - VariableDefinitions, VariableDefinition, InputValue, - Operation, Fragment, Selection, Directive, Field, Arguments, - FragmentSpread, InlineFragment, Type}; +use ast::{Definition, Document, OperationType, VariableDefinitions, VariableDefinition, + InputValue, Operation, Fragment, Selection, Directive, Field, Arguments, FragmentSpread, + InlineFragment, Type}; -use parser::{Lexer, Parser, Spanning, UnlocatedParseResult, OptionParseResult, ParseResult, ParseError, Token}; +use parser::{Lexer, Parser, Spanning, UnlocatedParseResult, OptionParseResult, ParseResult, + ParseError, Token}; use parser::value::parse_value_literal; #[doc(hidden)] @@ -27,10 +27,14 @@ 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(try!(parse_operation_definition(parser)))) + } + Token::Name("fragment") => { + Ok(Definition::Fragment(try!(parse_fragment_definition(parser)))) + } _ => Err(parser.next()?.map(ParseError::UnexpectedToken)), } } @@ -39,50 +43,48 @@ fn parse_operation_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Op if parser.peek().item == Token::CurlyOpen { let selection_set = try!(parse_selection_set(parser)); - Ok(Spanning::start_end( - &selection_set.start, - &selection_set.end, - Operation { - operation_type: OperationType::Query, - name: None, - variable_definitions: None, - directives: None, - selection_set: selection_set.item, - })) - } - else { + Ok(Spanning::start_end(&selection_set.start, + &selection_set.end, + Operation { + operation_type: OperationType::Query, + name: None, + variable_definitions: None, + directives: None, + selection_set: selection_set.item, + })) + } else { let start_pos = parser.peek().start.clone(); let operation_type = try!(parse_operation_type(parser)); let name = match parser.peek().item { Token::Name(_) => Some(try!(parser.expect_name())), - _ => None + _ => None, }; let variable_definitions = try!(parse_variable_definitions(parser)); let directives = try!(parse_directives(parser)); let selection_set = try!(parse_selection_set(parser)); - Ok(Spanning::start_end( - &start_pos, - &selection_set.end, - Operation { - operation_type: operation_type.item, - name: name, - variable_definitions: variable_definitions, - directives: directives.map(|s| s.item), - selection_set: selection_set.item, - })) + Ok(Spanning::start_end(&start_pos, + &selection_set.end, + Operation { + operation_type: operation_type.item, + name: name, + variable_definitions: variable_definitions, + directives: directives.map(|s| s.item), + selection_set: selection_set.item, + })) } } fn parse_fragment_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Fragment<'a>> { let Spanning { start: start_pos, .. } = try!(parser.expect(&Token::Name("fragment"))); let name = match parser.expect_name() { - Ok(n) => if n.item == "on" { + Ok(n) => { + if n.item == "on" { return Err(n.map(|_| ParseError::UnexpectedToken(Token::Name("on")))); - } - else { + } else { n - }, + } + } Err(e) => return Err(e), }; @@ -91,31 +93,27 @@ fn parse_fragment_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Fra let directives = try!(parse_directives(parser)); let selection_set = try!(parse_selection_set(parser)); - Ok(Spanning::start_end( - &start_pos, - &selection_set.end, - Fragment { - name: name, - type_condition: type_cond, - directives: directives.map(|s| s.item), - selection_set: selection_set.item, - })) + Ok(Spanning::start_end(&start_pos, + &selection_set.end, + Fragment { + name: name, + type_condition: type_cond, + directives: directives.map(|s| s.item), + selection_set: selection_set.item, + })) } -fn parse_optional_selection_set<'a>(parser: &mut Parser<'a>) -> OptionParseResult<'a, Vec>> { +fn parse_optional_selection_set<'a>(parser: &mut Parser<'a>) + -> OptionParseResult<'a, Vec>> { if parser.peek().item == Token::CurlyOpen { Ok(Some(try!(parse_selection_set(parser)))) - } - else { + } else { Ok(None) } } fn parse_selection_set<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Vec>> { - parser.unlocated_delimited_nonempty_list( - &Token::CurlyOpen, - parse_selection, - &Token::CurlyClose) + parser.unlocated_delimited_nonempty_list(&Token::CurlyOpen, parse_selection, &Token::CurlyClose) } fn parse_selection<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Selection<'a>> { @@ -135,56 +133,58 @@ fn parse_fragment<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Selec let directives = try!(parse_directives(parser)); let selection_set = try!(parse_selection_set(parser)); - Ok(Selection::InlineFragment( - Spanning::start_end( - &start_pos.clone(), - &selection_set.end, - InlineFragment { - type_condition: Some(name), - directives: directives.map(|s| s.item), - selection_set: selection_set.item, - }))) - }, + Ok(Selection::InlineFragment(Spanning::start_end(&start_pos.clone(), + &selection_set.end, + InlineFragment { + type_condition: Some(name), + directives: directives.map(|s| { + s.item + }), + selection_set: selection_set.item, + }))) + } Token::CurlyOpen => { let selection_set = try!(parse_selection_set(parser)); - Ok(Selection::InlineFragment( - Spanning::start_end( - &start_pos.clone(), - &selection_set.end, - InlineFragment { - type_condition: None, - directives: None, - selection_set: selection_set.item, - }))) - }, + Ok(Selection::InlineFragment(Spanning::start_end(&start_pos.clone(), + &selection_set.end, + InlineFragment { + type_condition: None, + directives: None, + selection_set: selection_set.item, + }))) + } Token::Name(_) => { let frag_name = try!(parser.expect_name()); let directives = try!(parse_directives(parser)); - Ok(Selection::FragmentSpread( - Spanning::start_end( - &start_pos.clone(), - &directives.as_ref().map_or(&frag_name.end, |s| &s.end).clone(), - FragmentSpread { - name: frag_name, - directives: directives.map(|s| s.item), - }))) - }, + Ok(Selection::FragmentSpread(Spanning::start_end(&start_pos.clone(), + &directives + .as_ref() + .map_or(&frag_name.end, + |s| &s.end) + .clone(), + FragmentSpread { + name: frag_name, + directives: directives.map(|s| { + s.item + }), + }))) + } Token::At => { let directives = try!(parse_directives(parser)); let selection_set = try!(parse_selection_set(parser)); - Ok(Selection::InlineFragment( - Spanning::start_end( - &start_pos.clone(), - &selection_set.end, - InlineFragment { - type_condition: None, - directives: directives.map(|s| s.item), - selection_set: selection_set.item, - }))) - }, + Ok(Selection::InlineFragment(Spanning::start_end(&start_pos.clone(), + &selection_set.end, + InlineFragment { + type_condition: None, + directives: directives.map(|s| { + s.item + }), + selection_set: selection_set.item, + }))) + } _ => Err(parser.next()?.map(ParseError::UnexpectedToken)), } } @@ -194,8 +194,7 @@ fn parse_field<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Field<'a>> { let name = if try!(parser.skip(&Token::Colon)).is_some() { try!(parser.expect_name()) - } - else { + } else { alias.take().unwrap() }; @@ -203,20 +202,21 @@ fn parse_field<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Field<'a>> { let directives = try!(parse_directives(parser)); let selection_set = try!(parse_optional_selection_set(parser)); - Ok(Spanning::start_end( - &alias.as_ref().unwrap_or(&name).start.clone(), - &selection_set.as_ref().map(|s| &s.end) - .or_else(|| directives.as_ref().map(|s| &s.end)) - .or_else(|| arguments.as_ref().map(|s| &s.end)) - .unwrap_or(&name.end) - .clone(), - Field { - alias: alias, - name: name, - arguments: arguments, - directives: directives.map(|s| s.item), - selection_set: selection_set.map(|s| s.item), - })) + Ok(Spanning::start_end(&alias.as_ref().unwrap_or(&name).start.clone(), + &selection_set + .as_ref() + .map(|s| &s.end) + .or_else(|| directives.as_ref().map(|s| &s.end)) + .or_else(|| arguments.as_ref().map(|s| &s.end)) + .unwrap_or(&name.end) + .clone(), + Field { + alias: alias, + name: name, + arguments: arguments, + directives: directives.map(|s| s.item), + selection_set: selection_set.map(|s| s.item), + })) } fn parse_arguments<'a>(parser: &mut Parser<'a>) -> OptionParseResult<'a, Arguments<'a>> { @@ -227,76 +227,79 @@ fn parse_arguments<'a>(parser: &mut Parser<'a>) -> OptionParseResult<'a, Argumen &Token::ParenOpen, parse_argument, &Token::ParenClose - )).map(|args| Arguments { items: args.into_iter().map(|s| s.item).collect() }))) + )) + .map(|args| { + Arguments { items: args.into_iter().map(|s| s.item).collect() } + }))) } } -fn parse_argument<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, (Spanning<&'a str>, Spanning)> { +fn parse_argument<'a>(parser: &mut Parser<'a>) + -> ParseResult<'a, (Spanning<&'a str>, Spanning)> { let name = try!(parser.expect_name()); try!(parser.expect(&Token::Colon)); let value = try!(parse_value_literal(parser, false)); - Ok(Spanning::start_end( - &name.start.clone(), - &value.end.clone(), - (name, value))) + Ok(Spanning::start_end(&name.start.clone(), &value.end.clone(), (name, value))) } fn parse_operation_type<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, OperationType> { match parser.peek().item { Token::Name("query") => Ok(parser.next()?.map(|_| OperationType::Query)), Token::Name("mutation") => Ok(parser.next()?.map(|_| OperationType::Mutation)), - _ => Err(parser.next()?.map(ParseError::UnexpectedToken)) + _ => Err(parser.next()?.map(ParseError::UnexpectedToken)), } } -fn parse_variable_definitions<'a>(parser: &mut Parser<'a>) -> OptionParseResult<'a, VariableDefinitions<'a>> { +fn parse_variable_definitions<'a>(parser: &mut Parser<'a>) + -> OptionParseResult<'a, VariableDefinitions<'a>> { if parser.peek().item != Token::ParenOpen { Ok(None) - } - else { + } 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() }))) + )) + .map(|defs| { + VariableDefinitions { + items: defs.into_iter().map(|s| s.item).collect(), + } + }))) } } -fn parse_variable_definition<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, (Spanning<&'a str>, VariableDefinition<'a>)> { +fn parse_variable_definition<'a> + (parser: &mut Parser<'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)); let default_value = if try!(parser.skip(&Token::Equals)).is_some() { - Some(try!(parse_value_literal(parser, true))) - } - else { - None - }; + Some(try!(parse_value_literal(parser, true))) + } else { + None + }; - Ok(Spanning::start_end( - &start_pos, - &default_value.as_ref().map_or(&var_type.end, |s| &s.end).clone(), - ( - Spanning::start_end( - &start_pos, - &var_name.end, - var_name.item, - ), - VariableDefinition { - var_type: var_type, - default_value: default_value, - } - ))) + Ok(Spanning::start_end(&start_pos, + &default_value + .as_ref() + .map_or(&var_type.end, |s| &s.end) + .clone(), + (Spanning::start_end(&start_pos, &var_name.end, var_name.item), + VariableDefinition { + var_type: var_type, + default_value: default_value, + }))) } -fn parse_directives<'a>(parser: &mut Parser<'a>) -> OptionParseResult<'a, Vec>>> { +fn parse_directives<'a>(parser: &mut Parser<'a>) + -> OptionParseResult<'a, Vec>>> { if parser.peek().item != Token::At { Ok(None) - } - else { + } else { let mut items = Vec::new(); while parser.peek().item == Token::At { items.push(try!(parse_directive(parser))); @@ -311,36 +314,35 @@ fn parse_directive<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Directive<'a> let name = try!(parser.expect_name()); let arguments = try!(parse_arguments(parser)); - Ok(Spanning::start_end( - &start_pos, - &arguments.as_ref().map_or(&name.end, |s| &s.end).clone(), - Directive { - name: name, - arguments: arguments, - })) + Ok(Spanning::start_end(&start_pos, + &arguments.as_ref().map_or(&name.end, |s| &s.end).clone(), + Directive { + name: name, + arguments: arguments, + })) } 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)) { + let parsed_type = if let Some(Spanning { start: start_pos, .. }) = + try!(parser.skip(&Token::BracketOpen)) { let inner_type = try!(parse_type(parser)); let Spanning { end: end_pos, .. } = try!(parser.expect(&Token::BracketClose)); - Spanning::start_end( - &start_pos, - &end_pos, - Type::List(Box::new(inner_type.item))) - } - else { + Spanning::start_end(&start_pos, &end_pos, Type::List(Box::new(inner_type.item))) + } else { try!(parser.expect_name()).map(Type::Named) }; Ok(match *parser.peek() { - Spanning { item: Token::ExclamationMark, .. } => - try!(wrap_non_null(parser, parsed_type)), - _ => parsed_type - }) + Spanning { item: Token::ExclamationMark, .. } => { + try!(wrap_non_null(parser, parsed_type)) + } + _ => parsed_type, + }) } -fn wrap_non_null<'a>(parser: &mut Parser<'a>, inner: Spanning>) -> ParseResult<'a, Type<'a>> { +fn wrap_non_null<'a>(parser: &mut Parser<'a>, + inner: Spanning>) + -> ParseResult<'a, Type<'a>> { let Spanning { end: end_pos, .. } = try!(parser.expect(&Token::ExclamationMark)); let wrapped = match inner.item { diff --git a/juniper/src/parser/lexer.rs b/juniper/src/parser/lexer.rs index a867e6c6..638cfb9b 100644 --- a/juniper/src/parser/lexer.rs +++ b/juniper/src/parser/lexer.rs @@ -45,7 +45,7 @@ pub enum Token<'a> { pub enum LexerError { /// An unknown character was found /// - /// Unknown characters are characters that do not occur anywhere in the + /// Unknown characters are characters that do not occur anywhere in the /// GraphQL language, such as `?` or `%`. UnknownCharacter(char), @@ -114,8 +114,7 @@ impl<'a> Lexer<'a> { if let Some((_, ch)) = next { if ch == '\n' { self.position.advance_line(); - } - else { + } else { self.position.advance_col(); } } @@ -138,24 +137,20 @@ impl<'a> Lexer<'a> { while let Some((_, ch)) = self.peek_char() { if ch == '\t' || ch == ' ' || ch == '\n' || ch == '\r' || ch == ',' { self.next_char(); - } - else if ch == '#' { + } else if ch == '#' { self.next_char(); while let Some((_, ch)) = self.peek_char() { if is_source_char(ch) && (ch == '\n' || ch == '\r') { self.next_char(); break; - } - else if is_source_char(ch) { + } else if is_source_char(ch) { self.next_char(); - } - else { + } else { break; } } - } - else { + } else { break; } } @@ -176,7 +171,8 @@ 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( + let (start_idx, start_ch) = + try!(self.next_char().ok_or( Spanning::zero_width(&self.position, LexerError::UnexpectedEndOfFile))); assert!(is_name_start(start_ch)); @@ -186,21 +182,20 @@ impl<'a> Lexer<'a> { if is_name_cont(ch) { self.next_char(); end_idx = idx; - } - else { + } else { break; } } - Ok(Spanning::start_end( - &start_pos, - &self.position, - Token::Name(&self.source[start_idx..end_idx + 1]))) + Ok(Spanning::start_end(&start_pos, + &self.position, + Token::Name(&self.source[start_idx..end_idx + 1]))) } fn scan_string(&mut self) -> LexerResult<'a> { let start_pos = self.position.clone(); - let (_, start_ch) = try!(self.next_char().ok_or( + let (_, start_ch) = + try!(self.next_char().ok_or( Spanning::zero_width(&self.position, LexerError::UnexpectedEndOfFile))); assert!(start_ch == '"'); @@ -209,64 +204,72 @@ impl<'a> Lexer<'a> { while let Some((_, ch)) = self.peek_char() { if ch == '"' { self.next_char(); - return Ok(Spanning::start_end( - &start_pos, - &self.position, - Token::String(acc))); - } - else if ch == '\\' { + return Ok(Spanning::start_end(&start_pos, &self.position, Token::String(acc))); + } else if ch == '\\' { self.next_char(); match self.peek_char() { - Some((_, '"')) => { self.next_char(); acc.push('"'); }, - Some((_, '\\')) => { self.next_char(); acc.push('\\'); }, - Some((_, '/')) => { self.next_char(); acc.push('/'); }, - Some((_, 'b')) => { self.next_char(); acc.push('\u{0008}'); }, - Some((_, 'f')) => { self.next_char(); acc.push('\u{000c}'); }, - Some((_, 'n')) => { self.next_char(); acc.push('\n'); }, - Some((_, 'r')) => { self.next_char(); acc.push('\r'); }, - Some((_, 't')) => { self.next_char(); acc.push('\t'); }, + Some((_, '"')) => { + self.next_char(); + acc.push('"'); + } + Some((_, '\\')) => { + self.next_char(); + acc.push('\\'); + } + Some((_, '/')) => { + self.next_char(); + acc.push('/'); + } + Some((_, 'b')) => { + self.next_char(); + acc.push('\u{0008}'); + } + Some((_, 'f')) => { + self.next_char(); + acc.push('\u{000c}'); + } + Some((_, 'n')) => { + self.next_char(); + acc.push('\n'); + } + Some((_, 'r')) => { + self.next_char(); + acc.push('\r'); + } + Some((_, 't')) => { + self.next_char(); + acc.push('\t'); + } Some((_, 'u')) => { let start_pos = self.position.clone(); self.next_char(); acc.push(try!(self.scan_escaped_unicode(&start_pos))); - }, + } Some((_, ch)) => { let mut s = String::from("\\"); s.push(ch); - return Err(Spanning::zero_width( - &self.position, - LexerError::UnknownEscapeSequence(s))); - }, + return Err(Spanning::zero_width(&self.position, + LexerError::UnknownEscapeSequence(s))); + } None => { - return Err(Spanning::zero_width( - &self.position, - LexerError::UnterminatedString)); - }, - } - if let Some((_, ch)) = self.peek_char() { - if ch == 'n' { - + return Err(Spanning::zero_width(&self.position, + LexerError::UnterminatedString)); } } - else { - return Err(Spanning::zero_width( - &self.position, - LexerError::UnterminatedString)); + if let Some((_, ch)) = self.peek_char() { + if ch == 'n' {} + } else { + return Err(Spanning::zero_width(&self.position, + LexerError::UnterminatedString)); } - } - else if ch == '\n' || ch == '\r' { - return Err(Spanning::zero_width( - &self.position, - LexerError::UnterminatedString)); - } - else if !is_source_char(ch) { - return Err(Spanning::zero_width( - &self.position, - LexerError::UnknownCharacterInString(ch))); - } - else { + } else if ch == '\n' || ch == '\r' { + return Err(Spanning::zero_width(&self.position, LexerError::UnterminatedString)); + } else if !is_source_char(ch) { + return Err(Spanning::zero_width(&self.position, + LexerError::UnknownCharacterInString(ch))); + } else { self.next_char(); acc.push(ch); } @@ -275,14 +278,18 @@ impl<'a> Lexer<'a> { Err(Spanning::zero_width(&self.position, LexerError::UnterminatedString)) } - fn scan_escaped_unicode(&mut self, start_pos: &SourcePosition) -> Result> { - let (start_idx, _) = try!(self.peek_char().ok_or( + fn scan_escaped_unicode(&mut self, + start_pos: &SourcePosition) + -> Result> { + let (start_idx, _) = + try!(self.peek_char().ok_or( Spanning::zero_width(&self.position, 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( + let (idx, ch) = + try!(self.next_char().ok_or( Spanning::zero_width(&self.position, LexerError::UnterminatedString))); if !ch.is_alphanumeric() { @@ -293,12 +300,12 @@ impl<'a> Lexer<'a> { len += 1; } - let escape = &self.source[start_idx..end_idx+1]; + let escape = &self.source[start_idx..end_idx + 1]; if len != 4 { - return Err(Spanning::zero_width( - start_pos, - LexerError::UnknownEscapeSequence("\\u".to_owned() + escape))); + return Err(Spanning::zero_width(start_pos, + LexerError::UnknownEscapeSequence("\\u".to_owned() + + escape))); } let code_point = try!(u32::from_str_radix(escape, 16).map_err(|_| @@ -306,10 +313,10 @@ impl<'a> Lexer<'a> { start_pos, LexerError::UnknownEscapeSequence("\\u".to_owned() + escape)))); - char::from_u32(code_point).ok_or_else(|| - Spanning::zero_width( - start_pos, - LexerError::UnknownEscapeSequence("\\u".to_owned() + escape))) + char::from_u32(code_point).ok_or_else(|| { + Spanning::zero_width(start_pos, + LexerError::UnknownEscapeSequence("\\u".to_owned() + escape)) + }) } fn scan_number(&mut self) -> LexerResult<'a> { @@ -334,8 +341,7 @@ impl<'a> Lexer<'a> { if ch == '-' { self.next_char(); is_negative = true; - } - else if ch == '+' { + } else if ch == '+' { self.next_char(); } } @@ -343,37 +349,35 @@ impl<'a> Lexer<'a> { } } - let mantissa = frac_part.map(|f| f as f64).map(|frac| - if frac > 0f64 { - frac / 10f64.powf(frac.log10().floor() + 1f64) - } - else { - 0f64 - }).map(|m| if int_part < 0 { -m } else { m }); + let mantissa = frac_part + .map(|f| f as f64) + .map(|frac| if frac > 0f64 { + frac / 10f64.powf(frac.log10().floor() + 1f64) + } else { + 0f64 + }) + .map(|m| if int_part < 0 { -m } else { m }); let exp = exp_part.map(|e| e as f64).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), - })) + 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), + })) } fn scan_integer_part(&mut self) -> Result> { let is_negative = { - let (_, init_ch) = try!(self.peek_char().ok_or( + let (_, init_ch) = + try!(self.peek_char().ok_or( Spanning::zero_width(&self.position, LexerError::UnexpectedEndOfFile))); if init_ch == '-' { self.next_char(); true - } - else { + } else { false } }; @@ -385,18 +389,20 @@ impl<'a> Lexer<'a> { self.next_char(); match self.peek_char() { - Some((_, '0')) => Err(Spanning::zero_width(&self.position, LexerError::UnexpectedCharacter(ch))), + Some((_, '0')) => { + Err(Spanning::zero_width(&self.position, LexerError::UnexpectedCharacter(ch))) + } _ => Ok(0), } - } - else { + } else { Ok(try!(self.scan_digits()) * if is_negative { -1 } else { 1 }) } } fn scan_digits(&mut self) -> Result> { let start_pos = self.position.clone(); - let (start_idx, ch) = try!(self.peek_char().ok_or( + let (start_idx, ch) = + try!(self.peek_char().ok_or( Spanning::zero_width(&self.position, LexerError::UnexpectedEndOfFile))); let mut end_idx = start_idx; @@ -407,14 +413,13 @@ impl<'a> Lexer<'a> { while let Some((idx, ch)) = self.peek_char() { if !ch.is_digit(10) { break; - } - else { + } else { self.next_char(); end_idx = idx; } } - i32::from_str_radix(&self.source[start_idx..end_idx+1], 10) + i32::from_str_radix(&self.source[start_idx..end_idx + 1], 10) .map_err(|_| Spanning::zero_width(&start_pos, LexerError::InvalidNumber)) } } @@ -432,37 +437,34 @@ impl<'a> Iterator for Lexer<'a> { let ch = self.iterator.peek().map(|&(_, ch)| ch); Some(match ch { - Some('!') => Ok(self.emit_single_char(Token::ExclamationMark)), - Some('$') => Ok(self.emit_single_char(Token::Dollar)), - Some('(') => Ok(self.emit_single_char(Token::ParenOpen)), - Some(')') => Ok(self.emit_single_char(Token::ParenClose)), - Some('[') => Ok(self.emit_single_char(Token::BracketOpen)), - Some(']') => Ok(self.emit_single_char(Token::BracketClose)), - Some('{') => Ok(self.emit_single_char(Token::CurlyOpen)), - Some('}') => Ok(self.emit_single_char(Token::CurlyClose)), - Some(':') => Ok(self.emit_single_char(Token::Colon)), - Some('=') => Ok(self.emit_single_char(Token::Equals)), - Some('@') => Ok(self.emit_single_char(Token::At)), - Some('|') => Ok(self.emit_single_char(Token::Pipe)), - Some('.') => self.scan_ellipsis(), - Some('"') => self.scan_string(), - Some(ch) => { - if is_number_start(ch) { - self.scan_number() - } - else if is_name_start(ch) { - self.scan_name() - } - else { - Err(Spanning::zero_width(&self.position, LexerError::UnknownCharacter(ch))) - } - }, - None => { - self.has_reached_eof = true; - Ok(Spanning::zero_width( - &self.position, Token::EndOfFile)) - }, - }) + Some('!') => Ok(self.emit_single_char(Token::ExclamationMark)), + Some('$') => Ok(self.emit_single_char(Token::Dollar)), + Some('(') => Ok(self.emit_single_char(Token::ParenOpen)), + Some(')') => Ok(self.emit_single_char(Token::ParenClose)), + Some('[') => Ok(self.emit_single_char(Token::BracketOpen)), + Some(']') => Ok(self.emit_single_char(Token::BracketClose)), + Some('{') => Ok(self.emit_single_char(Token::CurlyOpen)), + Some('}') => Ok(self.emit_single_char(Token::CurlyClose)), + Some(':') => Ok(self.emit_single_char(Token::Colon)), + Some('=') => Ok(self.emit_single_char(Token::Equals)), + Some('@') => Ok(self.emit_single_char(Token::At)), + Some('|') => Ok(self.emit_single_char(Token::Pipe)), + Some('.') => self.scan_ellipsis(), + Some('"') => self.scan_string(), + Some(ch) => { + if is_number_start(ch) { + self.scan_number() + } else if is_name_start(ch) { + self.scan_name() + } else { + Err(Spanning::zero_width(&self.position, LexerError::UnknownCharacter(ch))) + } + } + None => { + self.has_reached_eof = true; + Ok(Spanning::zero_width(&self.position, Token::EndOfFile)) + } + }) } } @@ -472,7 +474,9 @@ impl<'a> fmt::Display for Token<'a> { Token::Name(name) => write!(f, "{}", name), Token::Int(i) => write!(f, "{}", i), Token::Float(v) => write!(f, "{}", v), - Token::String(ref s) => write!(f, "\"{}\"", s.replace('\\', "\\\\").replace('"', "\\\"")), + Token::String(ref s) => { + write!(f, "\"{}\"", s.replace('\\', "\\\\").replace('"', "\\\"")) + } Token::ExclamationMark => write!(f, "!"), Token::Dollar => write!(f, "$"), Token::ParenOpen => write!(f, "("), @@ -512,8 +516,12 @@ impl fmt::Display for LexerError { match *self { LexerError::UnknownCharacter(c) => write!(f, "Unknown character \"{}\"", c), LexerError::UnterminatedString => write!(f, "Unterminated string literal"), - LexerError::UnknownCharacterInString(c) => write!(f, "Unknown character \"{}\" in string literal", c), - LexerError::UnknownEscapeSequence(ref s) => write!(f, "Unknown escape sequence \"{}\" in string", s), + LexerError::UnknownCharacterInString(c) => { + write!(f, "Unknown character \"{}\" in string literal", c) + } + LexerError::UnknownEscapeSequence(ref s) => { + write!(f, "Unknown escape sequence \"{}\" in string", s) + } LexerError::UnexpectedCharacter(c) => write!(f, "Unexpected character \"{}\"", c), LexerError::UnexpectedEndOfFile => write!(f, "Unexpected end of input"), LexerError::InvalidNumber => write!(f, "Invalid number literal"), diff --git a/juniper/src/parser/parser.rs b/juniper/src/parser/parser.rs index 65512d4f..9d241d10 100644 --- a/juniper/src/parser/parser.rs +++ b/juniper/src/parser/parser.rs @@ -43,9 +43,7 @@ impl<'a> Parser<'a> { } } - Ok(Parser { - tokens: tokens, - }) + Ok(Parser { tokens: tokens }) } #[doc(hidden)] @@ -56,10 +54,9 @@ impl<'a> Parser<'a> { #[doc(hidden)] pub fn next(&mut self) -> ParseResult<'a, Token<'a>> { if self.tokens.len() == 1 { - Err(Spanning::start_end( - &self.peek().start.clone(), - &self.peek().end.clone(), - ParseError::UnexpectedEndOfFile)) + Err(Spanning::start_end(&self.peek().start.clone(), + &self.peek().end.clone(), + ParseError::UnexpectedEndOfFile)) } else { Ok(self.tokens.remove(0)) } @@ -69,41 +66,39 @@ impl<'a> Parser<'a> { pub fn expect(&mut self, expected: &Token) -> ParseResult<'a, Token<'a>> { if &self.peek().item != expected { Err(self.next()?.map(ParseError::UnexpectedToken)) - } - else { + } else { self.next() } } #[doc(hidden)] - pub fn skip(&mut self, expected: &Token) -> Result>>, Spanning>> { + pub fn skip(&mut self, + expected: &Token) + -> Result>>, Spanning>> { if &self.peek().item == expected { Ok(Some(self.next()?)) - } - else if self.peek().item == Token::EndOfFile { - Err(Spanning::zero_width( - &self.peek().start, - ParseError::UnexpectedEndOfFile)) - } - else { + } else if self.peek().item == Token::EndOfFile { + Err(Spanning::zero_width(&self.peek().start, ParseError::UnexpectedEndOfFile)) + } else { Ok(None) } } #[doc(hidden)] - pub fn delimited_list(&mut self, opening: &Token, parser: F, closing: &Token) - -> ParseResult<'a, Vec>> - where T: fmt::Debug, F: Fn(&mut Parser<'a>) -> ParseResult<'a, T> + pub fn delimited_list(&mut self, + opening: &Token, + parser: F, + closing: &Token) + -> ParseResult<'a, Vec>> + where T: fmt::Debug, + F: Fn(&mut Parser<'a>) -> ParseResult<'a, T> { let Spanning { start: start_pos, .. } = try!(self.expect(opening)); let mut items = Vec::new(); loop { if let Some(Spanning { end: end_pos, .. }) = try!(self.skip(closing)) { - return Ok(Spanning::start_end( - &start_pos, - &end_pos, - items)); + return Ok(Spanning::start_end(&start_pos, &end_pos, items)); } items.push(try!(parser(self))); @@ -111,9 +106,13 @@ impl<'a> Parser<'a> { } #[doc(hidden)] - pub fn delimited_nonempty_list(&mut self, opening: &Token, parser: F, closing: &Token) - -> ParseResult<'a, Vec>> - where T: fmt::Debug, F: Fn(&mut Parser<'a>) -> ParseResult<'a, T> + pub fn delimited_nonempty_list(&mut self, + opening: &Token, + parser: F, + closing: &Token) + -> ParseResult<'a, Vec>> + where T: fmt::Debug, + F: Fn(&mut Parser<'a>) -> ParseResult<'a, T> { let Spanning { start: start_pos, .. } = try!(self.expect(opening)); let mut items = Vec::new(); @@ -122,18 +121,19 @@ impl<'a> Parser<'a> { items.push(try!(parser(self))); if let Some(Spanning { end: end_pos, .. }) = try!(self.skip(closing)) { - return Ok(Spanning::start_end( - &start_pos, - &end_pos, - items)); + return Ok(Spanning::start_end(&start_pos, &end_pos, items)); } } } #[doc(hidden)] - pub fn unlocated_delimited_nonempty_list(&mut self, opening: &Token, parser: F, closing: &Token) - -> ParseResult<'a, Vec> - where T: fmt::Debug, F: Fn(&mut Parser<'a>) -> UnlocatedParseResult<'a, T> + pub fn unlocated_delimited_nonempty_list(&mut self, + opening: &Token, + parser: F, + closing: &Token) + -> ParseResult<'a, Vec> + where T: fmt::Debug, + F: Fn(&mut Parser<'a>) -> UnlocatedParseResult<'a, T> { let Spanning { start: start_pos, .. } = try!(self.expect(opening)); let mut items = Vec::new(); @@ -142,10 +142,7 @@ impl<'a> Parser<'a> { items.push(try!(parser(self))); if let Some(Spanning { end: end_pos, .. }) = try!(self.skip(closing)) { - return Ok(Spanning::start_end( - &start_pos, - &end_pos, - items)); + return Ok(Spanning::start_end(&start_pos, &end_pos, items)); } } } @@ -153,19 +150,19 @@ impl<'a> Parser<'a> { #[doc(hidden)] pub fn expect_name(&mut self) -> ParseResult<'a, &'a str> { match *self.peek() { - Spanning { item: Token::Name(_), .. } => - Ok(self.next()?.map(|token| - if let Token::Name(name) = token { - name - } - else { - panic!("Internal parse error in `expect_name`"); - })), - Spanning { item: Token::EndOfFile, .. } => - Err(Spanning::start_end( - &self.peek().start.clone(), - &self.peek().end.clone(), - ParseError::UnexpectedEndOfFile)), + Spanning { item: Token::Name(_), .. } => { + Ok(self.next()? + .map(|token| if let Token::Name(name) = token { + name + } else { + panic!("Internal parse error in `expect_name`"); + })) + } + Spanning { item: Token::EndOfFile, .. } => { + Err(Spanning::start_end(&self.peek().start.clone(), + &self.peek().end.clone(), + ParseError::UnexpectedEndOfFile)) + } _ => Err(self.next()?.map(ParseError::UnexpectedToken)), } } diff --git a/juniper/src/parser/tests/document.rs b/juniper/src/parser/tests/document.rs index 566fa79f..22dd9282 100644 --- a/juniper/src/parser/tests/document.rs +++ b/juniper/src/parser/tests/document.rs @@ -3,8 +3,7 @@ use parser::{Spanning, SourcePosition, ParseError, Token}; use parser::document::parse_document_source; fn parse_document(s: &str) -> Document { - parse_document_source(s) - .expect(&format!("Parse error on input {:#?}", s)) + parse_document_source(s).expect(&format!("Parse error on input {:#?}", s)) } fn parse_document_error<'a>(s: &'a str) -> Spanning> { diff --git a/juniper/src/parser/tests/lexer.rs b/juniper/src/parser/tests/lexer.rs index 47f86dac..8353624f 100644 --- a/juniper/src/parser/tests/lexer.rs +++ b/juniper/src/parser/tests/lexer.rs @@ -12,7 +12,7 @@ fn tokenize_to_vec<'a>(s: &'a str) -> Vec>> { if at_eof { break; } - }, + } Some(Err(e)) => panic!("Error in input stream: {:#?} for {:#?}", e, s), None => panic!("EOF before EndOfFile token in {:#?}", s), } @@ -39,10 +39,10 @@ fn tokenize_error(s: &str) -> Spanning { if t.item == Token::EndOfFile { panic!("Tokenizer did not return error for {:#?}", s); } - }, + } Some(Err(e)) => { return e; - }, + } None => panic!("Tokenizer did not return error for {:#?}", s), } } @@ -274,7 +274,10 @@ fn string_errors() { #[test] fn numbers() { - fn assert_float_token_eq(source: &str, start: SourcePosition, end: SourcePosition, expected: f64) { + fn assert_float_token_eq(source: &str, + start: SourcePosition, + end: SourcePosition, + expected: f64) { let parsed = tokenize_single(source); assert_eq!(parsed.start, start); assert_eq!(parsed.end, end); @@ -297,17 +300,15 @@ fn numbers() { &SourcePosition::new(1, 0, 1), Token::Int(4))); - assert_float_token_eq( - "4.123", - SourcePosition::new(0, 0, 0), - SourcePosition::new(5, 0, 5), - 4.123); + assert_float_token_eq("4.123", + SourcePosition::new(0, 0, 0), + SourcePosition::new(5, 0, 5), + 4.123); - assert_float_token_eq( - "4.0", - SourcePosition::new(0, 0, 0), - SourcePosition::new(3, 0, 3), - 4.0); + assert_float_token_eq("4.0", + SourcePosition::new(0, 0, 0), + SourcePosition::new(3, 0, 3), + 4.0); assert_eq!( tokenize_single("-4"), @@ -330,71 +331,60 @@ fn numbers() { &SourcePosition::new(1, 0, 1), Token::Int(0))); - assert_float_token_eq( - "-4.123", - SourcePosition::new(0, 0, 0), - SourcePosition::new(6, 0, 6), - -4.123); + assert_float_token_eq("-4.123", + SourcePosition::new(0, 0, 0), + SourcePosition::new(6, 0, 6), + -4.123); - assert_float_token_eq( - "0.123", - SourcePosition::new(0, 0, 0), - SourcePosition::new(5, 0, 5), - 0.123); + assert_float_token_eq("0.123", + SourcePosition::new(0, 0, 0), + SourcePosition::new(5, 0, 5), + 0.123); - assert_float_token_eq( - "123e4", - SourcePosition::new(0, 0, 0), - SourcePosition::new(5, 0, 5), - 123e4); + assert_float_token_eq("123e4", + SourcePosition::new(0, 0, 0), + SourcePosition::new(5, 0, 5), + 123e4); - assert_float_token_eq( - "123E4", - SourcePosition::new(0, 0, 0), - SourcePosition::new(5, 0, 5), - 123e4); + assert_float_token_eq("123E4", + SourcePosition::new(0, 0, 0), + SourcePosition::new(5, 0, 5), + 123e4); - assert_float_token_eq( - "123e-4", - SourcePosition::new(0, 0, 0), - SourcePosition::new(6, 0, 6), - 123e-4); + assert_float_token_eq("123e-4", + SourcePosition::new(0, 0, 0), + SourcePosition::new(6, 0, 6), + 123e-4); - assert_float_token_eq( - "123e+4", - SourcePosition::new(0, 0, 0), - SourcePosition::new(6, 0, 6), - 123e4); + assert_float_token_eq("123e+4", + SourcePosition::new(0, 0, 0), + SourcePosition::new(6, 0, 6), + 123e4); - assert_float_token_eq( - "-1.123e4", - SourcePosition::new(0, 0, 0), - SourcePosition::new(8, 0, 8), - -1.123e4); + assert_float_token_eq("-1.123e4", + SourcePosition::new(0, 0, 0), + SourcePosition::new(8, 0, 8), + -1.123e4); - assert_float_token_eq( - "-1.123E4", - SourcePosition::new(0, 0, 0), - SourcePosition::new(8, 0, 8), - -1.123e4); + assert_float_token_eq("-1.123E4", + SourcePosition::new(0, 0, 0), + SourcePosition::new(8, 0, 8), + -1.123e4); - assert_float_token_eq( - "-1.123e-4", - SourcePosition::new(0, 0, 0), - SourcePosition::new(9, 0, 9), - -1.123e-4); + assert_float_token_eq("-1.123e-4", + SourcePosition::new(0, 0, 0), + SourcePosition::new(9, 0, 9), + -1.123e-4); - assert_float_token_eq( - "-1.123e+4", - SourcePosition::new(0, 0, 0), - SourcePosition::new(9, 0, 9), - -1.123e4); + assert_float_token_eq("-1.123e+4", + SourcePosition::new(0, 0, 0), + SourcePosition::new(9, 0, 9), + -1.123e4); - assert_float_token_eq( - "-1.123e45", - SourcePosition::new(0, 0, 0), - SourcePosition::new(9, 0, 9), - -1.123e45); + assert_float_token_eq("-1.123e45", + SourcePosition::new(0, 0, 0), + SourcePosition::new(9, 0, 9), + -1.123e45); } #[test] diff --git a/juniper/src/parser/tests/value.rs b/juniper/src/parser/tests/value.rs index 820b6a39..4ed0b2d7 100644 --- a/juniper/src/parser/tests/value.rs +++ b/juniper/src/parser/tests/value.rs @@ -6,11 +6,9 @@ use parser::value::parse_value_literal; fn parse_value(s: &str) -> Spanning { let mut lexer = Lexer::new(s); - let mut parser = Parser::new(&mut lexer) - .expect(&format!("Lexer error on input {:#?}", s)); + let mut parser = Parser::new(&mut lexer).expect(&format!("Lexer error on input {:#?}", s)); - parse_value_literal(&mut parser, false) - .expect(&format!("Parse error on input {:#?}", s)) + parse_value_literal(&mut parser, false).expect(&format!("Parse error on input {:#?}", s)) } #[test] diff --git a/juniper/src/parser/utils.rs b/juniper/src/parser/utils.rs index ff5a1466..49971889 100644 --- a/juniper/src/parser/utils.rs +++ b/juniper/src/parser/utils.rs @@ -61,14 +61,14 @@ impl Spanning { #[doc(hidden)] pub fn spanning(v: Vec>) -> Option>>> { - if let (Some(start), Some(end)) = (v.first().map(|s| s.start.clone()), v.last().map(|s| s.end.clone())) { + if let (Some(start), Some(end)) = + (v.first().map(|s| s.start.clone()), v.last().map(|s| s.end.clone())) { Some(Spanning { - item: v, - start: start, - end: end, - }) - } - else { + item: v, + start: start, + end: end, + }) + } else { None } } @@ -92,7 +92,9 @@ impl Spanning { } } -impl Clone for Spanning where T: Clone + fmt::Debug { +impl Clone for Spanning + where T: Clone + fmt::Debug +{ fn clone(&self) -> Self { Spanning { start: self.start.clone(), @@ -102,7 +104,9 @@ impl Clone for Spanning where T: Clone + fmt::Debug { } } -impl PartialEq for Spanning where T: PartialEq + fmt::Debug { +impl PartialEq for Spanning + where T: PartialEq + fmt::Debug +{ fn eq(&self, other: &Self) -> bool { self.start == other.start && self.end == other.end && self.item == other.item } @@ -110,7 +114,9 @@ impl PartialEq for Spanning where T: PartialEq + fmt::Debug { impl Eq for Spanning where T: Eq + fmt::Debug {} -impl Hash for Spanning where T: Hash + fmt::Debug { +impl Hash for Spanning + where T: Hash + fmt::Debug +{ fn hash(&self, state: &mut H) { self.start.hash(state); self.end.hash(state); @@ -155,7 +161,7 @@ impl SourcePosition { /// The index of the character in the input source /// /// Zero-based index. Take a substring of the original source starting at - /// this index to access the item pointed to by this `SourcePosition`. + /// this index to access the item pointed to by this `SourcePosition`. pub fn index(&self) -> usize { self.index } diff --git a/juniper/src/parser/value.rs b/juniper/src/parser/value.rs index 9b3c04a9..b8fa6bb5 100644 --- a/juniper/src/parser/value.rs +++ b/juniper/src/parser/value.rs @@ -2,31 +2,38 @@ use ast::InputValue; use parser::{Parser, ParseResult, ParseError, Token, Spanning}; -pub fn parse_value_literal<'a>(parser: &mut Parser<'a>, is_const: bool) -> ParseResult<'a, InputValue> { +pub fn parse_value_literal<'a>(parser: &mut Parser<'a>, + is_const: bool) + -> ParseResult<'a, InputValue> { match *parser.peek() { Spanning { item: Token::BracketOpen, .. } => parse_list_literal(parser, is_const), Spanning { item: Token::CurlyOpen, .. } => parse_object_literal(parser, is_const), Spanning { item: Token::Dollar, .. } if !is_const => parse_variable_literal(parser), - Spanning { item: Token::Int(i), .. } => - Ok(parser.next()?.map(|_| InputValue::int(i))), - Spanning { item: Token::Float(f), .. } => - Ok(parser.next()?.map(|_| InputValue::float(f))), - Spanning { item: Token::String(_), .. } => - Ok(parser.next()?.map(|t| - if let Token::String(s) = t { - InputValue::string(s) - } - else { - panic!("Internal parser error"); - })), - Spanning { item: Token::Name("true"), .. } => - Ok(parser.next()?.map(|_| InputValue::boolean(true))), - Spanning { item: Token::Name("false"), .. } => - Ok(parser.next()?.map(|_| InputValue::boolean(false))), - Spanning { item: Token::Name("null"), .. } => - Ok(parser.next()?.map(|_| InputValue::null())), - Spanning { item: Token::Name(name), .. } => - Ok(parser.next()?.map(|_| InputValue::enum_value(name.to_owned()))), + Spanning { item: Token::Int(i), .. } => Ok(parser.next()?.map(|_| InputValue::int(i))), + Spanning { item: Token::Float(f), .. } => Ok(parser.next()?.map(|_| InputValue::float(f))), + Spanning { item: Token::String(_), .. } => { + Ok(parser + .next()? + .map(|t| if let Token::String(s) = t { + InputValue::string(s) + } else { + panic!("Internal parser error"); + })) + } + Spanning { item: Token::Name("true"), .. } => { + Ok(parser.next()?.map(|_| InputValue::boolean(true))) + } + Spanning { item: Token::Name("false"), .. } => { + Ok(parser.next()?.map(|_| InputValue::boolean(false))) + } + Spanning { item: Token::Name("null"), .. } => { + Ok(parser.next()?.map(|_| InputValue::null())) + } + Spanning { item: Token::Name(name), .. } => { + Ok(parser + .next()? + .map(|_| InputValue::enum_value(name.to_owned()))) + } _ => Err(parser.next()?.map(ParseError::UnexpectedToken)), } } @@ -36,36 +43,44 @@ fn parse_list_literal<'a>(parser: &mut Parser<'a>, is_const: bool) -> ParseResul &Token::BracketOpen, |p| parse_value_literal(p, is_const), &Token::BracketClose - )).map(InputValue::parsed_list)) + )) + .map(InputValue::parsed_list)) } -fn parse_object_literal<'a>(parser: &mut Parser<'a>, is_const: bool) -> ParseResult<'a, InputValue> { +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()))) + )) + .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, Spanning)> { +fn parse_object_field<'a>(parser: &mut Parser<'a>, + is_const: bool) + -> ParseResult<'a, (Spanning, Spanning)> { let key = try!(parser.expect_name()); try!(parser.expect(&Token::Colon)); let value = try!(parse_value_literal(parser, is_const)); - Ok(Spanning::start_end( - &key.start.clone(), - &value.end.clone(), - (key.map(|s| s.to_owned()), value))) + Ok(Spanning::start_end(&key.start.clone(), + &value.end.clone(), + (key.map(|s| s.to_owned()), value))) } fn parse_variable_literal<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, InputValue> { let Spanning { start: start_pos, .. } = try!(parser.expect(&Token::Dollar)); - let Spanning { item: name, end: end_pos, ..} = try!(parser.expect_name()); + let Spanning { + item: name, + end: end_pos, + .. + } = try!(parser.expect_name()); - Ok(Spanning::start_end( - &start_pos, - &end_pos, - InputValue::variable(name))) + Ok(Spanning::start_end(&start_pos, &end_pos, InputValue::variable(name))) } diff --git a/juniper/src/schema/meta.rs b/juniper/src/schema/meta.rs index 017ce1bc..2e824e0e 100644 --- a/juniper/src/schema/meta.rs +++ b/juniper/src/schema/meta.rs @@ -179,8 +179,7 @@ impl<'a> MetaType<'a> { MetaType::Enum(EnumMeta { name, .. }) | MetaType::Interface(InterfaceMeta { name, .. }) | MetaType::Union(UnionMeta { name, .. }) | - MetaType::InputObject(InputObjectMeta { name, .. }) => - Some(name), + MetaType::InputObject(InputObjectMeta { name, .. }) => Some(name), _ => None, } } @@ -195,8 +194,7 @@ impl<'a> MetaType<'a> { MetaType::Enum(EnumMeta { ref description, .. }) | MetaType::Interface(InterfaceMeta { ref description, .. }) | MetaType::Union(UnionMeta { ref description, .. }) | - MetaType::InputObject(InputObjectMeta { ref description, .. }) => - description.as_ref(), + MetaType::InputObject(InputObjectMeta { ref description, .. }) => description.as_ref(), _ => None, } } @@ -225,8 +223,9 @@ impl<'a> MetaType<'a> { pub fn field_by_name(&self, name: &str) -> Option<&Field> { match *self { MetaType::Object(ObjectMeta { ref fields, .. }) | - MetaType::Interface(InterfaceMeta { ref fields, .. }) => - fields.iter().find(|f| f.name == name), + MetaType::Interface(InterfaceMeta { ref fields, .. }) => { + fields.iter().find(|f| f.name == name) + } _ => None, } } @@ -236,8 +235,9 @@ impl<'a> MetaType<'a> { /// Only input objects have input fields. This method always returns `None` for other types. pub fn input_field_by_name(&self, name: &str) -> Option<&Argument> { match *self { - MetaType::InputObject(InputObjectMeta { ref input_fields, .. }) => - input_fields.iter().find(|f| f.name == name), + MetaType::InputObject(InputObjectMeta { ref input_fields, .. }) => { + input_fields.iter().find(|f| f.name == name) + } _ => None, } } @@ -250,16 +250,17 @@ impl<'a> MetaType<'a> { MetaType::Enum(EnumMeta { name, .. }) | MetaType::Interface(InterfaceMeta { name, .. }) | MetaType::Union(UnionMeta { name, .. }) | - MetaType::InputObject(InputObjectMeta { name, .. }) => - Type::NonNullNamed(name), - MetaType::List(ListMeta { ref of_type }) => - Type::NonNullList(Box::new(of_type.clone())), - MetaType::Nullable(NullableMeta { ref of_type }) => + MetaType::InputObject(InputObjectMeta { name, .. }) => Type::NonNullNamed(name), + MetaType::List(ListMeta { ref of_type }) => { + Type::NonNullList(Box::new(of_type.clone())) + } + MetaType::Nullable(NullableMeta { ref of_type }) => { match *of_type { Type::NonNullNamed(inner) => Type::Named(inner), Type::NonNullList(ref inner) => Type::List(inner.clone()), ref t => t.clone(), - }, + } + } MetaType::Placeholder(PlaceholderMeta { ref of_type }) => of_type.clone(), } } @@ -274,8 +275,7 @@ impl<'a> MetaType<'a> { match *self { MetaType::Scalar(ScalarMeta { ref try_parse_fn, .. }) | MetaType::Enum(EnumMeta { ref try_parse_fn, .. }) | - MetaType::InputObject(InputObjectMeta { ref try_parse_fn, .. }) => - Some(try_parse_fn), + MetaType::InputObject(InputObjectMeta { ref try_parse_fn, .. }) => Some(try_parse_fn), _ => None, } } @@ -333,8 +333,7 @@ impl<'a> ScalarMeta<'a> { ScalarMeta { name: name, description: None, - try_parse_fn: Box::new( - |v: &InputValue| ::from(v).is_some()), + try_parse_fn: Box::new(|v: &InputValue| ::from(v).is_some()), } } @@ -355,9 +354,7 @@ impl<'a> ScalarMeta<'a> { impl<'a> ListMeta<'a> { /// Build a new list type by wrapping the specified type pub fn new(of_type: Type<'a>) -> ListMeta<'a> { - ListMeta { - of_type: of_type, - } + ListMeta { of_type: of_type } } /// Wrap the list in a generic meta type @@ -369,9 +366,7 @@ impl<'a> ListMeta<'a> { impl<'a> NullableMeta<'a> { /// Build a new nullable type by wrapping the specified type pub fn new(of_type: Type<'a>) -> NullableMeta<'a> { - NullableMeta { - of_type: of_type, - } + NullableMeta { of_type: of_type } } /// Wrap the nullable type in a generic meta type @@ -404,8 +399,10 @@ impl<'a> ObjectMeta<'a> { /// If a list of interfaces already was provided prior to calling this method, they will be /// overwritten. pub fn interfaces(mut self, interfaces: &[Type<'a>]) -> ObjectMeta<'a> { - self.interface_names = interfaces.iter() - .map(|t| t.innermost_name().to_owned()).collect(); + self.interface_names = interfaces + .iter() + .map(|t| t.innermost_name().to_owned()) + .collect(); self } @@ -422,8 +419,7 @@ impl<'a> EnumMeta<'a> { name: name, description: None, values: values.to_vec(), - try_parse_fn: Box::new( - |v: &InputValue| ::from(v).is_some()), + try_parse_fn: Box::new(|v: &InputValue| ::from(v).is_some()), } } @@ -471,8 +467,10 @@ impl<'a> UnionMeta<'a> { UnionMeta { name: name, description: None, - of_type_names: of_types.iter() - .map(|t| t.innermost_name().to_owned()).collect(), + of_type_names: of_types + .iter() + .map(|t| t.innermost_name().to_owned()) + .collect(), } } @@ -492,13 +490,14 @@ impl<'a> UnionMeta<'a> { impl<'a> InputObjectMeta<'a> { /// Build a new input type with the specified name and input fields - pub fn new(name: &'a str, input_fields: &[Argument<'a>]) -> InputObjectMeta<'a> { + pub fn new(name: &'a str, + input_fields: &[Argument<'a>]) + -> InputObjectMeta<'a> { InputObjectMeta { name: name, description: None, input_fields: input_fields.to_vec(), - try_parse_fn: Box::new( - |v: &InputValue| ::from(v).is_some()), + try_parse_fn: Box::new(|v: &InputValue| ::from(v).is_some()), } } @@ -530,8 +529,12 @@ impl<'a> Field<'a> { /// Arguments are unordered and can't contain duplicates by name. pub fn argument(mut self, argument: Argument<'a>) -> Field<'a> { match self.arguments { - None => { self.arguments = Some(vec![argument]); } - Some(ref mut args) => { args.push(argument); } + None => { + self.arguments = Some(vec![argument]); + } + Some(ref mut args) => { + args.push(argument); + } }; self @@ -553,7 +556,7 @@ impl<'a> Argument<'a> { name: name.to_owned(), description: None, arg_type: arg_type, - default_value: None + default_value: None, } } diff --git a/juniper/src/schema/model.rs b/juniper/src/schema/model.rs index 64bd69f8..489153b0 100644 --- a/juniper/src/schema/model.rs +++ b/juniper/src/schema/model.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use std::fmt; -use types::base::{GraphQLType}; +use types::base::GraphQLType; use executor::{Registry, Context}; use ast::Type; use schema::meta::{MetaType, ObjectMeta, PlaceholderMeta, UnionMeta, InterfaceMeta, Argument}; @@ -54,7 +54,7 @@ pub enum DirectiveLocation { impl<'a, QueryT, MutationT> RootNode<'a, QueryT, MutationT> where QueryT: GraphQLType, - MutationT: GraphQLType, + MutationT: GraphQLType { /// Construct a new root node from query and mutation nodes /// @@ -72,7 +72,7 @@ impl<'a, QueryT, MutationT> RootNode<'a, QueryT, MutationT> impl<'a> SchemaType<'a> { pub fn new() -> SchemaType<'a> where QueryT: GraphQLType, - MutationT: GraphQLType, + MutationT: GraphQLType { let mut directives = HashMap::new(); let query_type_name: String; @@ -83,12 +83,9 @@ impl<'a> SchemaType<'a> { mutation_type_name = registry.get_type::().innermost_name().to_owned(); registry.get_type::(); - directives.insert( - "skip".to_owned(), - DirectiveType::new_skip(&mut registry)); - directives.insert( - "include".to_owned(), - DirectiveType::new_include(&mut registry)); + directives.insert("skip".to_owned(), DirectiveType::new_skip(&mut registry)); + directives.insert("include".to_owned(), + DirectiveType::new_include(&mut registry)); let mut meta_fields = vec![ registry.field::("__schema"), @@ -99,12 +96,10 @@ impl<'a> SchemaType<'a> { if let Some(root_type) = registry.types.get_mut(&query_type_name) { if let MetaType::Object(ObjectMeta { ref mut fields, .. }) = *root_type { fields.append(&mut meta_fields); - } - else { + } else { panic!("Root type is not an object"); } - } - else { + } else { panic!("Root type not found"); } @@ -117,7 +112,11 @@ impl<'a> SchemaType<'a> { SchemaType { types: registry.types, query_type_name: query_type_name, - mutation_type_name: if &mutation_type_name != "_EmptyMutation" { Some(mutation_type_name) } else { None }, + mutation_type_name: if &mutation_type_name != "_EmptyMutation" { + Some(mutation_type_name) + } else { + None + }, directives: directives, } } @@ -135,30 +134,33 @@ impl<'a> SchemaType<'a> { } pub fn query_type(&self) -> TypeType { - TypeType::Concrete( - self.types.get(&self.query_type_name) - .expect("Query type does not exist in schema")) + TypeType::Concrete(self.types + .get(&self.query_type_name) + .expect("Query type does not exist in schema")) } pub fn concrete_query_type(&self) -> &MetaType { - self.types.get(&self.query_type_name) + self.types + .get(&self.query_type_name) .expect("Query type does not exist in schema") } pub fn mutation_type(&self) -> Option { if let Some(ref mutation_type_name) = self.mutation_type_name { Some(self.type_by_name(mutation_type_name) - .expect("Mutation type does not exist in schema")) - } - else { + .expect("Mutation type does not exist in schema")) + } else { None } } pub fn concrete_mutation_type(&self) -> Option<&MetaType> { - self.mutation_type_name.as_ref().map(|name| - self.concrete_type_by_name(name) - .expect("Mutation type does not exist in schema")) + self.mutation_type_name + .as_ref() + .map(|name| { + self.concrete_type_by_name(name) + .expect("Mutation type does not exist in schema") + }) } pub fn type_list(&self) -> Vec { @@ -171,15 +173,14 @@ impl<'a> SchemaType<'a> { pub fn make_type(&self, t: &Type) -> TypeType { match *t { - Type::NonNullNamed(n) => - TypeType::NonNull(Box::new( - self.type_by_name(n).expect("Type not found in schema"))), - Type::NonNullList(ref inner) => - TypeType::NonNull(Box::new( - TypeType::List(Box::new(self.make_type(inner))))), + Type::NonNullNamed(n) => { + TypeType::NonNull(Box::new(self.type_by_name(n).expect("Type not found in schema"))) + } + Type::NonNullList(ref inner) => { + TypeType::NonNull(Box::new(TypeType::List(Box::new(self.make_type(inner))))) + } Type::Named(n) => self.type_by_name(n).expect("Type not found in schema"), - Type::List(ref inner) => - TypeType::List(Box::new(self.make_type(inner))), + Type::List(ref inner) => TypeType::List(Box::new(self.make_type(inner))), } } @@ -197,7 +198,11 @@ impl<'a> SchemaType<'a> { } match (t1.is_abstract(), t2.is_abstract()) { - (true, true) => self.possible_types(t1).iter().any(|t| self.is_possible_type(t2, t)), + (true, true) => { + self.possible_types(t1) + .iter() + .any(|t| self.is_possible_type(t2, t)) + } (true, false) => self.is_possible_type(t1, t2), (false, true) => self.is_possible_type(t2, t1), (false, false) => false, @@ -206,21 +211,24 @@ impl<'a> SchemaType<'a> { pub fn possible_types(&self, t: &MetaType) -> Vec<&MetaType> { match *t { - MetaType::Union(UnionMeta { ref of_type_names, .. }) => + MetaType::Union(UnionMeta { ref of_type_names, .. }) => { of_type_names .iter() .flat_map(|t| self.concrete_type_by_name(t)) - .collect(), - MetaType::Interface(InterfaceMeta { name, .. }) => + .collect() + } + MetaType::Interface(InterfaceMeta { name, .. }) => { self.concrete_type_list() .into_iter() .filter(|t| match **t { - MetaType::Object(ObjectMeta { ref interface_names, .. }) => - interface_names.iter().any(|iname| iname == name), - _ => false - }) - .collect(), - _ => panic!("Can't retrieve possible types from non-abstract meta type") + MetaType::Object(ObjectMeta { ref interface_names, .. }) => { + interface_names.iter().any(|iname| iname == name) + } + _ => false, + }) + .collect() + } + _ => panic!("Can't retrieve possible types from non-abstract meta type"), } } @@ -240,26 +248,25 @@ impl<'a> SchemaType<'a> { match (super_type, sub_type) { (&NonNullNamed(super_name), &NonNullNamed(sub_name)) | (&Named(super_name), &Named(sub_name)) | - (&Named(super_name), &NonNullNamed(sub_name)) => - self.is_named_subtype(sub_name, super_name), + (&Named(super_name), &NonNullNamed(sub_name)) => { + self.is_named_subtype(sub_name, super_name) + } (&NonNullList(ref super_inner), &NonNullList(ref sub_inner)) | (&List(ref super_inner), &List(ref sub_inner)) | - (&List(ref super_inner), &NonNullList(ref sub_inner)) => - self.is_subtype(sub_inner, super_inner), - _ => false + (&List(ref super_inner), &NonNullList(ref sub_inner)) => { + self.is_subtype(sub_inner, super_inner) + } + _ => false, } } pub fn is_named_subtype(&self, sub_type_name: &str, super_type_name: &str) -> bool { if sub_type_name == super_type_name { true - } - else if let (Some(sub_type), Some(super_type)) - = (self.concrete_type_by_name(sub_type_name), self.concrete_type_by_name(super_type_name)) - { + } else if let (Some(sub_type), Some(super_type)) = + (self.concrete_type_by_name(sub_type_name), self.concrete_type_by_name(super_type_name)) { super_type.is_abstract() && self.is_possible_type(super_type, sub_type) - } - else { + } else { false } } @@ -269,13 +276,16 @@ impl<'a> TypeType<'a> { pub fn to_concrete(&self) -> Option<&'a MetaType> { match *self { TypeType::Concrete(t) => Some(t), - _ => None + _ => None, } } } impl<'a> DirectiveType<'a> { - pub fn new(name: &str, locations: &[DirectiveLocation], arguments: &[Argument<'a>]) -> DirectiveType<'a> { + pub fn new(name: &str, + locations: &[DirectiveLocation], + arguments: &[Argument<'a>]) + -> DirectiveType<'a> { DirectiveType { name: name.to_owned(), description: None, @@ -285,29 +295,19 @@ impl<'a> DirectiveType<'a> { } fn new_skip(registry: &mut Registry<'a>) -> DirectiveType<'a> { - Self::new( - "skip", - &[ - DirectiveLocation::Field, - DirectiveLocation::FragmentSpread, - DirectiveLocation::InlineFragment, - ], - &[ - registry.arg::("if"), - ]) + Self::new("skip", + &[DirectiveLocation::Field, + DirectiveLocation::FragmentSpread, + DirectiveLocation::InlineFragment], + &[registry.arg::("if")]) } fn new_include(registry: &mut Registry<'a>) -> DirectiveType<'a> { - Self::new( - "include", - &[ - DirectiveLocation::Field, - DirectiveLocation::FragmentSpread, - DirectiveLocation::InlineFragment, - ], - &[ - registry.arg::("if"), - ]) + Self::new("include", + &[DirectiveLocation::Field, + DirectiveLocation::FragmentSpread, + DirectiveLocation::InlineFragment], + &[registry.arg::("if")]) } pub fn description(mut self, description: &str) -> DirectiveType<'a> { @@ -319,13 +319,13 @@ impl<'a> DirectiveType<'a> { impl fmt::Display for DirectiveLocation { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(match *self { - DirectiveLocation::Query => "query", - DirectiveLocation::Mutation => "mutation", - DirectiveLocation::Field => "field", - DirectiveLocation::FragmentDefinition => "fragment definition", - DirectiveLocation::FragmentSpread => "fragment spread", - DirectiveLocation::InlineFragment => "inline fragment", - }) + DirectiveLocation::Query => "query", + DirectiveLocation::Mutation => "mutation", + DirectiveLocation::Field => "field", + DirectiveLocation::FragmentDefinition => "fragment definition", + DirectiveLocation::FragmentSpread => "fragment spread", + DirectiveLocation::InlineFragment => "inline fragment", + }) } } diff --git a/juniper/src/schema/schema.rs b/juniper/src/schema/schema.rs index 93dcd4c5..5874551a 100644 --- a/juniper/src/schema/schema.rs +++ b/juniper/src/schema/schema.rs @@ -6,8 +6,8 @@ use schema::meta::{MetaType, ObjectMeta, EnumMeta, InputObjectMeta, UnionMeta, I use schema::model::{RootNode, SchemaType, TypeType, DirectiveType, DirectiveLocation}; impl<'a, CtxT, QueryT, MutationT> GraphQLType for RootNode<'a, QueryT, MutationT> - where QueryT: GraphQLType, - MutationT: GraphQLType + where QueryT: GraphQLType, + MutationT: GraphQLType { type Context = CtxT; @@ -19,14 +19,24 @@ impl<'a, CtxT, QueryT, MutationT> GraphQLType for RootNode<'a, QueryT, MutationT QueryT::meta(registry) } - fn resolve_field(&self, field: &str, args: &Arguments, executor: &Executor) -> ExecutionResult { + fn resolve_field(&self, + field: &str, + args: &Arguments, + executor: &Executor) + -> ExecutionResult { match field { - "__schema" => executor.replaced_context(&self.schema).resolve(&self.schema), + "__schema" => { + executor + .replaced_context(&self.schema) + .resolve(&self.schema) + } "__type" => { let type_name: String = args.get("name").unwrap(); - executor.replaced_context(&self.schema).resolve(&self.schema.type_by_name(&type_name)) - }, - _=> self.query_type.resolve_field(field, args, executor), + executor + .replaced_context(&self.schema) + .resolve(&self.schema.type_by_name(&type_name)) + } + _ => self.query_type.resolve_field(field, args, executor), } } } diff --git a/juniper/src/tests/introspection_tests.rs b/juniper/src/tests/introspection_tests.rs index 6e9cceab..0bab4ab1 100644 --- a/juniper/src/tests/introspection_tests.rs +++ b/juniper/src/tests/introspection_tests.rs @@ -148,15 +148,25 @@ fn test_possible_types() { assert_eq!(errors, vec![]); let possible_types = result - .as_object_value().expect("execution result not an object") - .get("__type").expect("'__type' not present in result") - .as_object_value().expect("'__type' not an object") - .get("possibleTypes").expect("'possibleTypes' not present in '__type'") - .as_list_value().expect("'possibleTypes' not a list") - .iter().map(|t| t - .as_object_value().expect("possible type not an object") - .get("name").expect("'name' not present in type") - .as_string_value().expect("'name' not a string")) + .as_object_value() + .expect("execution result not an object") + .get("__type") + .expect("'__type' not present in result") + .as_object_value() + .expect("'__type' not an object") + .get("possibleTypes") + .expect("'possibleTypes' not present in '__type'") + .as_list_value() + .expect("'possibleTypes' not a list") + .iter() + .map(|t| { + t.as_object_value() + .expect("possible type not an object") + .get("name") + .expect("'name' not present in type") + .as_string_value() + .expect("'name' not a string") + }) .collect::>(); assert_eq!( diff --git a/juniper/src/tests/mod.rs b/juniper/src/tests/mod.rs index b5e3076b..79b5e798 100644 --- a/juniper/src/tests/mod.rs +++ b/juniper/src/tests/mod.rs @@ -2,5 +2,7 @@ pub mod model; mod schema; -#[cfg(test)] mod query_tests; -#[cfg(test)] mod introspection_tests; +#[cfg(test)] +mod query_tests; +#[cfg(test)] +mod introspection_tests; diff --git a/juniper/src/tests/model.rs b/juniper/src/tests/model.rs index f7098771..5eb42182 100644 --- a/juniper/src/tests/model.rs +++ b/juniper/src/tests/model.rs @@ -45,29 +45,57 @@ struct DroidData { } impl Character for HumanData { - fn id(&self) -> &str { &self.id } - fn name(&self) -> &str { &self.name } - fn friend_ids(&self) -> &[String] { &self.friend_ids } - fn appears_in(&self) -> &[Episode] { &self.appears_in } - fn secret_backstory(&self) -> &Option { &self.secret_backstory } - fn as_character(&self) -> &Character { self } + fn id(&self) -> &str { + &self.id + } + fn name(&self) -> &str { + &self.name + } + fn friend_ids(&self) -> &[String] { + &self.friend_ids + } + fn appears_in(&self) -> &[Episode] { + &self.appears_in + } + fn secret_backstory(&self) -> &Option { + &self.secret_backstory + } + fn as_character(&self) -> &Character { + self + } } impl Human for HumanData { - fn home_planet(&self) -> &Option { &self.home_planet } + fn home_planet(&self) -> &Option { + &self.home_planet + } } impl Character for DroidData { - fn id(&self) -> &str { &self.id } - fn name(&self) -> &str { &self.name } - fn friend_ids(&self) -> &[String] { &self.friend_ids } - fn appears_in(&self) -> &[Episode] { &self.appears_in } - fn secret_backstory(&self) -> &Option { &self.secret_backstory } - fn as_character(&self) -> &Character { self } + fn id(&self) -> &str { + &self.id + } + fn name(&self) -> &str { + &self.name + } + fn friend_ids(&self) -> &[String] { + &self.friend_ids + } + fn appears_in(&self) -> &[Episode] { + &self.appears_in + } + fn secret_backstory(&self) -> &Option { + &self.secret_backstory + } + fn as_character(&self) -> &Character { + self + } } impl Droid for DroidData { - fn primary_function(&self) -> &Option { &self.primary_function } + fn primary_function(&self) -> &Option { + &self.primary_function + } } pub struct Database { @@ -76,18 +104,21 @@ pub struct Database { } impl HumanData { - pub fn new( - id: &str, - name: &str, - friend_ids: &[&str], - appears_in: &[Episode], - secret_backstory: Option<&str>, - home_planet: Option<&str>) -> HumanData - { + pub fn new(id: &str, + name: &str, + friend_ids: &[&str], + appears_in: &[Episode], + secret_backstory: Option<&str>, + home_planet: Option<&str>) + -> HumanData { HumanData { id: id.to_owned(), name: name.to_owned(), - friend_ids: friend_ids.to_owned().into_iter().map(|f| f.to_owned()).collect(), + friend_ids: friend_ids + .to_owned() + .into_iter() + .map(|f| f.to_owned()) + .collect(), appears_in: appears_in.iter().cloned().collect(), secret_backstory: secret_backstory.map(|b| b.to_owned()), home_planet: home_planet.map(|p| p.to_owned()), @@ -96,18 +127,21 @@ impl HumanData { } impl DroidData { - pub fn new( - id: &str, - name: &str, - friend_ids: &[&str], - appears_in: &[Episode], - secret_backstory: Option<&str>, - primary_function: Option<&str>) -> DroidData - { + pub fn new(id: &str, + name: &str, + friend_ids: &[&str], + appears_in: &[Episode], + secret_backstory: Option<&str>, + primary_function: Option<&str>) + -> DroidData { DroidData { id: id.to_owned(), name: name.to_owned(), - friend_ids: friend_ids.to_owned().into_iter().map(|f| f.to_owned()).collect(), + friend_ids: friend_ids + .to_owned() + .into_iter() + .map(|f| f.to_owned()) + .collect(), appears_in: appears_in.iter().cloned().collect(), secret_backstory: secret_backstory.map(|b| b.to_owned()), primary_function: primary_function.map(|p| p.to_owned()), @@ -120,68 +154,61 @@ impl Database { let mut humans = HashMap::new(); let mut droids = HashMap::new(); - humans.insert("1000".to_owned(), HumanData::new( - "1000", - "Luke Skywalker", - &["1002", "1003", "2000", "2001"], - &[Episode::NewHope, Episode::Empire, Episode::Jedi], - None, - Some("Tatooine"), - )); + humans.insert("1000".to_owned(), + HumanData::new("1000", + "Luke Skywalker", + &["1002", "1003", "2000", "2001"], + &[Episode::NewHope, Episode::Empire, Episode::Jedi], + None, + Some("Tatooine"))); - humans.insert("1001".to_owned(), HumanData::new( - "1001", - "Darth Vader", - &["1004"], - &[Episode::NewHope, Episode::Empire, Episode::Jedi], - None, - Some("Tatooine"), - )); + humans.insert("1001".to_owned(), + HumanData::new("1001", + "Darth Vader", + &["1004"], + &[Episode::NewHope, Episode::Empire, Episode::Jedi], + None, + Some("Tatooine"))); - humans.insert("1002".to_owned(), HumanData::new( - "1002", - "Han Solo", - &["1000", "1003", "2001"], - &[Episode::NewHope, Episode::Empire, Episode::Jedi], - None, - None, - )); + humans.insert("1002".to_owned(), + HumanData::new("1002", + "Han Solo", + &["1000", "1003", "2001"], + &[Episode::NewHope, Episode::Empire, Episode::Jedi], + None, + None)); - humans.insert("1003".to_owned(), HumanData::new( - "1003", - "Leia Organa", - &["1000", "1002", "2000", "2001"], - &[Episode::NewHope, Episode::Empire, Episode::Jedi], - None, - Some("Alderaan"), - )); + humans.insert("1003".to_owned(), + HumanData::new("1003", + "Leia Organa", + &["1000", "1002", "2000", "2001"], + &[Episode::NewHope, Episode::Empire, Episode::Jedi], + None, + Some("Alderaan"))); - humans.insert("1004".to_owned(), HumanData::new( - "1004", - "Wilhuff Tarkin", - &["1001"], - &[Episode::NewHope], - None, - None, - )); + humans.insert("1004".to_owned(), + HumanData::new("1004", + "Wilhuff Tarkin", + &["1001"], + &[Episode::NewHope], + None, + None)); - droids.insert("2000".to_owned(), DroidData::new( - "2000", - "C-3PO", - &["1000", "1002", "1003", "2001"], - &[Episode::NewHope, Episode::Empire, Episode::Jedi], - None, - Some("Protocol"), - )); + droids.insert("2000".to_owned(), + DroidData::new("2000", + "C-3PO", + &["1000", "1002", "1003", "2001"], + &[Episode::NewHope, Episode::Empire, Episode::Jedi], + None, + Some("Protocol"))); - droids.insert("2001".to_owned(), DroidData::new( - "2001", - "R2-D2", - &["1000", "1002", "1003"], - &[Episode::NewHope, Episode::Empire, Episode::Jedi], - None, - Some("Astromech"), - )); + droids.insert("2001".to_owned(), + DroidData::new("2001", + "R2-D2", + &["1000", "1002", "1003"], + &[Episode::NewHope, Episode::Empire, Episode::Jedi], + None, + Some("Astromech"))); Database { humans: humans, @@ -208,17 +235,16 @@ impl Database { pub fn get_character(&self, id: &str) -> Option<&Character> { if let Some(h) = self.humans.get(id) { Some(h) - } - else if let Some(d) = self.droids.get(id) { + } else if let Some(d) = self.droids.get(id) { Some(d) - } - else { + } else { None } } pub fn get_friends(&self, c: &Character) -> Vec<&Character> { - c.friend_ids().iter() + c.friend_ids() + .iter() .flat_map(|id| self.get_character(id)) .collect() } diff --git a/juniper/src/tests/query_tests.rs b/juniper/src/tests/query_tests.rs index 6278df43..aeec86c3 100644 --- a/juniper/src/tests/query_tests.rs +++ b/juniper/src/tests/query_tests.rs @@ -251,7 +251,9 @@ fn test_query_name_variable() { let vars = vec![ ("someId".to_owned(), InputValue::string("1000")), - ].into_iter().collect(); + ] + .into_iter() + .collect(); assert_eq!( ::execute(doc, None, &schema, &vars, &database), @@ -271,7 +273,9 @@ fn test_query_name_invalid_variable() { let vars = vec![ ("someId".to_owned(), InputValue::string("some invalid id")), - ].into_iter().collect(); + ] + .into_iter() + .collect(); assert_eq!( ::execute(doc, None, &schema, &vars, &database), diff --git a/juniper/src/types/base.rs b/juniper/src/types/base.rs index 2c1d2770..af01b727 100644 --- a/juniper/src/types/base.rs +++ b/juniper/src/types/base.rs @@ -71,7 +71,9 @@ pub struct Arguments<'a> { impl<'a> Arguments<'a> { #[doc(hidden)] - pub fn new(mut args: Option>, meta_args: &'a Option>) -> Arguments<'a> { + pub fn new(mut args: Option>, + meta_args: &'a Option>) + -> Arguments<'a> { if meta_args.is_some() && args.is_none() { args = Some(HashMap::new()); } @@ -88,9 +90,7 @@ impl<'a> Arguments<'a> { } } - Arguments { - args: args - } + Arguments { args: args } } /// Get and convert an argument into the desired type. @@ -100,12 +100,16 @@ impl<'a> Arguments<'a> { /// /// Returns `Some` if the argument is present _and_ type conversion /// succeeeds. - pub fn get(&self, key: &str) -> Option where T: FromInputValue { + pub fn get(&self, key: &str) -> Option + where T: FromInputValue + { match self.args { - Some(ref args) => match args.get(key) { - Some(v) => Some(v.convert().unwrap()), - None => None, - }, + Some(ref args) => { + match args.get(key) { + Some(v) => Some(v.convert().unwrap()), + None => None, + } + } None => None, } } @@ -237,9 +241,11 @@ pub trait GraphQLType: Sized { /// /// The default implementation panics. #[allow(unused_variables)] - fn resolve_field(&self, field_name: &str, arguments: &Arguments, executor: &Executor) - -> ExecutionResult - { + fn resolve_field(&self, + field_name: &str, + arguments: &Arguments, + executor: &Executor) + -> ExecutionResult { panic!("resolve_field must be implemented by object types"); } @@ -250,7 +256,11 @@ pub trait GraphQLType: Sized { /// /// The default implementation panics. #[allow(unused_variables)] - fn resolve_into_type(&self, type_name: &str, selection_set: Option<&[Selection]>, executor: &Executor) -> ExecutionResult { + fn resolve_into_type(&self, + type_name: &str, + selection_set: Option<&[Selection]>, + executor: &Executor) + -> ExecutionResult { if Self::name().unwrap() == type_name { Ok(self.resolve(selection_set, executor)) } else { @@ -276,32 +286,38 @@ pub trait GraphQLType: Sized { /// The default implementation uses `resolve_field` to resolve all fields, /// including those through fragment expansion, for object types. For /// non-object types, this method panics. - fn resolve(&self, selection_set: Option<&[Selection]>, executor: &Executor) -> Value { + fn resolve(&self, + selection_set: Option<&[Selection]>, + executor: &Executor) + -> Value { if let Some(selection_set) = selection_set { let mut result = HashMap::new(); resolve_selection_set_into(self, selection_set, executor, &mut result); Value::object(result) - } - else { + } else { panic!("resolve() must be implemented by non-object output types"); } } } -fn resolve_selection_set_into( - instance: &T, - selection_set: &[Selection], - executor: &Executor, - result: &mut HashMap) - where T: GraphQLType +fn resolve_selection_set_into(instance: &T, + selection_set: &[Selection], + executor: &Executor, + result: &mut HashMap) + where T: GraphQLType { - let meta_type = executor.schema() + let meta_type = executor + .schema() .concrete_type_by_name(T::name().expect("Resolving named type's selection set")) .expect("Type not found in schema"); for selection in selection_set { match *selection { - Selection::Field(Spanning { item: ref f, start: ref start_pos, .. }) => { + Selection::Field(Spanning { + item: ref f, + start: ref start_pos, + .. + }) => { if is_excluded(&f.directives, executor.variables()) { continue; } @@ -309,10 +325,8 @@ fn resolve_selection_set_into( let response_name = &f.alias.as_ref().unwrap_or(&f.name).item; if f.name.item == "__typename" { - result.insert( - (*response_name).to_owned(), - Value::string( - instance.concrete_type_name(executor.context()))); + result.insert((*response_name).to_owned(), + Value::string(instance.concrete_type_name(executor.context()))); continue; } @@ -321,19 +335,22 @@ fn resolve_selection_set_into( let exec_vars = executor.variables(); - let sub_exec = executor.sub_executor( - Some(response_name), - start_pos.clone(), - f.selection_set.as_ref().map(|v| &v[..])); + let sub_exec = + executor.sub_executor(Some(response_name), + start_pos.clone(), + f.selection_set.as_ref().map(|v| &v[..])); - let field_result = instance.resolve_field( - f.name.item, - &Arguments::new( - f.arguments.as_ref().map(|m| - m.item.iter().map(|&(ref k, ref v)| - (k.item, v.item.clone().into_const(exec_vars))).collect()), - &meta_field.arguments), - &sub_exec); + let field_result = instance.resolve_field(f.name.item, + &Arguments::new(f.arguments + .as_ref() + .map(|m| { + m.item + .iter() + .map(|&(ref k, ref v)| (k.item, v.item.clone().into_const(exec_vars))) + .collect() + }), + &meta_field.arguments), + &sub_exec); match field_result { Ok(v) => merge_key_into(result, response_name, v), @@ -342,51 +359,50 @@ fn resolve_selection_set_into( result.insert((*response_name).to_owned(), Value::null()); } } - }, + } Selection::FragmentSpread(Spanning { item: ref spread, .. }) => { if is_excluded(&spread.directives, executor.variables()) { continue; } - let fragment = &executor.fragment_by_name(spread.name.item) - .expect("Fragment could not be found"); + let fragment = &executor + .fragment_by_name(spread.name.item) + .expect("Fragment could not be found"); - resolve_selection_set_into( - instance, &fragment.selection_set[..], executor, result); - }, - Selection::InlineFragment(Spanning { item: ref fragment, start: ref start_pos, .. }) => { + resolve_selection_set_into(instance, &fragment.selection_set[..], executor, result); + } + Selection::InlineFragment(Spanning { + item: ref fragment, + start: ref start_pos, + .. + }) => { if is_excluded(&fragment.directives, executor.variables()) { continue; } - let sub_exec = executor.sub_executor( - None, - start_pos.clone(), - Some(&fragment.selection_set[..])); + let sub_exec = + executor + .sub_executor(None, start_pos.clone(), Some(&fragment.selection_set[..])); if let Some(ref type_condition) = fragment.type_condition { - let sub_result = instance.resolve_into_type( - type_condition.item, - Some(&fragment.selection_set[..]), - &sub_exec); + let sub_result = instance.resolve_into_type(type_condition.item, + Some(&fragment.selection_set[..]), + &sub_exec); if let Ok(Value::Object(mut hash_map)) = sub_result { for (k, v) in hash_map.drain() { result.insert(k, v); } + } else if let Err(e) = sub_result { + sub_exec.push_error(e, start_pos.clone()); } - else if let Err(e) = sub_result { - sub_exec.push_error(e, start_pos.clone()); - } + } else { + resolve_selection_set_into(instance, + &fragment.selection_set[..], + &sub_exec, + result); } - else { - resolve_selection_set_into( - instance, - &fragment.selection_set[..], - &sub_exec, - result); - } - }, + } } } } @@ -394,49 +410,44 @@ fn resolve_selection_set_into( fn is_excluded(directives: &Option>>, vars: &Variables) -> bool { if let Some(ref directives) = *directives { for &Spanning { item: ref directive, .. } in directives { - let condition: bool = directive.arguments.iter() + let condition: bool = directive + .arguments + .iter() .flat_map(|m| m.item.get("if")) .flat_map(|v| v.item.clone().into_const(vars).convert()) - .next().unwrap(); + .next() + .unwrap(); if (directive.name.item == "skip" && condition) || (directive.name.item == "include" && !condition) { - return true + return true; } } } false } -fn merge_key_into( - result: &mut HashMap, - response_name: &str, - value: Value, -) { +fn merge_key_into(result: &mut HashMap, response_name: &str, value: Value) { match result.entry(response_name.to_owned()) { Entry::Occupied(mut e) => { match (e.get_mut().as_mut_object_value(), value) { (Some(dest_obj), Value::Object(src_obj)) => { merge_maps(dest_obj, src_obj); - }, + } _ => {} } - }, + } Entry::Vacant(e) => { e.insert(value); - }, + } } } -fn merge_maps( - dest: &mut HashMap, - src: HashMap, -) { +fn merge_maps(dest: &mut HashMap, src: HashMap) { for (key, value) in src { if dest.contains_key(&key) { merge_key_into(dest, &key, value); - } - else { + } else { dest.insert(key, value); } } diff --git a/juniper/src/types/containers.rs b/juniper/src/types/containers.rs index 9591b41c..e93bc8f2 100644 --- a/juniper/src/types/containers.rs +++ b/juniper/src/types/containers.rs @@ -3,9 +3,11 @@ use value::Value; use schema::meta::MetaType; use executor::{Executor, Registry}; -use types::base::{GraphQLType}; +use types::base::GraphQLType; -impl GraphQLType for Option where T: GraphQLType { +impl GraphQLType for Option + where T: GraphQLType +{ type Context = CtxT; fn name() -> Option<&'static str> { @@ -24,19 +26,25 @@ impl GraphQLType for Option where T: GraphQLType { } } -impl FromInputValue for Option where T: FromInputValue { +impl FromInputValue for Option + where T: FromInputValue +{ fn from(v: &InputValue) -> Option> { match v { &InputValue::Null => Some(None), - v => match v.convert() { - Some(x) => Some(Some(x)), - None => None, + v => { + match v.convert() { + Some(x) => Some(Some(x)), + None => None, + } } } } } -impl ToInputValue for Option where T: ToInputValue { +impl ToInputValue for Option + where T: ToInputValue +{ fn to(&self) -> InputValue { match *self { Some(ref v) => v.to(), @@ -45,7 +53,9 @@ impl ToInputValue for Option where T: ToInputValue { } } -impl GraphQLType for Vec where T: GraphQLType { +impl GraphQLType for Vec + where T: GraphQLType +{ type Context = CtxT; fn name() -> Option<&'static str> { @@ -57,42 +67,44 @@ impl GraphQLType for Vec where T: GraphQLType { } fn resolve(&self, _: Option<&[Selection]>, executor: &Executor) -> Value { - Value::list( - self.iter().map(|e| executor.resolve_into_value(e)).collect() - ) + Value::list(self.iter() + .map(|e| executor.resolve_into_value(e)) + .collect()) } } -impl FromInputValue for Vec where T: FromInputValue { +impl FromInputValue for Vec + where T: FromInputValue +{ fn from(v: &InputValue) -> Option> { match *v { InputValue::List(ref ls) => { let v: Vec<_> = ls.iter().filter_map(|i| i.item.convert()).collect(); - if v.len() == ls.len() { - Some(v) - } - else { - None - } - }, - ref other => + if v.len() == ls.len() { Some(v) } else { None } + } + ref other => { if let Some(e) = other.convert() { Some(vec![ e ]) } else { None } + } } } } -impl ToInputValue for Vec where T: ToInputValue { +impl ToInputValue for Vec + where T: ToInputValue +{ fn to(&self) -> InputValue { InputValue::list(self.iter().map(|v| v.to()).collect()) } } -impl<'a, T, CtxT> GraphQLType for &'a [T] where T: GraphQLType { +impl<'a, T, CtxT> GraphQLType for &'a [T] + where T: GraphQLType +{ type Context = CtxT; fn name() -> Option<&'static str> { @@ -104,13 +116,15 @@ impl<'a, T, CtxT> GraphQLType for &'a [T] where T: GraphQLType { } fn resolve(&self, _: Option<&[Selection]>, executor: &Executor) -> Value { - Value::list( - self.iter().map(|e| executor.resolve_into_value(e)).collect() - ) + Value::list(self.iter() + .map(|e| executor.resolve_into_value(e)) + .collect()) } } -impl<'a, T> ToInputValue for &'a [T] where T: ToInputValue { +impl<'a, T> ToInputValue for &'a [T] + where T: ToInputValue +{ fn to(&self) -> InputValue { InputValue::list(self.iter().map(|v| v.to()).collect()) } diff --git a/juniper/src/types/pointers.rs b/juniper/src/types/pointers.rs index 2ba17788..cae0ab8f 100644 --- a/juniper/src/types/pointers.rs +++ b/juniper/src/types/pointers.rs @@ -5,7 +5,9 @@ use schema::meta::MetaType; use executor::{Executor, Registry, ExecutionResult}; use types::base::{Arguments, GraphQLType}; -impl GraphQLType for Box where T: GraphQLType { +impl GraphQLType for Box + where T: GraphQLType +{ type Context = CtxT; fn name() -> Option<&'static str> { @@ -16,12 +18,19 @@ impl GraphQLType for Box where T: GraphQLType { T::meta(registry) } - fn resolve_into_type(&self, name: &str, selection_set: Option<&[Selection]>, executor: &Executor) -> ExecutionResult { + fn resolve_into_type(&self, + name: &str, + selection_set: Option<&[Selection]>, + executor: &Executor) + -> ExecutionResult { (**self).resolve_into_type(name, selection_set, executor) } - fn resolve_field(&self, field: &str, args: &Arguments, executor: &Executor) -> ExecutionResult - { + fn resolve_field(&self, + field: &str, + args: &Arguments, + executor: &Executor) + -> ExecutionResult { (**self).resolve_field(field, args, executor) } @@ -30,7 +39,9 @@ impl GraphQLType for Box where T: GraphQLType { } } -impl FromInputValue for Box where T: FromInputValue { +impl FromInputValue for Box + where T: FromInputValue +{ fn from(v: &InputValue) -> Option> { match ::from(v) { Some(v) => Some(Box::new(v)), @@ -39,13 +50,17 @@ impl FromInputValue for Box where T: FromInputValue { } } -impl ToInputValue for Box where T: ToInputValue { +impl ToInputValue for Box + where T: ToInputValue +{ fn to(&self) -> InputValue { (**self).to() } } -impl<'a, T, CtxT> GraphQLType for &'a T where T: GraphQLType { +impl<'a, T, CtxT> GraphQLType for &'a T + where T: GraphQLType +{ type Context = CtxT; fn name() -> Option<&'static str> { @@ -56,12 +71,19 @@ impl<'a, T, CtxT> GraphQLType for &'a T where T: GraphQLType { T::meta(registry) } - fn resolve_into_type(&self, name: &str, selection_set: Option<&[Selection]>, executor: &Executor) -> ExecutionResult { + fn resolve_into_type(&self, + name: &str, + selection_set: Option<&[Selection]>, + executor: &Executor) + -> ExecutionResult { (**self).resolve_into_type(name, selection_set, executor) } - fn resolve_field(&self, field: &str, args: &Arguments, executor: &Executor) -> ExecutionResult - { + fn resolve_field(&self, + field: &str, + args: &Arguments, + executor: &Executor) + -> ExecutionResult { (**self).resolve_field(field, args, executor) } @@ -70,7 +92,9 @@ impl<'a, T, CtxT> GraphQLType for &'a T where T: GraphQLType { } } -impl<'a, T> ToInputValue for &'a T where T: ToInputValue { +impl<'a, T> ToInputValue for &'a T + where T: ToInputValue +{ fn to(&self) -> InputValue { (**self).to() } diff --git a/juniper/src/types/scalars.rs b/juniper/src/types/scalars.rs index 03cb5e69..d6baeae4 100644 --- a/juniper/src/types/scalars.rs +++ b/juniper/src/types/scalars.rs @@ -156,9 +156,7 @@ pub struct EmptyMutation { impl EmptyMutation { /// Construct a new empty mutation pub fn new() -> EmptyMutation { - EmptyMutation { - phantom: PhantomData, - } + EmptyMutation { phantom: PhantomData } } } diff --git a/juniper/src/types/utilities.rs b/juniper/src/types/utilities.rs index e50263b8..0790931e 100644 --- a/juniper/src/types/utilities.rs +++ b/juniper/src/types/utilities.rs @@ -3,27 +3,33 @@ use ast::InputValue; use schema::model::{SchemaType, TypeType}; use schema::meta::{MetaType, InputObjectMeta, EnumMeta}; -pub fn is_valid_literal_value(schema: &SchemaType, arg_type: &TypeType, arg_value: &InputValue) -> bool { +pub fn is_valid_literal_value(schema: &SchemaType, + arg_type: &TypeType, + arg_value: &InputValue) + -> bool { match *arg_type { TypeType::NonNull(ref inner) => { if arg_value.is_null() { false - } - else { + } else { is_valid_literal_value(schema, inner, arg_value) } } TypeType::List(ref inner) => { match *arg_value { - InputValue::List(ref items) => items.iter().all(|i| is_valid_literal_value(schema, inner, &i.item)), + InputValue::List(ref items) => { + items + .iter() + .all(|i| is_valid_literal_value(schema, inner, &i.item)) + } ref v => is_valid_literal_value(schema, inner, v), } } TypeType::Concrete(t) => { // Even though InputValue::String can be parsed into an enum, they // are not valid as enum *literals* in a GraphQL query. - if let (&InputValue::String(_), Some(&MetaType::Enum(EnumMeta { .. }))) - = (arg_value, arg_type.to_concrete()) { + if let (&InputValue::String(_), Some(&MetaType::Enum(EnumMeta { .. }))) = + (arg_value, arg_type.to_concrete()) { return false; } @@ -40,31 +46,36 @@ pub fn is_valid_literal_value(schema: &SchemaType, arg_type: &TypeType, arg_valu } else { false } - }, + } InputValue::List(_) => false, InputValue::Object(ref obj) => { if let MetaType::InputObject(InputObjectMeta { ref input_fields, .. }) = *t { - let mut remaining_required_fields = input_fields.iter() - .filter_map(|f| if f.arg_type.is_non_null() { Some(&f.name) } else { None }) + let mut remaining_required_fields = input_fields + .iter() + .filter_map(|f| if f.arg_type.is_non_null() { + Some(&f.name) + } else { + None + }) .collect::>(); - let all_types_ok = obj.iter().all(|&(ref key, ref value)| { - remaining_required_fields.remove(&key.item); - if let Some(ref arg_type) = input_fields.iter() - .filter(|f| f.name == key.item) - .map(|f| schema.make_type(&f.arg_type)) - .next() - { - is_valid_literal_value(schema, arg_type, &value.item) - } - else { - false - } - }); + let all_types_ok = obj.iter() + .all(|&(ref key, ref value)| { + remaining_required_fields.remove(&key.item); + if let Some(ref arg_type) = + input_fields + .iter() + .filter(|f| f.name == key.item) + .map(|f| schema.make_type(&f.arg_type)) + .next() { + is_valid_literal_value(schema, arg_type, &value.item) + } else { + false + } + }); all_types_ok && remaining_required_fields.is_empty() - } - else { + } else { false } } diff --git a/juniper/src/validation/context.rs b/juniper/src/validation/context.rs index a4f9b541..09d23da1 100644 --- a/juniper/src/validation/context.rs +++ b/juniper/src/validation/context.rs @@ -60,12 +60,13 @@ impl<'a> ValidatorContext<'a> { parent_type_stack: Vec::new(), input_type_stack: Vec::new(), input_type_literal_stack: Vec::new(), - fragment_names: document.iter() + fragment_names: document + .iter() .filter_map(|def| match *def { - Definition::Fragment(ref frag) => Some(frag.item.name.item), - _ => None, - }) - .collect() + Definition::Fragment(ref frag) => Some(frag.item.name.item), + _ => None, + }) + .collect(), } } @@ -86,14 +87,13 @@ impl<'a> ValidatorContext<'a> { } #[doc(hidden)] - pub fn with_pushed_type(&mut self, t: Option<&Type<'a>>, f: F) - -> R + pub fn with_pushed_type(&mut self, t: Option<&Type<'a>>, f: F) -> R where F: FnOnce(&mut ValidatorContext<'a>) -> R { if let Some(t) = t { - self.type_stack.push(self.schema.concrete_type_by_name(t.innermost_name())); - } - else { + self.type_stack + .push(self.schema.concrete_type_by_name(t.innermost_name())); + } else { self.type_stack.push(None); } @@ -108,11 +108,11 @@ impl<'a> ValidatorContext<'a> { } #[doc(hidden)] - pub fn with_pushed_parent_type(&mut self, f: F) - -> R + pub fn with_pushed_parent_type(&mut self, f: F) -> R where F: FnOnce(&mut ValidatorContext<'a>) -> R { - self.parent_type_stack.push(*self.type_stack.last().unwrap_or(&None)); + self.parent_type_stack + .push(*self.type_stack.last().unwrap_or(&None)); let res = f(self); self.parent_type_stack.pop(); @@ -120,14 +120,13 @@ impl<'a> ValidatorContext<'a> { } #[doc(hidden)] - pub fn with_pushed_input_type(&mut self, t: Option<&Type<'a>>, f: F) - -> R + pub fn with_pushed_input_type(&mut self, t: Option<&Type<'a>>, f: F) -> R where F: FnOnce(&mut ValidatorContext<'a>) -> R { if let Some(t) = t { - self.input_type_stack.push(self.schema.concrete_type_by_name(t.innermost_name())); - } - else { + self.input_type_stack + .push(self.schema.concrete_type_by_name(t.innermost_name())); + } else { self.input_type_stack.push(None); } @@ -150,7 +149,7 @@ impl<'a> ValidatorContext<'a> { pub fn current_type_literal(&self) -> Option<&Type<'a>> { match self.type_literal_stack.last() { Some(&Some(ref t)) => Some(t), - _ => None + _ => None, } } diff --git a/juniper/src/validation/input_value.rs b/juniper/src/validation/input_value.rs index 766f2d18..04eccf6d 100644 --- a/juniper/src/validation/input_value.rs +++ b/juniper/src/validation/input_value.rs @@ -15,13 +15,10 @@ enum Path<'a> { ObjectField(&'a str, &'a Path<'a>), } -pub fn validate_input_values( - values: &Variables, - document: &Document, - schema: &SchemaType, -) - -> Vec -{ +pub fn validate_input_values(values: &Variables, + document: &Document, + schema: &SchemaType) + -> Vec { let mut errs = vec![]; for def in document { @@ -36,12 +33,10 @@ pub fn validate_input_values( errs } -fn validate_var_defs( - values: &Variables, - var_defs: &VariableDefinitions, - schema: &SchemaType, - errors: &mut Vec, -) { +fn validate_var_defs(values: &Variables, + var_defs: &VariableDefinitions, + schema: &SchemaType, + errors: &mut Vec) { for &(ref name, ref def) in var_defs.iter() { let raw_type_name = def.var_type.item.innermost_name(); match schema.concrete_type_by_name(raw_type_name) { @@ -49,46 +44,42 @@ fn validate_var_defs( let ct = schema.make_type(&def.var_type.item); if def.var_type.item.is_non_null() && is_absent_or_null(values.get(name.item)) { - errors.push(RuleError::new( - &format!( + errors.push(RuleError::new(&format!( r#"Variable "${}" of required type "{}" was not provided."#, name.item, def.var_type.item, ), - &[ name.start.clone() ], - )); + &[name.start.clone()])); } else if let Some(v) = values.get(name.item) { unify_value(name.item, &name.start, v, &ct, schema, errors, Path::Root); } - }, + } _ => errors.push(RuleError::new( &format!( r#"Variable "${}" expected value of type "{}" which cannot be used as an input type."#, name.item, def.var_type.item, ), &[ name.start.clone() ], - )) + )), } } } -fn unify_value<'a>( - var_name: &str, - var_pos: &SourcePosition, - value: &InputValue, - meta_type: &TypeType<'a>, - schema: &SchemaType, - errors: &mut Vec, - path: Path<'a>, -) { +fn unify_value<'a>(var_name: &str, + var_pos: &SourcePosition, + value: &InputValue, + meta_type: &TypeType<'a>, + schema: &SchemaType, + errors: &mut Vec, + path: Path<'a>) { match *meta_type { TypeType::NonNull(ref inner) => { if value.is_null() { - push_unification_error( - errors, var_name, var_pos, &path, - &format!(r#"Expected "{}", found null"#, meta_type) - ); - } - else { + push_unification_error(errors, + var_name, + var_pos, + &path, + &format!(r#"Expected "{}", found null"#, meta_type)); + } else { unify_value(var_name, var_pos, value, inner, schema, errors, path); } } @@ -99,11 +90,18 @@ fn unify_value<'a>( } match value.to_list_value() { - Some(l) => + Some(l) => { for (i, v) in l.iter().enumerate() { - unify_value(var_name, var_pos, v, inner, schema, errors, Path::ArrayElement(i, &path)); - }, - _ => unify_value(var_name, var_pos, value, inner, schema, errors, path) + unify_value(var_name, + var_pos, + v, + inner, + schema, + errors, + Path::ArrayElement(i, &path)); + } + } + _ => unify_value(var_name, var_pos, value, inner, schema, errors, path), } } @@ -113,76 +111,68 @@ fn unify_value<'a>( } match *mt { - MetaType::Scalar(ref sm) => - unify_scalar(var_name, var_pos, value, sm, errors, &path), - MetaType::Enum(ref em) => - unify_enum(var_name, var_pos, value, em, errors, &path), - MetaType::InputObject(ref iom) => - unify_input_object(var_name, var_pos, value, iom, schema, errors, &path), + MetaType::Scalar(ref sm) => { + unify_scalar(var_name, var_pos, value, sm, errors, &path) + } + MetaType::Enum(ref em) => unify_enum(var_name, var_pos, value, em, errors, &path), + MetaType::InputObject(ref iom) => { + unify_input_object(var_name, var_pos, value, iom, schema, errors, &path) + } _ => panic!("Can't unify non-input concrete type"), } } } } -fn unify_scalar<'a>( - var_name: &str, - var_pos: &SourcePosition, - value: &InputValue, - meta: &ScalarMeta, - errors: &mut Vec, - path: &Path<'a>, -) { +fn unify_scalar<'a>(var_name: &str, + var_pos: &SourcePosition, + value: &InputValue, + meta: &ScalarMeta, + errors: &mut Vec, + path: &Path<'a>) { if !(meta.try_parse_fn)(value) { - push_unification_error( - errors, - var_name, - var_pos, - path, - &format!(r#"Expected "{}""#, meta.name), - ); + push_unification_error(errors, + var_name, + var_pos, + path, + &format!(r#"Expected "{}""#, meta.name)); return; } match *value { - InputValue::List(_) => - push_unification_error( - errors, - var_name, - var_pos, - path, - &format!(r#"Expected "{}", found list"#, meta.name), - ), - InputValue::Object(_) => - push_unification_error( - errors, - var_name, - var_pos, - path, - &format!(r#"Expected "{}", found object"#, meta.name), - ), + InputValue::List(_) => { + push_unification_error(errors, + var_name, + var_pos, + path, + &format!(r#"Expected "{}", found list"#, meta.name)) + } + InputValue::Object(_) => { + push_unification_error(errors, + var_name, + var_pos, + path, + &format!(r#"Expected "{}", found object"#, meta.name)) + } _ => (), } } -fn unify_enum<'a>( - var_name: &str, - var_pos: &SourcePosition, - value: &InputValue, - meta: &EnumMeta, - errors: &mut Vec, - path: &Path<'a>, -) { +fn unify_enum<'a>(var_name: &str, + var_pos: &SourcePosition, + value: &InputValue, + meta: &EnumMeta, + errors: &mut Vec, + path: &Path<'a>) { match *value { - InputValue::String(ref name) | InputValue::Enum(ref name) => { + InputValue::String(ref name) | + InputValue::Enum(ref name) => { if !meta.values.iter().any(|ev| &ev.name == name) { - push_unification_error( - errors, - var_name, - var_pos, - path, - &format!(r#"Invalid value for enum "{}""#, meta.name), - ) + push_unification_error(errors, + var_name, + var_pos, + path, + &format!(r#"Invalid value for enum "{}""#, meta.name)) } } _ => push_unification_error( @@ -191,19 +181,17 @@ fn unify_enum<'a>( var_pos, path, &format!(r#"Expected "{}", found not a string or enum"#, meta.name), - ) + ), } } -fn unify_input_object<'a>( - var_name: &str, - var_pos: &SourcePosition, - value: &InputValue, - meta: &InputObjectMeta, - schema: &SchemaType, - errors: &mut Vec, - path: &Path<'a>, -) { +fn unify_input_object<'a>(var_name: &str, + var_pos: &SourcePosition, + value: &InputValue, + meta: &InputObjectMeta, + schema: &SchemaType, + errors: &mut Vec, + path: &Path<'a>) { if let Some(ref obj) = value.to_object_value() { let mut keys = obj.keys().collect::>(); @@ -215,15 +203,13 @@ fn unify_input_object<'a>( if !value.is_null() { has_value = true; - unify_value( - var_name, - var_pos, - value, - &schema.make_type(&input_field.arg_type), - schema, - errors, - Path::ObjectField(&input_field.name, path), - ); + unify_value(var_name, + var_pos, + value, + &schema.make_type(&input_field.arg_type), + schema, + errors, + Path::ObjectField(&input_field.name, path)); } } @@ -239,23 +225,18 @@ fn unify_input_object<'a>( } for key in keys { - push_unification_error( - errors, - var_name, - var_pos, - &Path::ObjectField(key, path), - "Unknown field", - ); + push_unification_error(errors, + var_name, + var_pos, + &Path::ObjectField(key, path), + "Unknown field"); } - } - else { - push_unification_error( - errors, - var_name, - var_pos, - path, - &format!(r#"Expected "{}", found not an object"#, meta.name), - ); + } else { + push_unification_error(errors, + var_name, + var_pos, + path, + &format!(r#"Expected "{}", found not an object"#, meta.name)); } } @@ -263,20 +244,16 @@ fn is_absent_or_null(v: Option<&InputValue>) -> bool { v.map_or(true, InputValue::is_null) } -fn push_unification_error<'a>( - errors: &mut Vec, - var_name: &str, - var_pos: &SourcePosition, - path: &Path<'a>, - message: &str, -) { - errors.push(RuleError::new( - &format!( +fn push_unification_error<'a>(errors: &mut Vec, + var_name: &str, + var_pos: &SourcePosition, + path: &Path<'a>, + message: &str) { + errors.push(RuleError::new(&format!( r#"Variable "${}" got invalid value. {}{}."#, var_name, path, message, ), - &[ var_pos.clone() ], - )); + &[var_pos.clone()])); } impl<'a> fmt::Display for Path<'a> { diff --git a/juniper/src/validation/mod.rs b/juniper/src/validation/mod.rs index 80b30de2..e2947a63 100644 --- a/juniper/src/validation/mod.rs +++ b/juniper/src/validation/mod.rs @@ -18,6 +18,5 @@ pub use self::multi_visitor::{MultiVisitor, MultiVisitorNil}; pub use self::input_value::validate_input_values; #[cfg(test)] -pub use self::test_harness::{ - expect_passes_rule, expect_fails_rule, - expect_passes_rule_with_schema, expect_fails_rule_with_schema}; +pub use self::test_harness::{expect_passes_rule, expect_fails_rule, + expect_passes_rule_with_schema, expect_fails_rule_with_schema}; diff --git a/juniper/src/validation/multi_visitor.rs b/juniper/src/validation/multi_visitor.rs index c5ba9df7..2f29c5bc 100644 --- a/juniper/src/validation/multi_visitor.rs +++ b/juniper/src/validation/multi_visitor.rs @@ -1,5 +1,5 @@ -use ast::{Document, Operation, Fragment, VariableDefinition, Selection, - Directive, InputValue, Field, FragmentSpread, InlineFragment}; +use ast::{Document, Operation, Fragment, VariableDefinition, Selection, Directive, InputValue, + Field, FragmentSpread, InlineFragment}; use parser::Spanning; use validation::{ValidatorContext, Visitor}; @@ -7,7 +7,9 @@ use validation::{ValidatorContext, Visitor}; pub trait MultiVisitor<'a> { fn visit_all) -> ()>(&mut self, f: F); - fn with>(self, visitor: V) -> MultiVisitorCons where Self: Sized { + fn with>(self, visitor: V) -> MultiVisitorCons + where Self: Sized + { MultiVisitorCons(visitor, self) } } @@ -29,7 +31,9 @@ impl<'a, A: Visitor<'a>, B: MultiVisitor<'a>> MultiVisitor<'a> for MultiVisitorC } } -impl<'a, M> Visitor<'a> for M where M: MultiVisitor<'a> { +impl<'a, M> Visitor<'a> for M + where M: MultiVisitor<'a> +{ fn enter_document(&mut self, ctx: &mut ValidatorContext<'a>, doc: &'a Document) { self.visit_all(|v| v.enter_document(ctx, doc)); } @@ -38,24 +42,36 @@ impl<'a, M> Visitor<'a> for M where M: MultiVisitor<'a> { self.visit_all(|v| v.exit_document(ctx, doc)); } - fn enter_operation_definition(&mut self, ctx: &mut ValidatorContext<'a>, op: &'a Spanning) { + fn enter_operation_definition(&mut self, + ctx: &mut ValidatorContext<'a>, + op: &'a Spanning) { self.visit_all(|v| v.enter_operation_definition(ctx, op)); } - fn exit_operation_definition(&mut self, ctx: &mut ValidatorContext<'a>, op: &'a Spanning) { + fn exit_operation_definition(&mut self, + ctx: &mut ValidatorContext<'a>, + op: &'a Spanning) { self.visit_all(|v| v.exit_operation_definition(ctx, op)); } - fn enter_fragment_definition(&mut self, ctx: &mut ValidatorContext<'a>, f: &'a Spanning) { + fn enter_fragment_definition(&mut self, + ctx: &mut ValidatorContext<'a>, + f: &'a Spanning) { self.visit_all(|v| v.enter_fragment_definition(ctx, f)); } - fn exit_fragment_definition(&mut self, ctx: &mut ValidatorContext<'a>, f: &'a Spanning) { + fn exit_fragment_definition(&mut self, + ctx: &mut ValidatorContext<'a>, + f: &'a Spanning) { self.visit_all(|v| v.exit_fragment_definition(ctx, f)); } - fn enter_variable_definition(&mut self, ctx: &mut ValidatorContext<'a>, def: &'a (Spanning<&'a str>, VariableDefinition)) { + fn enter_variable_definition(&mut self, + ctx: &mut ValidatorContext<'a>, + def: &'a (Spanning<&'a str>, VariableDefinition)) { self.visit_all(|v| v.enter_variable_definition(ctx, def)); } - fn exit_variable_definition(&mut self, ctx: &mut ValidatorContext<'a>, def: &'a (Spanning<&'a str>, VariableDefinition)) { + fn exit_variable_definition(&mut self, + ctx: &mut ValidatorContext<'a>, + def: &'a (Spanning<&'a str>, VariableDefinition)) { self.visit_all(|v| v.exit_variable_definition(ctx, def)); } @@ -66,10 +82,14 @@ impl<'a, M> Visitor<'a> for M where M: MultiVisitor<'a> { self.visit_all(|v| v.exit_directive(ctx, d)); } - fn enter_argument(&mut self, ctx: &mut ValidatorContext<'a>, arg: &'a (Spanning<&'a str>, Spanning)) { + fn enter_argument(&mut self, + ctx: &mut ValidatorContext<'a>, + arg: &'a (Spanning<&'a str>, Spanning)) { self.visit_all(|v| v.enter_argument(ctx, arg)); } - fn exit_argument(&mut self, ctx: &mut ValidatorContext<'a>, arg: &'a (Spanning<&'a str>, Spanning)) { + fn exit_argument(&mut self, + ctx: &mut ValidatorContext<'a>, + arg: &'a (Spanning<&'a str>, Spanning)) { self.visit_all(|v| v.exit_argument(ctx, arg)); } @@ -87,17 +107,25 @@ impl<'a, M> Visitor<'a> for M where M: MultiVisitor<'a> { self.visit_all(|v| v.exit_field(ctx, f)); } - fn enter_fragment_spread(&mut self, ctx: &mut ValidatorContext<'a>, s: &'a Spanning) { + fn enter_fragment_spread(&mut self, + ctx: &mut ValidatorContext<'a>, + s: &'a Spanning) { self.visit_all(|v| v.enter_fragment_spread(ctx, s)); } - fn exit_fragment_spread(&mut self, ctx: &mut ValidatorContext<'a>, s: &'a Spanning) { + fn exit_fragment_spread(&mut self, + ctx: &mut ValidatorContext<'a>, + s: &'a Spanning) { self.visit_all(|v| v.exit_fragment_spread(ctx, s)); } - fn enter_inline_fragment(&mut self, ctx: &mut ValidatorContext<'a>, f: &'a Spanning) { + fn enter_inline_fragment(&mut self, + ctx: &mut ValidatorContext<'a>, + f: &'a Spanning) { self.visit_all(|v| v.enter_inline_fragment(ctx, f)); } - fn exit_inline_fragment(&mut self, ctx: &mut ValidatorContext<'a>, f: &'a Spanning) { + fn exit_inline_fragment(&mut self, + ctx: &mut ValidatorContext<'a>, + f: &'a Spanning) { self.visit_all(|v| v.exit_inline_fragment(ctx, f)); } @@ -150,24 +178,36 @@ impl<'a, M> Visitor<'a> for M where M: MultiVisitor<'a> { self.visit_all(|v| v.exit_variable_value(ctx, s.clone())); } - fn enter_list_value(&mut self, ctx: &mut ValidatorContext<'a>, l: Spanning<&'a Vec>>) { + fn enter_list_value(&mut self, + ctx: &mut ValidatorContext<'a>, + l: Spanning<&'a Vec>>) { self.visit_all(|v| v.enter_list_value(ctx, l.clone())); } - fn exit_list_value(&mut self, ctx: &mut ValidatorContext<'a>, l: Spanning<&'a Vec>>) { + fn exit_list_value(&mut self, + ctx: &mut ValidatorContext<'a>, + l: Spanning<&'a Vec>>) { self.visit_all(|v| v.exit_list_value(ctx, l.clone())); } - fn enter_object_value(&mut self, ctx: &mut ValidatorContext<'a>, o: Spanning<&'a Vec<(Spanning, Spanning)>>) { + fn enter_object_value(&mut self, + ctx: &mut ValidatorContext<'a>, + o: Spanning<&'a Vec<(Spanning, Spanning)>>) { self.visit_all(|v| v.enter_object_value(ctx, o.clone())); } - fn exit_object_value(&mut self, ctx: &mut ValidatorContext<'a>, o: Spanning<&'a Vec<(Spanning, Spanning)>>) { + fn exit_object_value(&mut self, + ctx: &mut ValidatorContext<'a>, + o: Spanning<&'a Vec<(Spanning, Spanning)>>) { self.visit_all(|v| v.exit_object_value(ctx, o.clone())); } - fn enter_object_field(&mut self, ctx: &mut ValidatorContext<'a>, f: &'a (Spanning, Spanning)) { + fn enter_object_field(&mut self, + ctx: &mut ValidatorContext<'a>, + f: &'a (Spanning, Spanning)) { self.visit_all(|v| v.enter_object_field(ctx, f)); } - fn exit_object_field(&mut self, ctx: &mut ValidatorContext<'a>, f: &'a (Spanning, Spanning)) { + fn exit_object_field(&mut self, + ctx: &mut ValidatorContext<'a>, + f: &'a (Spanning, Spanning)) { self.visit_all(|v| v.exit_object_field(ctx, f)); } } diff --git a/juniper/src/validation/rules/arguments_of_correct_type.rs b/juniper/src/validation/rules/arguments_of_correct_type.rs index 03dc9cef..0b64c10b 100644 --- a/juniper/src/validation/rules/arguments_of_correct_type.rs +++ b/juniper/src/validation/rules/arguments_of_correct_type.rs @@ -9,13 +9,13 @@ pub struct ArgumentsOfCorrectType<'a> { } pub fn factory<'a>() -> ArgumentsOfCorrectType<'a> { - ArgumentsOfCorrectType { - current_args: None, - } + ArgumentsOfCorrectType { current_args: None } } impl<'a> Visitor<'a> for ArgumentsOfCorrectType<'a> { - fn enter_directive(&mut self, ctx: &mut ValidatorContext<'a>, directive: &'a Spanning) { + fn enter_directive(&mut self, + ctx: &mut ValidatorContext<'a>, + directive: &'a Spanning) { self.current_args = ctx.schema .directive_by_name(directive.item.name.item) .map(|d| &d.arguments); @@ -35,16 +35,19 @@ impl<'a> Visitor<'a> for ArgumentsOfCorrectType<'a> { self.current_args = None; } - fn enter_argument(&mut self, ctx: &mut ValidatorContext<'a>, &(ref arg_name, ref arg_value): &'a (Spanning<&'a str>, Spanning)) { - if let Some(argument_meta) = self.current_args - .and_then(|args| args.iter().find(|a| a.name == arg_name.item)) - { + fn enter_argument(&mut self, + ctx: &mut ValidatorContext<'a>, + &(ref arg_name, ref arg_value): &'a (Spanning<&'a str>, + Spanning)) { + if let Some(argument_meta) = + self.current_args + .and_then(|args| args.iter().find(|a| a.name == arg_name.item)) { let meta_type = ctx.schema.make_type(&argument_meta.arg_type); if !is_valid_literal_value(ctx.schema, &meta_type, &arg_value.item) { - ctx.report_error( - &error_message(arg_name.item, &format!("{}", argument_meta.arg_type)), - &[arg_value.start.clone()]); + ctx.report_error(&error_message(arg_name.item, + &format!("{}", argument_meta.arg_type)), + &[arg_value.start.clone()]); } } } @@ -66,7 +69,8 @@ mod tests { #[test] fn good_null_value() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { intArgField(intArg: null) @@ -77,23 +81,22 @@ mod tests { #[test] fn null_into_int() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { nonNullIntArgField(nonNullIntArg: null) } } "#, - &[ - RuleError::new(&error_message("nonNullIntArg", "Int!"), &[ - SourcePosition::new(97, 3, 50), - ]) - ]); + &[RuleError::new(&error_message("nonNullIntArg", "Int!"), + &[SourcePosition::new(97, 3, 50)])]); } #[test] fn good_int_value() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { intArgField(intArg: 2) @@ -104,7 +107,8 @@ mod tests { #[test] fn good_boolean_value() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { booleanArgField(booleanArg: true) @@ -115,7 +119,8 @@ mod tests { #[test] fn good_string_value() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { stringArgField(stringArg: "foo") @@ -126,7 +131,8 @@ mod tests { #[test] fn good_float_value() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { floatArgField(floatArg: 1.1) @@ -137,7 +143,8 @@ mod tests { #[test] fn int_into_float() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { floatArgField(floatArg: 1) @@ -148,7 +155,8 @@ mod tests { #[test] fn int_into_id() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { idArgField(idArg: 1) @@ -159,7 +167,8 @@ mod tests { #[test] fn string_into_id() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { idArgField(idArg: "someIdString") @@ -170,7 +179,8 @@ mod tests { #[test] fn good_enum_value() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { dog { doesKnowCommand(dogCommand: SIT) @@ -181,391 +191,344 @@ mod tests { #[test] fn int_into_string() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { stringArgField(stringArg: 1) } } "#, - &[ - RuleError::new(&error_message("stringArg", "String"), &[ - SourcePosition::new(89, 3, 42), - ]) - ]); + &[RuleError::new(&error_message("stringArg", "String"), + &[SourcePosition::new(89, 3, 42)])]); } #[test] fn float_into_string() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { stringArgField(stringArg: 1.0) } } "#, - &[ - RuleError::new(&error_message("stringArg", "String"), &[ - SourcePosition::new(89, 3, 42), - ]) - ]); + &[RuleError::new(&error_message("stringArg", "String"), + &[SourcePosition::new(89, 3, 42)])]); } #[test] fn boolean_into_string() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { stringArgField(stringArg: true) } } "#, - &[ - RuleError::new(&error_message("stringArg", "String"), &[ - SourcePosition::new(89, 3, 42), - ]) - ]); + &[RuleError::new(&error_message("stringArg", "String"), + &[SourcePosition::new(89, 3, 42)])]); } #[test] fn unquoted_string_into_string() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { stringArgField(stringArg: BAR) } } "#, - &[ - RuleError::new(&error_message("stringArg", "String"), &[ - SourcePosition::new(89, 3, 42), - ]) - ]); + &[RuleError::new(&error_message("stringArg", "String"), + &[SourcePosition::new(89, 3, 42)])]); } #[test] fn string_into_int() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { intArgField(intArg: "3") } } "#, - &[ - RuleError::new(&error_message("intArg", "Int"), &[ - SourcePosition::new(83, 3, 36), - ]) - ]); + &[RuleError::new(&error_message("intArg", "Int"), + &[SourcePosition::new(83, 3, 36)])]); } #[test] fn unquoted_string_into_int() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { intArgField(intArg: FOO) } } "#, - &[ - RuleError::new(&error_message("intArg", "Int"), &[ - SourcePosition::new(83, 3, 36), - ]) - ]); + &[RuleError::new(&error_message("intArg", "Int"), + &[SourcePosition::new(83, 3, 36)])]); } #[test] fn simple_float_into_int() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { intArgField(intArg: 3.0) } } "#, - &[ - RuleError::new(&error_message("intArg", "Int"), &[ - SourcePosition::new(83, 3, 36), - ]) - ]); + &[RuleError::new(&error_message("intArg", "Int"), + &[SourcePosition::new(83, 3, 36)])]); } #[test] fn float_into_int() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { intArgField(intArg: 3.333) } } "#, - &[ - RuleError::new(&error_message("intArg", "Int"), &[ - SourcePosition::new(83, 3, 36), - ]) - ]); + &[RuleError::new(&error_message("intArg", "Int"), + &[SourcePosition::new(83, 3, 36)])]); } #[test] fn string_into_float() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { floatArgField(floatArg: "3.333") } } "#, - &[ - RuleError::new(&error_message("floatArg", "Float"), &[ - SourcePosition::new(87, 3, 40), - ]) - ]); + &[RuleError::new(&error_message("floatArg", "Float"), + &[SourcePosition::new(87, 3, 40)])]); } #[test] fn boolean_into_float() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { floatArgField(floatArg: true) } } "#, - &[ - RuleError::new(&error_message("floatArg", "Float"), &[ - SourcePosition::new(87, 3, 40), - ]) - ]); + &[RuleError::new(&error_message("floatArg", "Float"), + &[SourcePosition::new(87, 3, 40)])]); } #[test] fn unquoted_into_float() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { floatArgField(floatArg: FOO) } } "#, - &[ - RuleError::new(&error_message("floatArg", "Float"), &[ - SourcePosition::new(87, 3, 40), - ]) - ]); + &[RuleError::new(&error_message("floatArg", "Float"), + &[SourcePosition::new(87, 3, 40)])]); } #[test] fn int_into_boolean() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { booleanArgField(booleanArg: 2) } } "#, - &[ - RuleError::new(&error_message("booleanArg", "Boolean"), &[ - SourcePosition::new(91, 3, 44), - ]) - ]); + &[RuleError::new(&error_message("booleanArg", "Boolean"), + &[SourcePosition::new(91, 3, 44)])]); } #[test] fn float_into_boolean() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { booleanArgField(booleanArg: 1.0) } } "#, - &[ - RuleError::new(&error_message("booleanArg", "Boolean"), &[ - SourcePosition::new(91, 3, 44), - ]) - ]); + &[RuleError::new(&error_message("booleanArg", "Boolean"), + &[SourcePosition::new(91, 3, 44)])]); } #[test] fn string_into_boolean() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { booleanArgField(booleanArg: "true") } } "#, - &[ - RuleError::new(&error_message("booleanArg", "Boolean"), &[ - SourcePosition::new(91, 3, 44), - ]) - ]); + &[RuleError::new(&error_message("booleanArg", "Boolean"), + &[SourcePosition::new(91, 3, 44)])]); } #[test] fn unquoted_into_boolean() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { booleanArgField(booleanArg: TRUE) } } "#, - &[ - RuleError::new(&error_message("booleanArg", "Boolean"), &[ - SourcePosition::new(91, 3, 44), - ]) - ]); + &[RuleError::new(&error_message("booleanArg", "Boolean"), + &[SourcePosition::new(91, 3, 44)])]); } #[test] fn float_into_id() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { idArgField(idArg: 1.0) } } "#, - &[ - RuleError::new(&error_message("idArg", "ID"), &[ - SourcePosition::new(81, 3, 34), - ]) - ]); + &[RuleError::new(&error_message("idArg", "ID"), + &[SourcePosition::new(81, 3, 34)])]); } #[test] fn boolean_into_id() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { idArgField(idArg: true) } } "#, - &[ - RuleError::new(&error_message("idArg", "ID"), &[ - SourcePosition::new(81, 3, 34), - ]) - ]); + &[RuleError::new(&error_message("idArg", "ID"), + &[SourcePosition::new(81, 3, 34)])]); } #[test] fn unquoted_into_id() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { idArgField(idArg: SOMETHING) } } "#, - &[ - RuleError::new(&error_message("idArg", "ID"), &[ - SourcePosition::new(81, 3, 34), - ]) - ]); + &[RuleError::new(&error_message("idArg", "ID"), + &[SourcePosition::new(81, 3, 34)])]); } #[test] fn int_into_enum() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { dog { doesKnowCommand(dogCommand: 2) } } "#, - &[ - RuleError::new(&error_message("dogCommand", "DogCommand"), &[ - SourcePosition::new(79, 3, 44), - ]) - ]); + &[RuleError::new(&error_message("dogCommand", "DogCommand"), + &[SourcePosition::new(79, 3, 44)])]); } #[test] fn float_into_enum() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { dog { doesKnowCommand(dogCommand: 1.0) } } "#, - &[ - RuleError::new(&error_message("dogCommand", "DogCommand"), &[ - SourcePosition::new(79, 3, 44), - ]) - ]); + &[RuleError::new(&error_message("dogCommand", "DogCommand"), + &[SourcePosition::new(79, 3, 44)])]); } #[test] fn string_into_enum() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { dog { doesKnowCommand(dogCommand: "SIT") } } "#, - &[ - RuleError::new(&error_message("dogCommand", "DogCommand"), &[ - SourcePosition::new(79, 3, 44), - ]) - ]); + &[RuleError::new(&error_message("dogCommand", "DogCommand"), + &[SourcePosition::new(79, 3, 44)])]); } #[test] fn boolean_into_enum() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { dog { doesKnowCommand(dogCommand: true) } } "#, - &[ - RuleError::new(&error_message("dogCommand", "DogCommand"), &[ - SourcePosition::new(79, 3, 44), - ]) - ]); + &[RuleError::new(&error_message("dogCommand", "DogCommand"), + &[SourcePosition::new(79, 3, 44)])]); } #[test] fn unknown_enum_value_into_enum() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { dog { doesKnowCommand(dogCommand: JUGGLE) } } "#, - &[ - RuleError::new(&error_message("dogCommand", "DogCommand"), &[ - SourcePosition::new(79, 3, 44), - ]) - ]); + &[RuleError::new(&error_message("dogCommand", "DogCommand"), + &[SourcePosition::new(79, 3, 44)])]); } #[test] fn different_case_enum_value_into_enum() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { dog { doesKnowCommand(dogCommand: sit) } } "#, - &[ - RuleError::new(&error_message("dogCommand", "DogCommand"), &[ - SourcePosition::new(79, 3, 44), - ]) - ]); + &[RuleError::new(&error_message("dogCommand", "DogCommand"), + &[SourcePosition::new(79, 3, 44)])]); } #[test] fn good_list_value() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { stringListArgField(stringListArg: ["one", "two"]) @@ -576,7 +539,8 @@ mod tests { #[test] fn empty_list_value() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { stringListArgField(stringListArg: []) @@ -587,7 +551,8 @@ mod tests { #[test] fn single_value_into_list() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { stringListArgField(stringListArg: "one") @@ -598,39 +563,36 @@ mod tests { #[test] fn incorrect_item_type() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { stringListArgField(stringListArg: ["one", 2]) } } "#, - &[ - RuleError::new(&error_message("stringListArg", "[String]"), &[ - SourcePosition::new(97, 3, 50), - ]) - ]); + &[RuleError::new(&error_message("stringListArg", "[String]"), + &[SourcePosition::new(97, 3, 50)])]); } #[test] fn single_value_of_incorrect_type() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { stringListArgField(stringListArg: 1) } } "#, - &[ - RuleError::new(&error_message("stringListArg", "[String]"), &[ - SourcePosition::new(97, 3, 50), - ]) - ]); + &[RuleError::new(&error_message("stringListArg", "[String]"), + &[SourcePosition::new(97, 3, 50)])]); } #[test] fn arg_on_optional_arg() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { dog { isHousetrained(atOtherHomes: true) @@ -641,7 +603,8 @@ mod tests { #[test] fn no_arg_on_optional_arg() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { dog { isHousetrained @@ -652,7 +615,8 @@ mod tests { #[test] fn multiple_args() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { multipleReqs(req1: 1, req2: 2) @@ -663,7 +627,8 @@ mod tests { #[test] fn multiple_args_reverse_order() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { multipleReqs(req2: 2, req1: 1) @@ -674,7 +639,8 @@ mod tests { #[test] fn no_args_on_multiple_optional() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { multipleOpts @@ -685,7 +651,8 @@ mod tests { #[test] fn one_arg_on_multiple_optional() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { multipleOpts(opt1: 1) @@ -696,7 +663,8 @@ mod tests { #[test] fn second_arg_on_multiple_optional() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { multipleOpts(opt2: 1) @@ -707,7 +675,8 @@ mod tests { #[test] fn multiple_reqs_on_mixed_list() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { multipleOptAndReq(req1: 3, req2: 4) @@ -718,7 +687,8 @@ mod tests { #[test] fn multiple_reqs_and_one_opt_on_mixed_list() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { multipleOptAndReq(req1: 3, req2: 4, opt1: 5) @@ -729,7 +699,8 @@ mod tests { #[test] fn all_reqs_and_opts_on_mixed_list() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { multipleOptAndReq(req1: 3, req2: 4, opt1: 5, opt2: 6) @@ -740,42 +711,38 @@ mod tests { #[test] fn incorrect_value_type() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { multipleReqs(req2: "two", req1: "one") } } "#, - &[ - RuleError::new(&error_message("req2", "Int!"), &[ - SourcePosition::new(82, 3, 35), - ]), - RuleError::new(&error_message("req1", "Int!"), &[ - SourcePosition::new(95, 3, 48), - ]), - ]); + &[RuleError::new(&error_message("req2", "Int!"), + &[SourcePosition::new(82, 3, 35)]), + RuleError::new(&error_message("req1", "Int!"), + &[SourcePosition::new(95, 3, 48)])]); } #[test] fn incorrect_value_and_missing_argument() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { multipleReqs(req1: "one") } } "#, - &[ - RuleError::new(&error_message("req1", "Int!"), &[ - SourcePosition::new(82, 3, 35), - ]), - ]); + &[RuleError::new(&error_message("req1", "Int!"), + &[SourcePosition::new(82, 3, 35)])]); } #[test] fn optional_arg_despite_required_field_in_type() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { complexArgField @@ -786,7 +753,8 @@ mod tests { #[test] fn partial_object_only_required() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { complexArgField(complexArg: { requiredField: true }) @@ -797,7 +765,8 @@ mod tests { #[test] fn partial_object_required_field_can_be_falsy() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { complexArgField(complexArg: { requiredField: false }) @@ -808,7 +777,8 @@ mod tests { #[test] fn partial_object_including_required() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { complexArgField(complexArg: { requiredField: true, intField: 4 }) @@ -819,7 +789,8 @@ mod tests { #[test] fn full_object() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { complexArgField(complexArg: { @@ -836,7 +807,8 @@ mod tests { #[test] fn full_object_with_fields_in_different_order() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { complexArgField(complexArg: { @@ -853,23 +825,22 @@ mod tests { #[test] fn partial_object_missing_required() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { complexArgField(complexArg: { intField: 4 }) } } "#, - &[ - RuleError::new(&error_message("complexArg", "ComplexInput"), &[ - SourcePosition::new(91, 3, 44), - ]), - ]); + &[RuleError::new(&error_message("complexArg", "ComplexInput"), + &[SourcePosition::new(91, 3, 44)])]); } #[test] fn partial_object_invalid_field_type() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { complexArgField(complexArg: { @@ -879,16 +850,14 @@ mod tests { } } "#, - &[ - RuleError::new(&error_message("complexArg", "ComplexInput"), &[ - SourcePosition::new(91, 3, 44), - ]), - ]); + &[RuleError::new(&error_message("complexArg", "ComplexInput"), + &[SourcePosition::new(91, 3, 44)])]); } #[test] fn partial_object_unknown_field_arg() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { complexArgField(complexArg: { @@ -898,16 +867,14 @@ mod tests { } } "#, - &[ - RuleError::new(&error_message("complexArg", "ComplexInput"), &[ - SourcePosition::new(91, 3, 44), - ]), - ]); + &[RuleError::new(&error_message("complexArg", "ComplexInput"), + &[SourcePosition::new(91, 3, 44)])]); } #[test] fn directive_with_valid_types() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { dog @include(if: true) { name @@ -921,20 +888,17 @@ mod tests { #[test] fn directive_with_incorrect_types() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { dog @include(if: "yes") { name @skip(if: ENUM) } } "#, - &[ - RuleError::new(&error_message("if", "Boolean!"), &[ - SourcePosition::new(38, 2, 27), - ]), - RuleError::new(&error_message("if", "Boolean!"), &[ - SourcePosition::new(74, 3, 27), - ]), - ]); + &[RuleError::new(&error_message("if", "Boolean!"), + &[SourcePosition::new(38, 2, 27)]), + RuleError::new(&error_message("if", "Boolean!"), + &[SourcePosition::new(74, 3, 27)])]); } } 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 7082bfe8..034e0584 100644 --- a/juniper/src/validation/rules/default_values_of_correct_type.rs +++ b/juniper/src/validation/rules/default_values_of_correct_type.rs @@ -3,29 +3,33 @@ use types::utilities::is_valid_literal_value; use parser::Spanning; use validation::{Visitor, ValidatorContext}; -pub struct DefaultValuesOfCorrectType { -} +pub struct DefaultValuesOfCorrectType {} pub fn factory() -> DefaultValuesOfCorrectType { - DefaultValuesOfCorrectType { - } + DefaultValuesOfCorrectType {} } impl<'a> Visitor<'a> for DefaultValuesOfCorrectType { - fn enter_variable_definition(&mut self, ctx: &mut ValidatorContext<'a>, &(ref var_name, ref var_def): &'a (Spanning<&'a str>, VariableDefinition)) { - if let Some(Spanning { item: ref var_value, ref start, .. }) = var_def.default_value { + fn enter_variable_definition(&mut self, + ctx: &mut ValidatorContext<'a>, + &(ref var_name, ref var_def): &'a (Spanning<&'a str>, + VariableDefinition)) { + if let Some(Spanning { + item: ref var_value, + ref start, + .. + }) = var_def.default_value { if var_def.var_type.item.is_non_null() { - ctx.report_error( - &non_null_error_message(var_name.item, &format!("{}", var_def.var_type.item)), - &[start.clone()]) - } - else { + ctx.report_error(&non_null_error_message(var_name.item, + &format!("{}", var_def.var_type.item)), + &[start.clone()]) + } else { let meta_type = ctx.schema.make_type(&var_def.var_type.item); if !is_valid_literal_value(ctx.schema, &meta_type, var_value) { - ctx.report_error( - &type_error_message(var_name.item, &format!("{}", var_def.var_type.item)), - &[start.clone()]); + ctx.report_error(&type_error_message(var_name.item, + &format!("{}", var_def.var_type.item)), + &[start.clone()]); } } } @@ -53,7 +57,8 @@ mod tests { #[test] fn variables_with_no_default_values() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query NullableValues($a: Int, $b: String, $c: ComplexInput) { dog { name } } @@ -62,7 +67,8 @@ mod tests { #[test] fn required_variables_without_default_values() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query RequiredValues($a: Int!, $b: String!) { dog { name } } @@ -71,7 +77,8 @@ mod tests { #[test] fn variables_with_valid_default_values() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query WithDefaultValues( $a: Int = 1, $b: String = "ok", @@ -84,24 +91,22 @@ mod tests { #[test] fn no_required_variables_with_default_values() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query UnreachableDefaultValues($a: Int! = 3, $b: String! = "default") { dog { name } } "#, - &[ - RuleError::new(&non_null_error_message("a", "Int!"), &[ - SourcePosition::new(53, 1, 52), - ]), - RuleError::new(&non_null_error_message("b", "String!"), &[ - SourcePosition::new(70, 1, 69), - ]), - ]); + &[RuleError::new(&non_null_error_message("a", "Int!"), + &[SourcePosition::new(53, 1, 52)]), + RuleError::new(&non_null_error_message("b", "String!"), + &[SourcePosition::new(70, 1, 69)])]); } #[test] fn variables_with_invalid_default_values() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query InvalidDefaultValues( $a: Int = "one", $b: String = 4, @@ -110,45 +115,36 @@ mod tests { dog { name } } "#, - &[ - RuleError::new(&type_error_message("a", "Int"), &[ - SourcePosition::new(61, 2, 22), - ]), - RuleError::new(&type_error_message("b", "String"), &[ - SourcePosition::new(93, 3, 25), - ]), - RuleError::new(&type_error_message("c", "ComplexInput"), &[ - SourcePosition::new(127, 4, 31), - ]), - ]); + &[RuleError::new(&type_error_message("a", "Int"), + &[SourcePosition::new(61, 2, 22)]), + RuleError::new(&type_error_message("b", "String"), + &[SourcePosition::new(93, 3, 25)]), + RuleError::new(&type_error_message("c", "ComplexInput"), + &[SourcePosition::new(127, 4, 31)])]); } #[test] fn complex_variables_missing_required_field() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query MissingRequiredField($a: ComplexInput = {intField: 3}) { 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)])]); } #[test] fn list_variables_with_invalid_item() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query InvalidItem($a: [String] = ["one", 2]) { 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 174d8d53..ad9b3ab3 100644 --- a/juniper/src/validation/rules/fields_on_correct_type.rs +++ b/juniper/src/validation/rules/fields_on_correct_type.rs @@ -16,9 +16,8 @@ impl<'a> Visitor<'a> for FieldsOnCorrectType { let type_name = parent_type.name().unwrap_or(""); if parent_type.field_by_name(field_name.item).is_none() { - context.report_error( - &error_message(field_name.item, type_name), - &[field_name.start.clone()]); + context.report_error(&error_message(field_name.item, type_name), + &[field_name.start.clone()]); } } } @@ -38,7 +37,8 @@ mod tests { #[test] fn selection_on_object() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment objectFieldSelection on Dog { __typename name @@ -48,7 +48,8 @@ mod tests { #[test] fn aliased_selection_on_object() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment aliasedObjectFieldSelection on Dog { tn : __typename otherName : name @@ -58,7 +59,8 @@ mod tests { #[test] fn selection_on_interface() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment interfaceFieldSelection on Pet { __typename name @@ -68,7 +70,8 @@ mod tests { #[test] fn aliased_selection_on_interface() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment interfaceFieldSelection on Pet { otherName : name } @@ -77,7 +80,8 @@ mod tests { #[test] fn lying_alias_selection() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment lyingAliasSelection on Dog { name : nickname } @@ -86,7 +90,8 @@ mod tests { #[test] fn ignores_unknown_type() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment unknownSelection on UnknownType { unknownField } @@ -95,7 +100,8 @@ mod tests { #[test] fn nested_unknown_fields() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment typeKnownAgain on Pet { unknown_pet_field { ... on Cat { @@ -104,137 +110,118 @@ mod tests { } } "#, - &[ - RuleError::new(&error_message("unknown_pet_field", "Pet"), &[ - SourcePosition::new(56, 2, 12) - ]), - RuleError::new(&error_message("unknown_cat_field", "Cat"), &[ - SourcePosition::new(119, 4, 16) - ]), - ]); + &[RuleError::new(&error_message("unknown_pet_field", "Pet"), + &[SourcePosition::new(56, 2, 12)]), + RuleError::new(&error_message("unknown_cat_field", "Cat"), + &[SourcePosition::new(119, 4, 16)])]); } #[test] fn unknown_field_on_fragment() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment fieldNotDefined on Dog { meowVolume } "#, - &[ - RuleError::new(&error_message("meowVolume", "Dog"), &[ - SourcePosition::new(57, 2, 12) - ]), - ]); + &[RuleError::new(&error_message("meowVolume", "Dog"), + &[SourcePosition::new(57, 2, 12)])]); } #[test] fn ignores_deeply_unknown_field() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment deepFieldNotDefined on Dog { unknown_field { deeper_unknown_field } } "#, - &[ - RuleError::new(&error_message("unknown_field", "Dog"), &[ - SourcePosition::new(61, 2, 12) - ]), - ]); + &[RuleError::new(&error_message("unknown_field", "Dog"), + &[SourcePosition::new(61, 2, 12)])]); } #[test] fn unknown_subfield() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment subFieldNotDefined on Human { pets { unknown_field } } "#, - &[ - RuleError::new(&error_message("unknown_field", "Pet"), &[ - SourcePosition::new(83, 3, 14) - ]), - ]); + &[RuleError::new(&error_message("unknown_field", "Pet"), + &[SourcePosition::new(83, 3, 14)])]); } #[test] fn unknown_field_on_inline_fragment() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment fieldNotDefined on Pet { ... on Dog { meowVolume } } "#, - &[ - RuleError::new(&error_message("meowVolume", "Dog"), &[ - SourcePosition::new(84, 3, 14) - ]), - ]); + &[RuleError::new(&error_message("meowVolume", "Dog"), + &[SourcePosition::new(84, 3, 14)])]); } #[test] fn unknown_aliased_target() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment aliasedFieldTargetNotDefined on Dog { volume : mooVolume } "#, - &[ - RuleError::new(&error_message("mooVolume", "Dog"), &[ - SourcePosition::new(79, 2, 21) - ]), - ]); + &[RuleError::new(&error_message("mooVolume", "Dog"), + &[SourcePosition::new(79, 2, 21)])]); } #[test] fn unknown_aliased_lying_field_target() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment aliasedLyingFieldTargetNotDefined on Dog { barkVolume : kawVolume } "#, - &[ - RuleError::new(&error_message("kawVolume", "Dog"), &[ - SourcePosition::new(88, 2, 25) - ]), - ]); + &[RuleError::new(&error_message("kawVolume", "Dog"), + &[SourcePosition::new(88, 2, 25)])]); } #[test] fn not_defined_on_interface() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment notDefinedOnInterface on Pet { tailLength } "#, - &[ - RuleError::new(&error_message("tailLength", "Pet"), &[ - SourcePosition::new(63, 2, 12) - ]), - ]); + &[RuleError::new(&error_message("tailLength", "Pet"), + &[SourcePosition::new(63, 2, 12)])]); } #[test] fn defined_in_concrete_types_but_not_interface() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment definedOnImplementorsButNotInterface on Pet { nickname } "#, - &[ - RuleError::new(&error_message("nickname", "Pet"), &[ - SourcePosition::new(78, 2, 12) - ]), - ]); + &[RuleError::new(&error_message("nickname", "Pet"), + &[SourcePosition::new(78, 2, 12)])]); } #[test] fn meta_field_on_union() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment definedOnImplementorsButNotInterface on Pet { __typename } @@ -243,21 +230,20 @@ mod tests { #[test] fn fields_on_union() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment definedOnImplementorsQueriedOnUnion on CatOrDog { name } "#, - &[ - RuleError::new(&error_message("name", "CatOrDog"), &[ - SourcePosition::new(82, 2, 12) - ]), - ]); + &[RuleError::new(&error_message("name", "CatOrDog"), + &[SourcePosition::new(82, 2, 12)])]); } #[test] fn valid_field_in_inline_fragment() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment objectFieldSelection on Pet { ... on Dog { name diff --git a/juniper/src/validation/rules/fragments_on_composite_types.rs b/juniper/src/validation/rules/fragments_on_composite_types.rs index bb27a162..5caae9eb 100644 --- a/juniper/src/validation/rules/fragments_on_composite_types.rs +++ b/juniper/src/validation/rules/fragments_on_composite_types.rs @@ -9,35 +9,36 @@ pub fn factory() -> FragmentsOnCompositeTypes { } impl<'a> Visitor<'a> for FragmentsOnCompositeTypes { - fn enter_fragment_definition(&mut self, context: &mut ValidatorContext<'a>, f: &'a Spanning) { + fn enter_fragment_definition(&mut self, + context: &mut ValidatorContext<'a>, + f: &'a Spanning) { { if let Some(current_type) = context.current_type() { if !current_type.is_composite() { let type_name = current_type.name().unwrap_or(""); let type_cond = &f.item.type_condition; - context.report_error( - &error_message( - Some(f.item.name.item), - type_name), - &[type_cond.start.clone()]); + context.report_error(&error_message(Some(f.item.name.item), type_name), + &[type_cond.start.clone()]); } } } } - fn enter_inline_fragment(&mut self, context: &mut ValidatorContext<'a>, f: &'a Spanning) { + fn enter_inline_fragment(&mut self, + context: &mut ValidatorContext<'a>, + f: &'a Spanning) { { if let Some(ref type_cond) = f.item.type_condition { - let invalid_type_name = context.current_type().iter() + let invalid_type_name = context + .current_type() + .iter() .filter(|&t| !t.is_composite()) .map(|t| t.name().unwrap_or("")) .next(); if let Some(name) = invalid_type_name { - context.report_error( - &error_message(None, name), - &[type_cond.start.clone()]); + context.report_error(&error_message(None, name), &[type_cond.start.clone()]); } } } @@ -49,8 +50,7 @@ fn error_message(fragment_name: Option<&str>, on_type: &str) -> String { format!( r#"Fragment "{}" cannot condition non composite type "{}"#, name, on_type) - } - else { + } else { format!( r#"Fragment cannot condition on non composite type "{}""#, on_type) @@ -66,7 +66,8 @@ mod tests { #[test] fn on_object() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment validFragment on Dog { barks } @@ -75,7 +76,8 @@ mod tests { #[test] fn on_interface() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment validFragment on Pet { name } @@ -84,7 +86,8 @@ mod tests { #[test] fn on_object_inline() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment validFragment on Pet { ... on Dog { barks @@ -95,7 +98,8 @@ mod tests { #[test] fn on_inline_without_type_cond() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment validFragment on Pet { ... { name @@ -106,7 +110,8 @@ mod tests { #[test] fn on_union() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment validFragment on CatOrDog { __typename } @@ -115,59 +120,51 @@ mod tests { #[test] fn not_on_scalar() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment scalarFragment on Boolean { 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)])]); } #[test] fn not_on_enum() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment scalarFragment on FurColor { 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)])]); } #[test] fn not_on_input_object() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment inputFragment on ComplexInput { 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)])]); } #[test] fn not_on_scalar_inline() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment invalidFragment on Pet { ... on String { barks } } "#, - &[ - 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 cc1d2b0d..0b90cf67 100644 --- a/juniper/src/validation/rules/known_argument_names.rs +++ b/juniper/src/validation/rules/known_argument_names.rs @@ -14,16 +14,17 @@ pub struct KnownArgumentNames<'a> { } pub fn factory<'a>() -> KnownArgumentNames<'a> { - KnownArgumentNames { - current_args: None, - } + KnownArgumentNames { current_args: None } } impl<'a> Visitor<'a> for KnownArgumentNames<'a> { - fn enter_directive(&mut self, ctx: &mut ValidatorContext<'a>, directive: &'a Spanning) { - self.current_args = ctx.schema - .directive_by_name(directive.item.name.item) - .map(|d| (ArgumentPosition::Directive(directive.item.name.item), &d.arguments)); + fn enter_directive(&mut self, + ctx: &mut ValidatorContext<'a>, + directive: &'a Spanning) { + self.current_args = + ctx.schema + .directive_by_name(directive.item.name.item) + .map(|d| (ArgumentPosition::Directive(directive.item.name.item), &d.arguments)); } fn exit_directive(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) { @@ -34,31 +35,35 @@ impl<'a> Visitor<'a> for KnownArgumentNames<'a> { self.current_args = ctx.parent_type() .and_then(|t| t.field_by_name(field.item.name.item)) .and_then(|f| f.arguments.as_ref()) - .map(|args| ( - ArgumentPosition::Field( - field.item.name.item, - ctx.parent_type().expect("Parent type should exist") - .name().expect("Parent type should be named")), - args)); + .map(|args| { + (ArgumentPosition::Field(field.item.name.item, + ctx.parent_type() + .expect("Parent type should exist") + .name() + .expect("Parent type should be named")), + args) + }); } fn exit_field(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) { self.current_args = None; } - fn enter_argument(&mut self, ctx: &mut ValidatorContext<'a>, &(ref arg_name, _): &'a (Spanning<&'a str>, Spanning)) { + fn enter_argument(&mut self, + ctx: &mut ValidatorContext<'a>, + &(ref arg_name, _): &'a (Spanning<&'a str>, Spanning)) { if let Some((ref pos, args)) = self.current_args { if args.iter().find(|a| a.name == arg_name.item).is_none() { let message = match *pos { - ArgumentPosition::Field(field_name, type_name) => - field_error_message(arg_name.item, field_name, type_name), - ArgumentPosition::Directive(directive_name) => - directive_error_message(arg_name.item, directive_name), + ArgumentPosition::Field(field_name, type_name) => { + field_error_message(arg_name.item, field_name, type_name) + } + ArgumentPosition::Directive(directive_name) => { + directive_error_message(arg_name.item, directive_name) + } }; - ctx.report_error( - &message, - &[arg_name.start.clone()]); + ctx.report_error(&message, &[arg_name.start.clone()]); } } } @@ -85,7 +90,8 @@ mod tests { #[test] fn single_arg_is_known() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment argOnRequiredArg on Dog { doesKnowCommand(dogCommand: SIT) } @@ -94,7 +100,8 @@ mod tests { #[test] fn multiple_args_are_known() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment multipleArgs on ComplicatedArgs { multipleReqs(req1: 1, req2: 2) } @@ -103,7 +110,8 @@ mod tests { #[test] fn ignores_args_of_unknown_fields() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment argOnUnknownField on Dog { unknownField(unknownArg: SIT) } @@ -112,7 +120,8 @@ mod tests { #[test] fn multiple_args_in_reverse_order_are_known() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment multipleArgsReverseOrder on ComplicatedArgs { multipleReqs(req2: 2, req1: 1) } @@ -121,7 +130,8 @@ mod tests { #[test] fn no_args_on_optional_arg() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment noArgOnOptionalArg on Dog { isHousetrained } @@ -130,7 +140,8 @@ mod tests { #[test] fn args_are_known_deeply() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { dog { doesKnowCommand(dogCommand: SIT) @@ -148,7 +159,8 @@ mod tests { #[test] fn directive_args_are_known() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { dog @skip(if: true) } @@ -157,52 +169,52 @@ mod tests { #[test] fn undirective_args_are_invalid() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { 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)])]); } #[test] fn invalid_arg_name() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment invalidArgName on Dog { 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)])]); } #[test] fn unknown_args_amongst_known_args() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment oneGoodArgOneInvalidArg on Dog { doesKnowCommand(whoknows: 1, dogCommand: SIT, unknown: true) } "#, - &[ - RuleError::new(&field_error_message("whoknows", "doesKnowCommand", "Dog"), &[ - SourcePosition::new(81, 2, 28), - ]), - RuleError::new(&field_error_message("unknown", "doesKnowCommand", "Dog"), &[ - SourcePosition::new(111, 2, 58), - ]), - ]); + &[RuleError::new(&field_error_message("whoknows", + "doesKnowCommand", + "Dog"), + &[SourcePosition::new(81, 2, 28)]), + RuleError::new(&field_error_message("unknown", + "doesKnowCommand", + "Dog"), + &[SourcePosition::new(111, 2, 58)])]); } #[test] fn unknown_args_deeply() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { dog { doesKnowCommand(unknown: true) @@ -216,13 +228,13 @@ mod tests { } } "#, - &[ - RuleError::new(&field_error_message("unknown", "doesKnowCommand", "Dog"), &[ - SourcePosition::new(61, 3, 30), - ]), - RuleError::new(&field_error_message("unknown", "doesKnowCommand", "Dog"), &[ - SourcePosition::new(193, 8, 34), - ]), - ]); + &[RuleError::new(&field_error_message("unknown", + "doesKnowCommand", + "Dog"), + &[SourcePosition::new(61, 3, 30)]), + RuleError::new(&field_error_message("unknown", + "doesKnowCommand", + "Dog"), + &[SourcePosition::new(193, 8, 34)])]); } } diff --git a/juniper/src/validation/rules/known_directives.rs b/juniper/src/validation/rules/known_directives.rs index 3b70d2db..074a16b0 100644 --- a/juniper/src/validation/rules/known_directives.rs +++ b/juniper/src/validation/rules/known_directives.rs @@ -8,20 +8,23 @@ pub struct KnownDirectives { } pub fn factory() -> KnownDirectives { - KnownDirectives { - location_stack: Vec::new(), - } + KnownDirectives { location_stack: Vec::new() } } impl<'a> Visitor<'a> for KnownDirectives { - fn enter_operation_definition(&mut self, _: &mut ValidatorContext<'a>, op: &'a Spanning) { - self.location_stack.push(match op.item.operation_type { - OperationType::Query => DirectiveLocation::Query, - OperationType::Mutation => DirectiveLocation::Mutation, - }); + fn enter_operation_definition(&mut self, + _: &mut ValidatorContext<'a>, + op: &'a Spanning) { + self.location_stack + .push(match op.item.operation_type { + OperationType::Query => DirectiveLocation::Query, + OperationType::Mutation => DirectiveLocation::Mutation, + }); } - fn exit_operation_definition(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) { + fn exit_operation_definition(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a Spanning) { let top = self.location_stack.pop(); assert!(top == Some(DirectiveLocation::Query) || top == Some(DirectiveLocation::Mutation)); } @@ -35,49 +38,65 @@ impl<'a> Visitor<'a> for KnownDirectives { assert_eq!(top, Some(DirectiveLocation::Field)); } - fn enter_fragment_definition(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) { - self.location_stack.push(DirectiveLocation::FragmentDefinition); + fn enter_fragment_definition(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a Spanning) { + self.location_stack + .push(DirectiveLocation::FragmentDefinition); } - fn exit_fragment_definition(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) { + fn exit_fragment_definition(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a Spanning) { let top = self.location_stack.pop(); assert_eq!(top, Some(DirectiveLocation::FragmentDefinition)); } - fn enter_fragment_spread(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) { + fn enter_fragment_spread(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a Spanning) { self.location_stack.push(DirectiveLocation::FragmentSpread); } - fn exit_fragment_spread(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) { + fn exit_fragment_spread(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a Spanning) { let top = self.location_stack.pop(); assert_eq!(top, Some(DirectiveLocation::FragmentSpread)); } - fn enter_inline_fragment(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) { + fn enter_inline_fragment(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a Spanning) { self.location_stack.push(DirectiveLocation::InlineFragment); } - fn exit_inline_fragment(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) { + fn exit_inline_fragment(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a Spanning) { let top = self.location_stack.pop(); assert_eq!(top, Some(DirectiveLocation::InlineFragment)); } - fn enter_directive(&mut self, ctx: &mut ValidatorContext<'a>, directive: &'a Spanning) { + fn enter_directive(&mut self, + ctx: &mut ValidatorContext<'a>, + directive: &'a Spanning) { let directive_name = &directive.item.name.item; if let Some(directive_type) = ctx.schema.directive_by_name(directive_name) { if let Some(current_location) = self.location_stack.last() { - if directive_type.locations.iter().find(|l| l == ¤t_location).is_none() { - ctx.report_error( - &misplaced_error_message(directive_name, current_location), - &[directive.start.clone()]); + if directive_type + .locations + .iter() + .find(|l| l == ¤t_location) + .is_none() { + ctx.report_error(&misplaced_error_message(directive_name, current_location), + &[directive.start.clone()]); } } - } - else { - ctx.report_error( - &unknown_error_message(directive_name), - &[directive.start.clone()]); + } else { + ctx.report_error(&unknown_error_message(directive_name), + &[directive.start.clone()]); } } } @@ -100,7 +119,8 @@ mod tests { #[test] fn with_no_directives() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo { name ...Frag @@ -114,7 +134,8 @@ mod tests { #[test] fn with_known_directives() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { dog @include(if: true) { name @@ -128,23 +149,22 @@ mod tests { #[test] fn with_unknown_directive() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { dog @unknown(directive: "value") { name } } "#, - &[ - RuleError::new(&unknown_error_message("unknown"), &[ - SourcePosition::new(29, 2, 16), - ]), - ]); + &[RuleError::new(&unknown_error_message("unknown"), + &[SourcePosition::new(29, 2, 16)])]); } #[test] fn with_many_unknown_directives() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { dog @unknown(directive: "value") { name @@ -157,22 +177,18 @@ mod tests { } } "#, - &[ - RuleError::new(&unknown_error_message("unknown"), &[ - SourcePosition::new(29, 2, 16), - ]), - RuleError::new(&unknown_error_message("unknown"), &[ - SourcePosition::new(111, 5, 18), - ]), - RuleError::new(&unknown_error_message("unknown"), &[ - SourcePosition::new(180, 7, 19), - ]), - ]); + &[RuleError::new(&unknown_error_message("unknown"), + &[SourcePosition::new(29, 2, 16)]), + RuleError::new(&unknown_error_message("unknown"), + &[SourcePosition::new(111, 5, 18)]), + RuleError::new(&unknown_error_message("unknown"), + &[SourcePosition::new(180, 7, 19)])]); } #[test] fn with_well_placed_directives() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo @onQuery { name @include(if: true) ...Frag @include(if: true) diff --git a/juniper/src/validation/rules/known_fragment_names.rs b/juniper/src/validation/rules/known_fragment_names.rs index 7fd28ab5..5241cb1b 100644 --- a/juniper/src/validation/rules/known_fragment_names.rs +++ b/juniper/src/validation/rules/known_fragment_names.rs @@ -9,12 +9,13 @@ pub fn factory() -> KnownFragmentNames { } impl<'a> Visitor<'a> for KnownFragmentNames { - fn enter_fragment_spread(&mut self, context: &mut ValidatorContext<'a>, spread: &'a Spanning) { + fn enter_fragment_spread(&mut self, + context: &mut ValidatorContext<'a>, + spread: &'a Spanning) { let spread_name = &spread.item.name; if !context.is_known_fragment(spread_name.item) { - context.report_error( - &error_message(spread_name.item), - &[spread_name.start.clone()]); + context.report_error(&error_message(spread_name.item), + &[spread_name.start.clone()]); } } } @@ -32,7 +33,8 @@ mod tests { #[test] fn known() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { human(id: 4) { ...HumanFields1 @@ -59,7 +61,8 @@ mod tests { #[test] fn unknown() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { human(id: 4) { ...UnknownFragment1 @@ -73,16 +76,11 @@ mod tests { ...UnknownFragment3 } "#, - &[ - RuleError::new(&error_message("UnknownFragment1"), &[ - SourcePosition::new(57, 3, 17), - ]), - RuleError::new(&error_message("UnknownFragment2"), &[ - SourcePosition::new(122, 5, 19), - ]), - RuleError::new(&error_message("UnknownFragment3"), &[ - SourcePosition::new(255, 11, 15), - ]), - ]); + &[RuleError::new(&error_message("UnknownFragment1"), + &[SourcePosition::new(57, 3, 17)]), + RuleError::new(&error_message("UnknownFragment2"), + &[SourcePosition::new(122, 5, 19)]), + RuleError::new(&error_message("UnknownFragment3"), + &[SourcePosition::new(255, 11, 15)])]); } } diff --git a/juniper/src/validation/rules/known_type_names.rs b/juniper/src/validation/rules/known_type_names.rs index 198ddb36..bc36bce0 100644 --- a/juniper/src/validation/rules/known_type_names.rs +++ b/juniper/src/validation/rules/known_type_names.rs @@ -9,18 +9,24 @@ pub fn factory() -> KnownTypeNames { } impl<'a> Visitor<'a> for KnownTypeNames { - fn enter_inline_fragment(&mut self, ctx: &mut ValidatorContext<'a>, fragment: &'a Spanning) { + fn enter_inline_fragment(&mut self, + ctx: &mut ValidatorContext<'a>, + fragment: &'a Spanning) { if let Some(ref type_cond) = fragment.item.type_condition { validate_type(ctx, type_cond.item, &type_cond.start); } } - fn enter_fragment_definition(&mut self, ctx: &mut ValidatorContext<'a>, fragment: &'a Spanning) { + fn enter_fragment_definition(&mut self, + ctx: &mut ValidatorContext<'a>, + fragment: &'a Spanning) { let type_cond = &fragment.item.type_condition; validate_type(ctx, type_cond.item, &type_cond.start); } - fn enter_variable_definition(&mut self, ctx: &mut ValidatorContext<'a>, &(_, ref var_def): &'a (Spanning<&'a str>, VariableDefinition)) { + fn enter_variable_definition(&mut self, + ctx: &mut ValidatorContext<'a>, + &(_, ref var_def): &'a (Spanning<&'a str>, VariableDefinition)) { let type_name = var_def.var_type.item.innermost_name(); validate_type(ctx, type_name, &var_def.var_type.start); } @@ -28,9 +34,7 @@ impl<'a> Visitor<'a> for KnownTypeNames { fn validate_type<'a>(ctx: &mut ValidatorContext<'a>, type_name: &str, location: &SourcePosition) { if ctx.schema.type_by_name(type_name).is_none() { - ctx.report_error( - &error_message(type_name), - &[location.clone()]); + ctx.report_error(&error_message(type_name), &[location.clone()]); } } @@ -47,7 +51,8 @@ mod tests { #[test] fn known_type_names_are_valid() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo($var: String, $required: [String!]!) { user(id: 4) { pets { ... on Pet { name }, ...PetFields, ... { name } } @@ -61,7 +66,8 @@ mod tests { #[test] fn unknown_type_names_are_invalid() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Foo($var: JumbledUpLetters) { user(id: 4) { name @@ -72,16 +78,11 @@ mod tests { name } "#, - &[ - RuleError::new(&error_message("JumbledUpLetters"), &[ - SourcePosition::new(27, 1, 26), - ]), - RuleError::new(&error_message("Badger"), &[ - SourcePosition::new(120, 4, 28), - ]), - RuleError::new(&error_message("Peettt"), &[ - SourcePosition::new(210, 7, 32), - ]), - ]); + &[RuleError::new(&error_message("JumbledUpLetters"), + &[SourcePosition::new(27, 1, 26)]), + RuleError::new(&error_message("Badger"), + &[SourcePosition::new(120, 4, 28)]), + RuleError::new(&error_message("Peettt"), + &[SourcePosition::new(210, 7, 32)])]); } } diff --git a/juniper/src/validation/rules/lone_anonymous_operation.rs b/juniper/src/validation/rules/lone_anonymous_operation.rs index 20d3ceb7..7b6ed420 100644 --- a/juniper/src/validation/rules/lone_anonymous_operation.rs +++ b/juniper/src/validation/rules/lone_anonymous_operation.rs @@ -7,23 +7,22 @@ pub struct LoneAnonymousOperation { } pub fn factory() -> LoneAnonymousOperation { - LoneAnonymousOperation { - operation_count: None, - } + LoneAnonymousOperation { operation_count: None } } impl<'a> Visitor<'a> for LoneAnonymousOperation { fn enter_document(&mut self, _: &mut ValidatorContext<'a>, doc: &'a Document) { - self.operation_count = Some(doc - .iter() - .filter(|d| match **d { - Definition::Operation(_) => true, - Definition::Fragment(_) => false, - }) - .count()); + self.operation_count = Some(doc.iter() + .filter(|d| match **d { + Definition::Operation(_) => true, + Definition::Fragment(_) => false, + }) + .count()); } - fn enter_operation_definition(&mut self, ctx: &mut ValidatorContext<'a>, op: &'a Spanning) { + fn enter_operation_definition(&mut self, + ctx: &mut ValidatorContext<'a>, + op: &'a Spanning) { if let Some(operation_count) = self.operation_count { if operation_count > 1 && op.item.name.is_none() { ctx.report_error(error_message(), &[op.start.clone()]); @@ -45,7 +44,8 @@ mod tests { #[test] fn no_operations() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment fragA on Type { field } @@ -54,7 +54,8 @@ mod tests { #[test] fn one_anon_operation() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { field } @@ -63,7 +64,8 @@ mod tests { #[test] fn multiple_named_operations() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo { field } @@ -76,7 +78,8 @@ mod tests { #[test] fn anon_operation_with_fragment() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { ...Foo } @@ -88,7 +91,8 @@ mod tests { #[test] fn multiple_anon_operations() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { fieldA } @@ -96,19 +100,14 @@ mod tests { fieldB } "#, - &[ - RuleError::new(error_message(), &[ - SourcePosition::new(11, 1, 10), - ]), - RuleError::new(error_message(), &[ - SourcePosition::new(54, 4, 10), - ]), - ]); + &[RuleError::new(error_message(), &[SourcePosition::new(11, 1, 10)]), + RuleError::new(error_message(), &[SourcePosition::new(54, 4, 10)])]); } #[test] fn anon_operation_with_a_mutation() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { fieldA } @@ -116,10 +115,6 @@ 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 23df5fb0..2f959428 100644 --- a/juniper/src/validation/rules/no_fragment_cycles.rs +++ b/juniper/src/validation/rules/no_fragment_cycles.rs @@ -46,7 +46,9 @@ impl<'a> Visitor<'a> for NoFragmentCycles<'a> { ctx.append_errors(detector.errors); } - fn enter_fragment_definition(&mut self, _: &mut ValidatorContext<'a>, fragment: &'a Spanning) { + fn enter_fragment_definition(&mut self, + _: &mut ValidatorContext<'a>, + fragment: &'a Spanning) { assert!(self.current_fragment.is_none()); let fragment_name = &fragment.item.name.item; @@ -54,20 +56,23 @@ impl<'a> Visitor<'a> for NoFragmentCycles<'a> { self.fragment_order.push(fragment_name); } - fn exit_fragment_definition(&mut self, _: &mut ValidatorContext<'a>, fragment: &'a Spanning) { + fn exit_fragment_definition(&mut self, + _: &mut ValidatorContext<'a>, + fragment: &'a Spanning) { assert_eq!(Some(fragment.item.name.item), self.current_fragment); self.current_fragment = None; } - fn enter_fragment_spread(&mut self, _: &mut ValidatorContext<'a>, spread: &'a Spanning) { + fn enter_fragment_spread(&mut self, + _: &mut ValidatorContext<'a>, + spread: &'a Spanning) { if let Some(current_fragment) = self.current_fragment { self.spreads .entry(current_fragment) .or_insert_with(Vec::new) - .push(Spanning::start_end( - &spread.start.clone(), - &spread.end.clone(), - spread.item.name.item)); + .push(Spanning::start_end(&spread.start.clone(), + &spread.end.clone(), + spread.item.name.item)); } } } @@ -88,16 +93,14 @@ impl<'a> CycleDetector<'a> { if let Some(index) = index { let err_pos = if index < path.len() { - path[index] - } else { - node - }; + path[index] + } else { + node + }; - self.errors.push(RuleError::new( - &error_message(name), - &[err_pos.start.clone()])); - } - else if !self.visited.contains(name) { + self.errors + .push(RuleError::new(&error_message(name), &[err_pos.start.clone()])); + } else if !self.visited.contains(name) { path.push(node); self.detect_from(name, path); path.pop(); @@ -121,7 +124,8 @@ mod tests { #[test] fn single_reference_is_valid() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment fragA on Dog { ...fragB } fragment fragB on Dog { name } "#); @@ -129,7 +133,8 @@ mod tests { #[test] fn spreading_twice_is_not_circular() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment fragA on Dog { ...fragB, ...fragB } fragment fragB on Dog { name } "#); @@ -137,7 +142,8 @@ mod tests { #[test] fn spreading_twice_indirectly_is_not_circular() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment fragA on Dog { ...fragB, ...fragC } fragment fragB on Dog { ...fragC } fragment fragC on Dog { name } @@ -146,7 +152,8 @@ mod tests { #[test] fn double_spread_within_abstract_types() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment nameFragment on Pet { ... on Dog { name } ... on Cat { name } @@ -161,7 +168,8 @@ mod tests { #[test] fn does_not_false_positive_on_unknown_fragment() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment nameFragment on Pet { ...UnknownFragment } @@ -170,73 +178,64 @@ mod tests { #[test] fn spreading_recursively_within_field_fails() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + 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)])]); } #[test] fn no_spreading_itself_directly() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + 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)])]); } #[test] fn no_spreading_itself_directly_within_inline_fragment() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment fragA on Pet { ... on Dog { ...fragA } } "#, - &[ - RuleError::new(&error_message("fragA"), &[ - SourcePosition::new(74, 3, 14) - ]), - ]); + &[RuleError::new(&error_message("fragA"), + &[SourcePosition::new(74, 3, 14)])]); } #[test] fn no_spreading_itself_indirectly() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" 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)])]); } #[test] fn no_spreading_itself_indirectly_reports_opposite_order() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" 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)])]); } #[test] fn no_spreading_itself_indirectly_within_inline_fragment() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment fragA on Pet { ... on Dog { ...fragB @@ -248,16 +247,14 @@ mod tests { } } "#, - &[ - RuleError::new(&error_message("fragA"), &[ - SourcePosition::new(74, 3, 14) - ]), - ]); + &[RuleError::new(&error_message("fragA"), + &[SourcePosition::new(74, 3, 14)])]); } #[test] fn no_spreading_itself_deeply() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment fragA on Dog { ...fragB } fragment fragB on Dog { ...fragC } fragment fragC on Dog { ...fragO } @@ -267,67 +264,53 @@ mod tests { fragment fragO on Dog { ...fragP } fragment fragP on Dog { ...fragA, ...fragX } "#, - &[ - RuleError::new(&error_message("fragA"), &[ - SourcePosition::new(35, 1, 34) - ]), - RuleError::new(&error_message("fragO"), &[ - SourcePosition::new(305, 7, 34) - ]), - ]); + &[RuleError::new(&error_message("fragA"), + &[SourcePosition::new(35, 1, 34)]), + RuleError::new(&error_message("fragO"), + &[SourcePosition::new(305, 7, 34)])]); } #[test] fn no_spreading_itself_deeply_two_paths() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment fragA on Dog { ...fragB, ...fragC } fragment fragB on Dog { ...fragA } fragment fragC on Dog { ...fragA } "#, - &[ - RuleError::new(&error_message("fragA"), &[ - SourcePosition::new(35, 1, 34) - ]), - RuleError::new(&error_message("fragA"), &[ - SourcePosition::new(45, 1, 44) - ]), - ]); + &[RuleError::new(&error_message("fragA"), + &[SourcePosition::new(35, 1, 34)]), + RuleError::new(&error_message("fragA"), + &[SourcePosition::new(45, 1, 44)])]); } #[test] fn no_spreading_itself_deeply_two_paths_alt_traversal_order() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment fragA on Dog { ...fragC } fragment fragB on Dog { ...fragC } fragment fragC on Dog { ...fragA, ...fragB } "#, - &[ - RuleError::new(&error_message("fragA"), &[ - SourcePosition::new(35, 1, 34) - ]), - RuleError::new(&error_message("fragC"), &[ - SourcePosition::new(135, 3, 44) - ]), - ]); + &[RuleError::new(&error_message("fragA"), + &[SourcePosition::new(35, 1, 34)]), + RuleError::new(&error_message("fragC"), + &[SourcePosition::new(135, 3, 44)])]); } #[test] fn no_spreading_itself_deeply_and_immediately() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment fragA on Dog { ...fragB } fragment fragB on Dog { ...fragB, ...fragC } fragment fragC on Dog { ...fragA, ...fragB } "#, - &[ - RuleError::new(&error_message("fragA"), &[ - SourcePosition::new(35, 1, 34) - ]), - RuleError::new(&error_message("fragB"), &[ - SourcePosition::new(80, 2, 34) - ]), - RuleError::new(&error_message("fragB"), &[ - SourcePosition::new(90, 2, 44) - ]), - ]); + &[RuleError::new(&error_message("fragA"), + &[SourcePosition::new(35, 1, 34)]), + RuleError::new(&error_message("fragB"), + &[SourcePosition::new(80, 2, 34)]), + RuleError::new(&error_message("fragB"), + &[SourcePosition::new(90, 2, 44)])]); } } diff --git a/juniper/src/validation/rules/no_undefined_variables.rs b/juniper/src/validation/rules/no_undefined_variables.rs index afedc89f..1d927f63 100644 --- a/juniper/src/validation/rules/no_undefined_variables.rs +++ b/juniper/src/validation/rules/no_undefined_variables.rs @@ -26,7 +26,11 @@ pub fn factory<'a>() -> NoUndefinedVariables<'a> { } impl<'a> NoUndefinedVariables<'a> { - fn find_undef_vars(&'a self, scope: &Scope<'a>, defined: &HashSet<&'a str>, unused: &mut Vec<&'a Spanning<&'a str>>, visited: &mut HashSet>) { + fn find_undef_vars(&'a self, + scope: &Scope<'a>, + defined: &HashSet<&'a str>, + unused: &mut Vec<&'a Spanning<&'a str>>, + visited: &mut HashSet>) { if visited.contains(scope) { return; } @@ -54,39 +58,50 @@ impl<'a> Visitor<'a> for NoUndefinedVariables<'a> { for (op_name, &(ref pos, ref def_vars)) in &self.defined_variables { let mut unused = Vec::new(); let mut visited = HashSet::new(); - self.find_undef_vars(&Scope::Operation(*op_name), def_vars, &mut unused, &mut visited); + self.find_undef_vars(&Scope::Operation(*op_name), + def_vars, + &mut unused, + &mut visited); ctx.append_errors(unused - .into_iter() - .map(|var| RuleError::new( - &error_message(var.item, *op_name), - &[ - var.start.clone(), - pos.clone() - ])) - .collect()); + .into_iter() + .map(|var| { + RuleError::new(&error_message(var.item, *op_name), + &[var.start.clone(), pos.clone()]) + }) + .collect()); } } - fn enter_operation_definition(&mut self, _: &mut ValidatorContext<'a>, op: &'a Spanning) { + fn enter_operation_definition(&mut self, + _: &mut ValidatorContext<'a>, + op: &'a Spanning) { let op_name = op.item.name.as_ref().map(|s| s.item); self.current_scope = Some(Scope::Operation(op_name)); - self.defined_variables.insert(op_name, (op.start.clone(), HashSet::new())); + self.defined_variables + .insert(op_name, (op.start.clone(), HashSet::new())); } - fn enter_fragment_definition(&mut self, _: &mut ValidatorContext<'a>, f: &'a Spanning) { + fn enter_fragment_definition(&mut self, + _: &mut ValidatorContext<'a>, + f: &'a Spanning) { self.current_scope = Some(Scope::Fragment(f.item.name.item)); } - fn enter_fragment_spread(&mut self, _: &mut ValidatorContext<'a>, spread: &'a Spanning) { + fn enter_fragment_spread(&mut self, + _: &mut ValidatorContext<'a>, + spread: &'a Spanning) { if let Some(ref scope) = self.current_scope { - self.spreads.entry(scope.clone()) + self.spreads + .entry(scope.clone()) .or_insert_with(Vec::new) .push(spread.item.name.item); } } - fn enter_variable_definition(&mut self, _: &mut ValidatorContext<'a>, &(ref var_name, _): &'a (Spanning<&'a str>, VariableDefinition)) { + fn enter_variable_definition(&mut self, + _: &mut ValidatorContext<'a>, + &(ref var_name, _): &'a (Spanning<&'a str>, VariableDefinition)) { if let Some(Scope::Operation(ref name)) = self.current_scope { if let Some(&mut (_, ref mut vars)) = self.defined_variables.get_mut(name) { vars.insert(var_name.item); @@ -94,19 +109,23 @@ impl<'a> Visitor<'a> for NoUndefinedVariables<'a> { } } - fn enter_argument(&mut self, _: &mut ValidatorContext<'a>, &(_, ref value): &'a (Spanning<&'a str>, Spanning)) { + fn enter_argument(&mut self, + _: &mut ValidatorContext<'a>, + &(_, ref value): &'a (Spanning<&'a str>, Spanning)) { if let Some(ref scope) = self.current_scope { self.used_variables .entry(scope.clone()) .or_insert_with(Vec::new) - .append(&mut value.item - .referenced_variables() - .iter() - .map(|&var_name| Spanning::start_end( - &value.start.clone(), - &value.end.clone(), - var_name)) - .collect()); + .append(&mut value + .item + .referenced_variables() + .iter() + .map(|&var_name| { + Spanning::start_end(&value.start.clone(), + &value.end.clone(), + var_name) + }) + .collect()); } } } @@ -114,8 +133,7 @@ impl<'a> Visitor<'a> for NoUndefinedVariables<'a> { fn error_message(var_name: &str, op_name: Option<&str>) -> String { if let Some(op_name) = op_name { format!(r#"Variable "${}" is not defined by operation "{}""#, var_name, op_name) - } - else { + } else { format!(r#"Variable "${}" is not defined"#, var_name) } } @@ -129,7 +147,8 @@ mod tests { #[test] fn all_variables_defined() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo($a: String, $b: String, $c: String) { field(a: $a, b: $b, c: $c) } @@ -138,7 +157,8 @@ mod tests { #[test] fn all_variables_deeply_defined() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo($a: String, $b: String, $c: String) { field(a: $a) { field(b: $b) { @@ -151,7 +171,8 @@ mod tests { #[test] fn all_variables_deeply_defined_in_inline_fragments_defined() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo($a: String, $b: String, $c: String) { ... on Type { field(a: $a) { @@ -168,7 +189,8 @@ mod tests { #[test] fn all_variables_in_fragments_deeply_defined() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo($a: String, $b: String, $c: String) { ...FragA } @@ -190,7 +212,8 @@ mod tests { #[test] fn variable_within_single_fragment_defined_in_multiple_operations() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo($a: String) { ...FragA } @@ -205,7 +228,8 @@ mod tests { #[test] fn variable_within_fragments_defined_in_operations() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo($a: String) { ...FragA } @@ -223,7 +247,8 @@ mod tests { #[test] fn variable_within_recursive_fragment_defined() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo($a: String) { ...FragA } @@ -237,56 +262,50 @@ mod tests { #[test] fn variable_not_defined() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Foo($a: String, $b: String, $c: String) { 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)])]); } #[test] fn variable_not_defined_by_unnamed_query() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { 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)])]); } #[test] fn multiple_variables_not_defined() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Foo($b: String) { field(a: $a, b: $b, c: $c) } "#, - &[ - RuleError::new(&error_message("a", Some("Foo")), &[ - SourcePosition::new(56, 2, 21), - SourcePosition::new(11, 1, 10), - ]), - RuleError::new(&error_message("c", Some("Foo")), &[ - SourcePosition::new(70, 2, 35), - SourcePosition::new(11, 1, 10), - ]), - ]); + &[RuleError::new(&error_message("a", Some("Foo")), + &[SourcePosition::new(56, 2, 21), + SourcePosition::new(11, 1, 10)]), + RuleError::new(&error_message("c", Some("Foo")), + &[SourcePosition::new(70, 2, 35), + SourcePosition::new(11, 1, 10)])]); } #[test] fn variable_in_fragment_not_defined_by_unnamed_query() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { ...FragA } @@ -294,17 +313,15 @@ 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)])]); } #[test] fn variable_in_fragment_not_defined_by_operation() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Foo($a: String, $b: String) { ...FragA } @@ -322,17 +339,15 @@ 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)])]); } #[test] fn multiple_variables_in_fragments_not_defined() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Foo($b: String) { ...FragA } @@ -350,21 +365,18 @@ mod tests { field(c: $c) } "#, - &[ - RuleError::new(&error_message("a", Some("Foo")), &[ - SourcePosition::new(124, 5, 21), - SourcePosition::new(11, 1, 10), - ]), - RuleError::new(&error_message("c", Some("Foo")), &[ - SourcePosition::new(346, 15, 21), - SourcePosition::new(11, 1, 10), - ]), - ]); + &[RuleError::new(&error_message("a", Some("Foo")), + &[SourcePosition::new(124, 5, 21), + SourcePosition::new(11, 1, 10)]), + RuleError::new(&error_message("c", Some("Foo")), + &[SourcePosition::new(346, 15, 21), + SourcePosition::new(11, 1, 10)])]); } #[test] fn single_variable_in_fragment_not_defined_by_multiple_operations() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Foo($a: String) { ...FragAB } @@ -375,21 +387,18 @@ mod tests { field(a: $a, b: $b) } "#, - &[ - RuleError::new(&error_message("b", Some("Foo")), &[ - SourcePosition::new(201, 8, 28), - SourcePosition::new(11, 1, 10), - ]), - RuleError::new(&error_message("b", Some("Bar")), &[ - SourcePosition::new(201, 8, 28), - SourcePosition::new(79, 4, 10), - ]), - ]); + &[RuleError::new(&error_message("b", Some("Foo")), + &[SourcePosition::new(201, 8, 28), + SourcePosition::new(11, 1, 10)]), + RuleError::new(&error_message("b", Some("Bar")), + &[SourcePosition::new(201, 8, 28), + SourcePosition::new(79, 4, 10)])]); } #[test] fn variables_in_fragment_not_defined_by_multiple_operations() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Foo($b: String) { ...FragAB } @@ -400,21 +409,18 @@ mod tests { field(a: $a, b: $b) } "#, - &[ - RuleError::new(&error_message("a", Some("Foo")), &[ - SourcePosition::new(194, 8, 21), - SourcePosition::new(11, 1, 10), - ]), - RuleError::new(&error_message("b", Some("Bar")), &[ - SourcePosition::new(201, 8, 28), - SourcePosition::new(79, 4, 10), - ]), - ]); + &[RuleError::new(&error_message("a", Some("Foo")), + &[SourcePosition::new(194, 8, 21), + SourcePosition::new(11, 1, 10)]), + RuleError::new(&error_message("b", Some("Bar")), + &[SourcePosition::new(201, 8, 28), + SourcePosition::new(79, 4, 10)])]); } #[test] fn variable_in_fragment_used_by_other_operation() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Foo($b: String) { ...FragA } @@ -428,21 +434,18 @@ mod tests { field(b: $b) } "#, - &[ - RuleError::new(&error_message("a", Some("Foo")), &[ - SourcePosition::new(191, 8, 21), - SourcePosition::new(11, 1, 10), - ]), - RuleError::new(&error_message("b", Some("Bar")), &[ - SourcePosition::new(263, 11, 21), - SourcePosition::new(78, 4, 10), - ]), - ]); + &[RuleError::new(&error_message("a", Some("Foo")), + &[SourcePosition::new(191, 8, 21), + SourcePosition::new(11, 1, 10)]), + RuleError::new(&error_message("b", Some("Bar")), + &[SourcePosition::new(263, 11, 21), + SourcePosition::new(78, 4, 10)])]); } #[test] fn multiple_undefined_variables_produce_multiple_errors() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Foo($b: String) { ...FragAB } @@ -458,31 +461,23 @@ mod tests { field2(c: $c) } "#, - &[ - RuleError::new(&error_message("a", Some("Foo")), &[ - SourcePosition::new(195, 8, 22), - SourcePosition::new(11, 1, 10), - ]), - RuleError::new(&error_message("b", Some("Bar")), &[ - SourcePosition::new(202, 8, 29), - SourcePosition::new(79, 4, 10), - ]), - RuleError::new(&error_message("a", Some("Foo")), &[ - SourcePosition::new(249, 10, 22), - SourcePosition::new(11, 1, 10), - ]), - RuleError::new(&error_message("b", Some("Bar")), &[ - SourcePosition::new(256, 10, 29), - SourcePosition::new(79, 4, 10), - ]), - RuleError::new(&error_message("c", Some("Foo")), &[ - SourcePosition::new(329, 13, 22), - SourcePosition::new(11, 1, 10), - ]), - RuleError::new(&error_message("c", Some("Bar")), &[ - SourcePosition::new(329, 13, 22), - SourcePosition::new(79, 4, 10), - ]), - ]); + &[RuleError::new(&error_message("a", Some("Foo")), + &[SourcePosition::new(195, 8, 22), + SourcePosition::new(11, 1, 10)]), + RuleError::new(&error_message("b", Some("Bar")), + &[SourcePosition::new(202, 8, 29), + SourcePosition::new(79, 4, 10)]), + RuleError::new(&error_message("a", Some("Foo")), + &[SourcePosition::new(249, 10, 22), + SourcePosition::new(11, 1, 10)]), + RuleError::new(&error_message("b", Some("Bar")), + &[SourcePosition::new(256, 10, 29), + SourcePosition::new(79, 4, 10)]), + RuleError::new(&error_message("c", Some("Foo")), + &[SourcePosition::new(329, 13, 22), + SourcePosition::new(11, 1, 10)]), + RuleError::new(&error_message("c", Some("Bar")), + &[SourcePosition::new(329, 13, 22), + SourcePosition::new(79, 4, 10)])]); } } diff --git a/juniper/src/validation/rules/no_unused_fragments.rs b/juniper/src/validation/rules/no_unused_fragments.rs index 03accf08..7584a73a 100644 --- a/juniper/src/validation/rules/no_unused_fragments.rs +++ b/juniper/src/validation/rules/no_unused_fragments.rs @@ -29,8 +29,7 @@ impl<'a> NoUnusedFragments<'a> { if let Scope::Fragment(name) = *from { if result.contains(name) { return; - } - else { + } else { result.insert(name); } } @@ -48,7 +47,7 @@ impl<'a> Visitor<'a> for NoUnusedFragments<'a> { let mut reachable = HashSet::new(); for def in defs { - if let Definition::Operation(Spanning { item: Operation { ref name, .. }, ..}) = *def { + if let Definition::Operation(Spanning { item: Operation { ref name, .. }, .. }) = *def { let op_name = name.as_ref().map(|s| s.item); self.find_reachable_fragments(&Scope::Operation(op_name), &mut reachable); } @@ -56,29 +55,32 @@ impl<'a> Visitor<'a> for NoUnusedFragments<'a> { for fragment in &self.defined_fragments { if !reachable.contains(&fragment.item) { - ctx.report_error( - &error_message(fragment.item), - &[fragment.start.clone()]); + ctx.report_error(&error_message(fragment.item), &[fragment.start.clone()]); } } } - fn enter_operation_definition(&mut self, _: &mut ValidatorContext<'a>, op: &'a Spanning) { + fn enter_operation_definition(&mut self, + _: &mut ValidatorContext<'a>, + op: &'a Spanning) { let op_name = op.item.name.as_ref().map(|s| s.item.as_ref()); self.current_scope = Some(Scope::Operation(op_name)); } - fn enter_fragment_definition(&mut self, _: &mut ValidatorContext<'a>, f: &'a Spanning) { + fn enter_fragment_definition(&mut self, + _: &mut ValidatorContext<'a>, + f: &'a Spanning) { self.current_scope = Some(Scope::Fragment(f.item.name.item)); - self.defined_fragments.insert(Spanning::start_end( - &f.start, - &f.end, - f.item.name.item)); + self.defined_fragments + .insert(Spanning::start_end(&f.start, &f.end, f.item.name.item)); } - fn enter_fragment_spread(&mut self, _: &mut ValidatorContext<'a>, spread: &'a Spanning) { + fn enter_fragment_spread(&mut self, + _: &mut ValidatorContext<'a>, + spread: &'a Spanning) { if let Some(ref scope) = self.current_scope { - self.spreads.entry(scope.clone()) + self.spreads + .entry(scope.clone()) .or_insert_with(Vec::new) .push(spread.item.name.item); } @@ -98,7 +100,8 @@ mod tests { #[test] fn all_fragment_names_are_used() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { human(id: 4) { ...HumanFields1 @@ -122,7 +125,8 @@ mod tests { #[test] fn all_fragment_names_are_used_by_multiple_operations() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo { human(id: 4) { ...HumanFields1 @@ -148,7 +152,8 @@ mod tests { #[test] fn contains_unknown_fragments() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Foo { human(id: 4) { ...HumanFields1 @@ -176,19 +181,16 @@ mod tests { name } "#, - &[ - RuleError::new(&error_message("Unused1"), &[ - SourcePosition::new(465, 21, 10), - ]), - RuleError::new(&error_message("Unused2"), &[ - SourcePosition::new(532, 24, 10), - ]), - ]); + &[RuleError::new(&error_message("Unused1"), + &[SourcePosition::new(465, 21, 10)]), + RuleError::new(&error_message("Unused2"), + &[SourcePosition::new(532, 24, 10)])]); } #[test] fn contains_unknown_fragments_with_ref_cycle() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Foo { human(id: 4) { ...HumanFields1 @@ -218,19 +220,16 @@ mod tests { ...Unused1 } "#, - &[ - RuleError::new(&error_message("Unused1"), &[ - SourcePosition::new(465, 21, 10), - ]), - RuleError::new(&error_message("Unused2"), &[ - SourcePosition::new(555, 25, 10), - ]), - ]); + &[RuleError::new(&error_message("Unused1"), + &[SourcePosition::new(465, 21, 10)]), + RuleError::new(&error_message("Unused2"), + &[SourcePosition::new(555, 25, 10)])]); } #[test] fn contains_unknown_and_undef_fragments() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Foo { human(id: 4) { ...bar @@ -240,10 +239,7 @@ 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 d378280b..f55e6428 100644 --- a/juniper/src/validation/rules/no_unused_variables.rs +++ b/juniper/src/validation/rules/no_unused_variables.rs @@ -26,7 +26,11 @@ pub fn factory<'a>() -> NoUnusedVariables<'a> { } impl<'a> NoUnusedVariables<'a> { - fn find_used_vars(&self, from: &Scope<'a>, defined: &HashSet<&'a str>, used: &mut HashSet<&'a str>, visited: &mut HashSet>) { + fn find_used_vars(&self, + from: &Scope<'a>, + defined: &HashSet<&'a str>, + used: &mut HashSet<&'a str>, + visited: &mut HashSet>) { if visited.contains(from) { return; } @@ -54,41 +58,50 @@ impl<'a> Visitor<'a> for NoUnusedVariables<'a> { for (op_name, def_vars) in &self.defined_variables { let mut used = HashSet::new(); let mut visited = HashSet::new(); - self.find_used_vars( - &Scope::Operation(*op_name), - &def_vars.iter().map(|def| def.item).collect(), - &mut used, - &mut visited); + self.find_used_vars(&Scope::Operation(*op_name), + &def_vars.iter().map(|def| def.item).collect(), + &mut used, + &mut visited); ctx.append_errors(def_vars - .iter() - .filter(|var| !used.contains(var.item)) - .map(|var| RuleError::new( - &error_message(var.item, *op_name), - &[var.start.clone()])) - .collect()); + .iter() + .filter(|var| !used.contains(var.item)) + .map(|var| { + RuleError::new(&error_message(var.item, *op_name), + &[var.start.clone()]) + }) + .collect()); } } - fn enter_operation_definition(&mut self, _: &mut ValidatorContext<'a>, op: &'a Spanning) { + fn enter_operation_definition(&mut self, + _: &mut ValidatorContext<'a>, + op: &'a Spanning) { let op_name = op.item.name.as_ref().map(|s| s.item); self.current_scope = Some(Scope::Operation(op_name)); self.defined_variables.insert(op_name, HashSet::new()); } - fn enter_fragment_definition(&mut self, _: &mut ValidatorContext<'a>, f: &'a Spanning) { + fn enter_fragment_definition(&mut self, + _: &mut ValidatorContext<'a>, + f: &'a Spanning) { self.current_scope = Some(Scope::Fragment(f.item.name.item)); } - fn enter_fragment_spread(&mut self, _: &mut ValidatorContext<'a>, spread: &'a Spanning) { + fn enter_fragment_spread(&mut self, + _: &mut ValidatorContext<'a>, + spread: &'a Spanning) { if let Some(ref scope) = self.current_scope { - self.spreads.entry(scope.clone()) + self.spreads + .entry(scope.clone()) .or_insert_with(Vec::new) .push(spread.item.name.item); } } - fn enter_variable_definition(&mut self, _: &mut ValidatorContext<'a>, &(ref var_name, _): &'a (Spanning<&'a str>, VariableDefinition)) { + fn enter_variable_definition(&mut self, + _: &mut ValidatorContext<'a>, + &(ref var_name, _): &'a (Spanning<&'a str>, VariableDefinition)) { if let Some(Scope::Operation(ref name)) = self.current_scope { if let Some(vars) = self.defined_variables.get_mut(name) { vars.insert(var_name); @@ -96,7 +109,9 @@ impl<'a> Visitor<'a> for NoUnusedVariables<'a> { } } - fn enter_argument(&mut self, _: &mut ValidatorContext<'a>, &(_, ref value): &'a (Spanning<&'a str>, Spanning)) { + fn enter_argument(&mut self, + _: &mut ValidatorContext<'a>, + &(_, ref value): &'a (Spanning<&'a str>, Spanning)) { if let Some(ref scope) = self.current_scope { self.used_variables .entry(scope.clone()) @@ -109,8 +124,7 @@ impl<'a> Visitor<'a> for NoUnusedVariables<'a> { fn error_message(var_name: &str, op_name: Option<&str>) -> String { if let Some(op_name) = op_name { format!(r#"Variable "${}" is not defined by operation "{}""#, var_name, op_name) - } - else { + } else { format!(r#"Variable "${}" is not defined"#, var_name) } } @@ -124,7 +138,8 @@ mod tests { #[test] fn uses_all_variables() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query ($a: String, $b: String, $c: String) { field(a: $a, b: $b, c: $c) } @@ -133,7 +148,8 @@ mod tests { #[test] fn uses_all_variables_deeply() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo($a: String, $b: String, $c: String) { field(a: $a) { field(b: $b) { @@ -146,7 +162,8 @@ mod tests { #[test] fn uses_all_variables_deeply_in_inline_fragments() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo($a: String, $b: String, $c: String) { ... on Type { field(a: $a) { @@ -163,7 +180,8 @@ mod tests { #[test] fn uses_all_variables_in_fragments() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo($a: String, $b: String, $c: String) { ...FragA } @@ -185,7 +203,8 @@ mod tests { #[test] fn variable_used_by_fragment_in_multiple_operations() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo($a: String) { ...FragA } @@ -203,7 +222,8 @@ mod tests { #[test] fn variable_used_by_recursive_fragment() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo($a: String) { ...FragA } @@ -217,38 +237,34 @@ mod tests { #[test] fn variable_not_used() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query ($a: String, $b: String, $c: String) { 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)])]); } #[test] fn multiple_variables_not_used_1() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Foo($a: String, $b: String, $c: String) { field(b: $b) } "#, - &[ - RuleError::new(&error_message("a", Some("Foo")), &[ - SourcePosition::new(21, 1, 20), - ]), - RuleError::new(&error_message("c", Some("Foo")), &[ - SourcePosition::new(45, 1, 44), - ]), - ]); + &[RuleError::new(&error_message("a", Some("Foo")), + &[SourcePosition::new(21, 1, 20)]), + RuleError::new(&error_message("c", Some("Foo")), + &[SourcePosition::new(45, 1, 44)])]); } #[test] fn variable_not_used_in_fragment() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Foo($a: String, $b: String, $c: String) { ...FragA } @@ -266,16 +282,14 @@ 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)])]); } #[test] fn multiple_variables_not_used_2() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Foo($a: String, $b: String, $c: String) { ...FragA } @@ -293,19 +307,16 @@ mod tests { field } "#, - &[ - RuleError::new(&error_message("a", Some("Foo")), &[ - SourcePosition::new(21, 1, 20), - ]), - RuleError::new(&error_message("c", Some("Foo")), &[ - SourcePosition::new(45, 1, 44), - ]), - ]); + &[RuleError::new(&error_message("a", Some("Foo")), + &[SourcePosition::new(21, 1, 20)]), + RuleError::new(&error_message("c", Some("Foo")), + &[SourcePosition::new(45, 1, 44)])]); } #[test] fn variable_not_used_by_unreferenced_fragment() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Foo($b: String) { ...FragA } @@ -316,16 +327,14 @@ 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)])]); } #[test] fn variable_not_used_by_fragment_used_by_other_operation() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Foo($b: String) { ...FragA } @@ -339,13 +348,9 @@ mod tests { field(b: $b) } "#, - &[ - RuleError::new(&error_message("b", Some("Foo")), &[ - SourcePosition::new(21, 1, 20), - ]), - RuleError::new(&error_message("a", Some("Bar")), &[ - SourcePosition::new(88, 4, 20), - ]), - ]); + &[RuleError::new(&error_message("b", Some("Foo")), + &[SourcePosition::new(21, 1, 20)]), + RuleError::new(&error_message("a", Some("Bar")), + &[SourcePosition::new(88, 4, 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 b6ee584b..b3645f31 100644 --- a/juniper/src/validation/rules/overlapping_fields_can_be_merged.rs +++ b/juniper/src/validation/rules/overlapping_fields_can_be_merged.rs @@ -35,7 +35,7 @@ struct OrderedMap { struct OrderedMapIter<'a, K: 'a, V: 'a> { map: &'a HashMap, - inner: ::std::slice::Iter<'a, K> + inner: ::std::slice::Iter<'a, K>, } impl OrderedMap { @@ -53,15 +53,24 @@ impl OrderedMap { } } - fn get(&self, k: &Q) -> Option<&V> where K: Borrow, Q: Hash + Eq { + fn get(&self, k: &Q) -> Option<&V> + where K: Borrow, + Q: Hash + Eq + { self.data.get(k) } - fn get_mut(&mut self, k: &Q) -> Option<&mut V> where K: Borrow, Q: Hash + Eq { + fn get_mut(&mut self, k: &Q) -> Option<&mut V> + where K: Borrow, + Q: Hash + Eq + { self.data.get_mut(k) } - fn contains_key(&self, k: &Q) -> bool where K: Borrow, Q: Hash + Eq { + fn contains_key(&self, k: &Q) -> bool + where K: Borrow, + Q: Hash + Eq + { self.data.contains_key(k) } @@ -78,38 +87,33 @@ impl<'a, K: Eq + Hash + 'a, V: 'a> Iterator for OrderedMapIter<'a, K, V> { type Item = (&'a K, &'a V); fn next(&mut self) -> Option { - self.inner.next() + self.inner + .next() .and_then(|key| self.map.get(key).map(|value| (key, value))) } } impl<'a> PairSet<'a> { fn new() -> PairSet<'a> { - PairSet { - data: HashMap::new(), - } + PairSet { data: HashMap::new() } } fn contains(&self, a: &'a str, b: &'a str, mutex: bool) -> bool { if let Some(result) = self.data.get(a).and_then(|s| s.get(b)) { - if !mutex { - !result - } - else { - true - } - } - else { + if !mutex { !result } else { true } + } else { false } } fn insert(&mut self, a: &'a str, b: &'a str, mutex: bool) { - self.data.entry(a) + self.data + .entry(a) .or_insert_with(HashMap::new) .insert(b, mutex); - self.data.entry(b) + self.data + .entry(b) .or_insert_with(HashMap::new) .insert(a, mutex); } @@ -128,50 +132,43 @@ pub fn factory<'a>() -> OverlappingFieldsCanBeMerged<'a> { } impl<'a> OverlappingFieldsCanBeMerged<'a> { - fn find_conflicts_within_selection_set( - &self, - parent_type: Option<&'a MetaType>, - selection_set: &'a [Selection], - ctx: &ValidatorContext<'a>, - ) - -> Vec - { + fn find_conflicts_within_selection_set(&self, + parent_type: Option<&'a MetaType>, + selection_set: &'a [Selection], + ctx: &ValidatorContext<'a>) + -> Vec { let mut conflicts = Vec::new(); - let (field_map, fragment_names) = self.get_fields_and_fragment_names(parent_type, selection_set, ctx); + let (field_map, fragment_names) = + self.get_fields_and_fragment_names(parent_type, selection_set, ctx); self.collect_conflicts_within(&mut conflicts, &field_map, ctx); for (i, frag_name1) in fragment_names.iter().enumerate() { - self.collect_conflicts_between_fields_and_fragment( - &mut conflicts, - &field_map, - frag_name1, - false, - ctx); + self.collect_conflicts_between_fields_and_fragment(&mut conflicts, + &field_map, + frag_name1, + false, + ctx); - for frag_name2 in &fragment_names[i+1..] { - self.collect_conflicts_between_fragments( - &mut conflicts, - frag_name1, - frag_name2, - false, - ctx); + for frag_name2 in &fragment_names[i + 1..] { + self.collect_conflicts_between_fragments(&mut conflicts, + frag_name1, + frag_name2, + false, + ctx); } } conflicts } - fn collect_conflicts_between_fragments( - &self, - conflicts: &mut Vec, - fragment_name1: &'a str, - fragment_name2: &'a str, - mutually_exclusive: bool, - ctx: &ValidatorContext<'a>, - ) - { + fn collect_conflicts_between_fragments(&self, + conflicts: &mut Vec, + fragment_name1: &'a str, + fragment_name2: &'a str, + mutually_exclusive: bool, + ctx: &ValidatorContext<'a>) { if fragment_name1 == fragment_name2 { return; } @@ -187,91 +184,87 @@ impl<'a> OverlappingFieldsCanBeMerged<'a> { }; { - if self.compared_fragments.borrow().contains(fragment_name1, fragment_name2, mutually_exclusive) { + if self.compared_fragments + .borrow() + .contains(fragment_name1, fragment_name2, mutually_exclusive) { return; } } { - self.compared_fragments.borrow_mut().insert(fragment_name1, fragment_name2, mutually_exclusive); + self.compared_fragments + .borrow_mut() + .insert(fragment_name1, fragment_name2, mutually_exclusive); } - let (field_map1, fragment_names1) = self.get_referenced_fields_and_fragment_names(fragment1, ctx); - let (field_map2, fragment_names2) = self.get_referenced_fields_and_fragment_names(fragment2, ctx); + let (field_map1, fragment_names1) = + self.get_referenced_fields_and_fragment_names(fragment1, ctx); + let (field_map2, fragment_names2) = + self.get_referenced_fields_and_fragment_names(fragment2, ctx); - self.collect_conflicts_between( - conflicts, - mutually_exclusive, - &field_map1, - &field_map2, - ctx); + self.collect_conflicts_between(conflicts, + mutually_exclusive, + &field_map1, + &field_map2, + ctx); for fragment_name2 in &fragment_names2 { - self.collect_conflicts_between_fragments( - conflicts, - fragment_name1, - fragment_name2, - mutually_exclusive, - ctx); + self.collect_conflicts_between_fragments(conflicts, + fragment_name1, + fragment_name2, + mutually_exclusive, + ctx); } for fragment_name1 in &fragment_names1 { - self.collect_conflicts_between_fragments( - conflicts, - fragment_name1, - fragment_name2, - mutually_exclusive, - ctx); + self.collect_conflicts_between_fragments(conflicts, + fragment_name1, + fragment_name2, + mutually_exclusive, + ctx); } } - fn collect_conflicts_between_fields_and_fragment( - &self, - conflicts: &mut Vec, - field_map: &AstAndDefCollection<'a>, - fragment_name: &str, - mutually_exclusive: bool, - ctx: &ValidatorContext<'a>, - ) - { + fn collect_conflicts_between_fields_and_fragment(&self, + conflicts: &mut Vec, + field_map: &AstAndDefCollection<'a>, + fragment_name: &str, + mutually_exclusive: bool, + ctx: &ValidatorContext<'a>) { let fragment = match self.named_fragments.get(fragment_name) { Some(f) => f, None => return, }; - let (field_map2, fragment_names2) = self.get_referenced_fields_and_fragment_names(fragment, ctx); + let (field_map2, fragment_names2) = + self.get_referenced_fields_and_fragment_names(fragment, ctx); - self.collect_conflicts_between( - conflicts, - mutually_exclusive, - field_map, - &field_map2, - ctx); + self.collect_conflicts_between(conflicts, mutually_exclusive, field_map, &field_map2, ctx); for fragment_name2 in fragment_names2 { - self.collect_conflicts_between_fields_and_fragment( - conflicts, - field_map, - fragment_name2, - mutually_exclusive, - ctx); + self.collect_conflicts_between_fields_and_fragment(conflicts, + field_map, + fragment_name2, + mutually_exclusive, + ctx); } } - fn collect_conflicts_between( - &self, - conflicts: &mut Vec, - mutually_exclusive: bool, - field_map1: &AstAndDefCollection<'a>, - field_map2: &AstAndDefCollection<'a>, - ctx: &ValidatorContext<'a>, - ) - { + fn collect_conflicts_between(&self, + conflicts: &mut Vec, + mutually_exclusive: bool, + field_map1: &AstAndDefCollection<'a>, + field_map2: &AstAndDefCollection<'a>, + ctx: &ValidatorContext<'a>) { for (response_name, fields1) in field_map1.iter() { if let Some(fields2) = field_map2.get(response_name) { for field1 in fields1 { for field2 in fields2 { - if let Some(conflict) = self.find_conflict(response_name, field1, field2, mutually_exclusive, ctx) { + if let Some(conflict) = self.find_conflict(response_name, + field1, + field2, + mutually_exclusive, + ctx) { conflicts.push(conflict); } } @@ -280,17 +273,18 @@ impl<'a> OverlappingFieldsCanBeMerged<'a> { } } - fn collect_conflicts_within( - &self, - conflicts: &mut Vec, - field_map: &AstAndDefCollection<'a>, - ctx: &ValidatorContext<'a>, - ) - { + fn collect_conflicts_within(&self, + conflicts: &mut Vec, + field_map: &AstAndDefCollection<'a>, + ctx: &ValidatorContext<'a>) { for (response_name, fields) in field_map.iter() { for (i, field1) in fields.iter().enumerate() { - for field2 in &fields[i+1..] { - if let Some(conflict) = self.find_conflict(response_name, field1, field2, false, ctx) { + for field2 in &fields[i + 1..] { + if let Some(conflict) = self.find_conflict(response_name, + field1, + field2, + false, + ctx) { conflicts.push(conflict); } } @@ -298,36 +292,31 @@ impl<'a> OverlappingFieldsCanBeMerged<'a> { } } - fn find_conflict( - &self, - response_name: &str, - field1: &AstAndDef<'a>, - field2: &AstAndDef<'a>, - parents_mutually_exclusive: bool, - ctx: &ValidatorContext<'a>, - ) - -> Option - { + fn find_conflict(&self, + response_name: &str, + field1: &AstAndDef<'a>, + field2: &AstAndDef<'a>, + parents_mutually_exclusive: bool, + ctx: &ValidatorContext<'a>) + -> Option { let AstAndDef(ref parent_type1, ast1, ref def1) = *field1; let AstAndDef(ref parent_type2, ast2, ref def2) = *field2; - let mutually_exclusive = parents_mutually_exclusive - || (parent_type1 != parent_type2 - && self.is_object_type(ctx, *parent_type1) - && self.is_object_type(ctx, *parent_type2)); + let mutually_exclusive = parents_mutually_exclusive || + (parent_type1 != parent_type2 && + self.is_object_type(ctx, *parent_type1) && + self.is_object_type(ctx, *parent_type2)); if !mutually_exclusive { let name1 = &ast1.item.name.item; let name2 = &ast2.item.name.item; if name1 != name2 { - return Some(Conflict( - ConflictReason( - response_name.to_owned(), - ConflictReasonMessage::Message(format!( + return Some(Conflict(ConflictReason(response_name.to_owned(), + ConflictReasonMessage::Message(format!( "{} and {} are different fields", name1, name2))), - vec![ast1.start.clone()], - vec![ast2.start.clone()])); + vec![ast1.start.clone()], + vec![ast2.start.clone()])); } if !self.is_same_arguments(&ast1.item.arguments, &ast2.item.arguments) { @@ -346,141 +335,129 @@ impl<'a> OverlappingFieldsCanBeMerged<'a> { if let (Some(t1), Some(t2)) = (t1, t2) { if self.is_type_conflict(ctx, t1, t2) { - return Some(Conflict( - ConflictReason( - response_name.to_owned(), - ConflictReasonMessage::Message(format!( + return Some(Conflict(ConflictReason(response_name.to_owned(), + ConflictReasonMessage::Message(format!( "they return conflicting types {} and {}", t1, t2))), - vec![ast1.start.clone()], - vec![ast2.start.clone()])); + vec![ast1.start.clone()], + vec![ast2.start.clone()])); } } - if let (&Some(ref s1), &Some(ref s2)) = (&ast1.item.selection_set, &ast2.item.selection_set) { - let conflicts = self.find_conflicts_between_sub_selection_sets( - mutually_exclusive, - t1.map(|t| t.innermost_name()), - s1, - t2.map(|t| t.innermost_name()), - s2, - ctx); + if let (&Some(ref s1), &Some(ref s2)) = + (&ast1.item.selection_set, &ast2.item.selection_set) { + let conflicts = + self.find_conflicts_between_sub_selection_sets(mutually_exclusive, + t1.map(|t| t.innermost_name()), + s1, + t2.map(|t| t.innermost_name()), + s2, + ctx); - return self.subfield_conflicts( - &conflicts, - response_name, - &ast1.start, - &ast2.start); + return self.subfield_conflicts(&conflicts, response_name, &ast1.start, &ast2.start); } None } - fn find_conflicts_between_sub_selection_sets( - &self, - mutually_exclusive: bool, - parent_type1: Option<&str>, - selection_set1: &'a [Selection], - parent_type2: Option<&str>, - selection_set2: &'a [Selection], - ctx: &ValidatorContext<'a>, - ) - -> Vec - { + fn find_conflicts_between_sub_selection_sets(&self, + mutually_exclusive: bool, + parent_type1: Option<&str>, + selection_set1: &'a [Selection], + parent_type2: Option<&str>, + selection_set2: &'a [Selection], + ctx: &ValidatorContext<'a>) + -> Vec { let mut conflicts = Vec::new(); let parent_type1 = parent_type1.and_then(|t| ctx.schema.concrete_type_by_name(t)); let parent_type2 = parent_type2.and_then(|t| ctx.schema.concrete_type_by_name(t)); - let (field_map1, fragment_names1) = self.get_fields_and_fragment_names(parent_type1, selection_set1, ctx); - let (field_map2, fragment_names2) = self.get_fields_and_fragment_names(parent_type2, selection_set2, ctx); + let (field_map1, fragment_names1) = + self.get_fields_and_fragment_names(parent_type1, selection_set1, ctx); + let (field_map2, fragment_names2) = + self.get_fields_and_fragment_names(parent_type2, selection_set2, ctx); - self.collect_conflicts_between( - &mut conflicts, - mutually_exclusive, - &field_map1, - &field_map2, - ctx); + self.collect_conflicts_between(&mut conflicts, + mutually_exclusive, + &field_map1, + &field_map2, + ctx); for fragment_name in &fragment_names2 { - self.collect_conflicts_between_fields_and_fragment( - &mut conflicts, - &field_map1, - fragment_name, - mutually_exclusive, - ctx); + self.collect_conflicts_between_fields_and_fragment(&mut conflicts, + &field_map1, + fragment_name, + mutually_exclusive, + ctx); } for fragment_name in &fragment_names1 { - self.collect_conflicts_between_fields_and_fragment( - &mut conflicts, - &field_map2, - fragment_name, - mutually_exclusive, - ctx); + self.collect_conflicts_between_fields_and_fragment(&mut conflicts, + &field_map2, + fragment_name, + mutually_exclusive, + ctx); } for fragment_name1 in &fragment_names1 { for fragment_name2 in &fragment_names2 { - self.collect_conflicts_between_fragments( - &mut conflicts, - fragment_name1, - fragment_name2, - mutually_exclusive, - ctx); + self.collect_conflicts_between_fragments(&mut conflicts, + fragment_name1, + fragment_name2, + mutually_exclusive, + ctx); } } conflicts } - fn subfield_conflicts( - &self, - conflicts: &[Conflict], - response_name: &str, - pos1: &SourcePosition, - pos2: &SourcePosition, - ) - -> Option - { + fn subfield_conflicts(&self, + conflicts: &[Conflict], + response_name: &str, + pos1: &SourcePosition, + pos2: &SourcePosition) + -> Option { if conflicts.is_empty() { return None; } - Some(Conflict( - ConflictReason( - response_name.to_owned(), - ConflictReasonMessage::Nested(conflicts.iter().map(|c| c.0.clone()).collect())), - vec![pos1.clone()].into_iter() - .chain(conflicts.iter().flat_map(|&Conflict(_, ref fs1, _)| fs1.clone())) - .collect(), - vec![pos2.clone()].into_iter() - .chain(conflicts.iter().flat_map(|&Conflict(_, _, ref fs2)| fs2.clone())) - .collect())) + Some(Conflict(ConflictReason(response_name.to_owned(), + ConflictReasonMessage::Nested(conflicts + .iter() + .map(|c| { + c.0.clone() + }) + .collect())), + vec![pos1.clone()] + .into_iter() + .chain(conflicts + .iter() + .flat_map(|&Conflict(_, ref fs1, _)| fs1.clone())) + .collect(), + vec![pos2.clone()] + .into_iter() + .chain(conflicts + .iter() + .flat_map(|&Conflict(_, _, ref fs2)| fs2.clone())) + .collect())) } - fn is_type_conflict( - &self, - ctx: &ValidatorContext<'a>, - t1: &Type, - t2: &Type, - ) - -> bool - { + fn is_type_conflict(&self, ctx: &ValidatorContext<'a>, t1: &Type, t2: &Type) -> bool { match (t1, t2) { (&Type::List(ref inner1), &Type::List(ref inner2)) | - (&Type::NonNullList(ref inner1), &Type::NonNullList(ref inner2)) => - self.is_type_conflict(ctx, inner1, inner2), + (&Type::NonNullList(ref inner1), &Type::NonNullList(ref inner2)) => { + self.is_type_conflict(ctx, inner1, inner2) + } (&Type::NonNullNamed(n1), &Type::NonNullNamed(n2)) | (&Type::Named(n1), &Type::Named(n2)) => { let ct1 = ctx.schema.concrete_type_by_name(n1); let ct2 = ctx.schema.concrete_type_by_name(n2); - if ct1.map(|ct| ct.is_leaf()).unwrap_or(false) - || ct2.map(|ct| ct.is_leaf()).unwrap_or(false) - { + if ct1.map(|ct| ct.is_leaf()).unwrap_or(false) || + ct2.map(|ct| ct.is_leaf()).unwrap_or(false) { n1 != n2 - } - else { + } else { false } } @@ -488,13 +465,10 @@ impl<'a> OverlappingFieldsCanBeMerged<'a> { } } - fn is_same_arguments( - &self, - args1: &Option>, - args2: &Option>, - ) - -> bool - { + fn is_same_arguments(&self, + args1: &Option>, + args2: &Option>) + -> bool { match (args1, args2) { (&None, &None) => true, (&Some(Spanning { item: ref args1, .. }), &Some(Spanning { item: ref args2, .. })) => { @@ -502,94 +476,95 @@ impl<'a> OverlappingFieldsCanBeMerged<'a> { return false; } - args1.iter().all(|&(ref n1, ref v1)| { - if let Some(&(_, ref v2)) = args2.iter().find(|&&(ref n2, _)| n1.item == n2.item) { - v1.item.unlocated_eq(&v2.item) - } - else { - false - } - }) - }, - _ => false + args1 + .iter() + .all(|&(ref n1, ref v1)| if let Some(&(_, ref v2)) = + args2.iter().find(|&&(ref n2, _)| n1.item == n2.item) { + v1.item.unlocated_eq(&v2.item) + } else { + false + }) + } + _ => false, } } - fn is_object_type( - &self, - ctx: &ValidatorContext<'a>, - type_name: Option<&str>, - ) - -> bool - { + fn is_object_type(&self, ctx: &ValidatorContext<'a>, type_name: Option<&str>) -> bool { match type_name.and_then(|n| ctx.schema.concrete_type_by_name(n)) { Some(&MetaType::Object(_)) => true, - _ => false + _ => false, } } - fn get_referenced_fields_and_fragment_names( - &self, - fragment: &'a Fragment, - ctx: &ValidatorContext<'a>, - ) - -> (AstAndDefCollection<'a>, Vec<&'a str>) - { - let fragment_type = ctx.schema.concrete_type_by_name(fragment.type_condition.item); + fn get_referenced_fields_and_fragment_names(&self, + fragment: &'a Fragment, + ctx: &ValidatorContext<'a>) + -> (AstAndDefCollection<'a>, Vec<&'a str>) { + let fragment_type = ctx.schema + .concrete_type_by_name(fragment.type_condition.item); self.get_fields_and_fragment_names(fragment_type, &fragment.selection_set, ctx) } - fn get_fields_and_fragment_names( - &self, - parent_type: Option<&'a MetaType>, - selection_set: &'a [Selection], - ctx: &ValidatorContext<'a>, - ) - -> (AstAndDefCollection<'a>, Vec<&'a str>) - { + fn get_fields_and_fragment_names(&self, + parent_type: Option<&'a MetaType>, + selection_set: &'a [Selection], + ctx: &ValidatorContext<'a>) + -> (AstAndDefCollection<'a>, Vec<&'a str>) { let mut ast_and_defs = OrderedMap::new(); let mut fragment_names = Vec::new(); - self.collect_fields_and_fragment_names(parent_type, selection_set, ctx, &mut ast_and_defs, &mut fragment_names); + self.collect_fields_and_fragment_names(parent_type, + selection_set, + ctx, + &mut ast_and_defs, + &mut fragment_names); (ast_and_defs, fragment_names) } - fn collect_fields_and_fragment_names( - &self, - parent_type: Option<&'a MetaType>, - selection_set: &'a [Selection], - ctx: &ValidatorContext<'a>, - ast_and_defs: &mut AstAndDefCollection<'a>, - fragment_names: &mut Vec<&'a str>, - ) - { + fn collect_fields_and_fragment_names(&self, + parent_type: Option<&'a MetaType>, + selection_set: &'a [Selection], + ctx: &ValidatorContext<'a>, + ast_and_defs: &mut AstAndDefCollection<'a>, + fragment_names: &mut Vec<&'a str>) { for selection in selection_set { match *selection { Selection::Field(ref f) => { let field_name = &f.item.name.item; let field_def = parent_type.and_then(|t| t.field_by_name(field_name)); - let response_name = f.item.alias.as_ref().map(|s| &s.item).unwrap_or(field_name); + let response_name = + f.item.alias.as_ref().map(|s| &s.item).unwrap_or(field_name); if !ast_and_defs.contains_key(response_name) { ast_and_defs.insert(response_name, Vec::new()); } - ast_and_defs.get_mut(response_name).unwrap() + ast_and_defs + .get_mut(response_name) + .unwrap() .push(AstAndDef(parent_type.and_then(MetaType::name), f, field_def)); - }, - Selection::FragmentSpread(Spanning { item: FragmentSpread { ref name, ..}, ..}) => { + } + Selection::FragmentSpread(Spanning { + item: FragmentSpread { ref name, .. }, .. + }) => { if fragment_names.iter().find(|n| *n == &name.item).is_none() { fragment_names.push(name.item); } - }, + } Selection::InlineFragment(Spanning { item: ref inline, .. }) => { - let parent_type = inline.type_condition.as_ref() + let parent_type = inline + .type_condition + .as_ref() .and_then(|cond| ctx.schema.concrete_type_by_name(cond.item)) .or(parent_type); - self.collect_fields_and_fragment_names(parent_type, &inline.selection_set, ctx, ast_and_defs, fragment_names); + self.collect_fields_and_fragment_names(parent_type, + &inline.selection_set, + ctx, + ast_and_defs, + fragment_names); } } } @@ -605,10 +580,11 @@ impl<'a> Visitor<'a> for OverlappingFieldsCanBeMerged<'a> { } } - fn enter_selection_set(&mut self, ctx: &mut ValidatorContext<'a>, selection_set: &'a Vec) { - for Conflict(ConflictReason(reason_name, reason_msg), mut p1, mut p2) - in self.find_conflicts_within_selection_set(ctx.parent_type(), selection_set, ctx) - { + fn enter_selection_set(&mut self, + ctx: &mut ValidatorContext<'a>, + selection_set: &'a Vec) { + for Conflict(ConflictReason(reason_name, reason_msg), mut p1, mut p2) in + self.find_conflicts_within_selection_set(ctx.parent_type(), selection_set, ctx) { p1.append(&mut p2); ctx.report_error(&error_message(&reason_name, &reason_msg), &p1); } @@ -623,15 +599,18 @@ fn error_message(reason_name: &str, reason: &ConflictReasonMessage) -> String { fn format_reason(reason: &ConflictReasonMessage) -> String { match *reason { ConflictReasonMessage::Message(ref name) => name.clone(), - ConflictReasonMessage::Nested(ref nested) => - nested.iter() - .map(|&ConflictReason(ref name, ref subreason)| - format!( + ConflictReasonMessage::Nested(ref nested) => { + nested + .iter() + .map(|&ConflictReason(ref name, ref subreason)| { + format!( r#"subfields "{}" conflict because {}"#, name, - format_reason(subreason))) + format_reason(subreason)) + }) .collect::>() .join(" and ") + } } } @@ -647,12 +626,12 @@ mod tests { use parser::SourcePosition; use validation::{RuleError, expect_passes_rule, expect_fails_rule, - expect_passes_rule_with_schema, - expect_fails_rule_with_schema}; + expect_passes_rule_with_schema, expect_fails_rule_with_schema}; #[test] fn unique_fields() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment uniqueFields on Dog { name nickname @@ -662,7 +641,8 @@ mod tests { #[test] fn identical_fields() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment mergeIdenticalFields on Dog { name name @@ -672,7 +652,8 @@ mod tests { #[test] fn identical_fields_with_identical_args() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment mergeIdenticalFieldsWithIdenticalArgs on Dog { doesKnowCommand(dogCommand: SIT) doesKnowCommand(dogCommand: SIT) @@ -682,7 +663,8 @@ mod tests { #[test] fn identical_fields_with_identical_directives() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment mergeSameFieldsWithSameDirectives on Dog { name @include(if: true) name @include(if: true) @@ -692,7 +674,8 @@ mod tests { #[test] fn different_args_with_different_aliases() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment differentArgsWithDifferentAliases on Dog { knowsSit: doesKnowCommand(dogCommand: SIT) knowsDown: doesKnowCommand(dogCommand: DOWN) @@ -702,7 +685,8 @@ mod tests { #[test] fn different_directives_with_different_aliases() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment differentDirectivesWithDifferentAliases on Dog { nameIfTrue: name @include(if: true) nameIfFalse: name @include(if: false) @@ -712,7 +696,8 @@ mod tests { #[test] fn different_skip_include_directives_accepted() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment differentDirectivesWithDifferentAliases on Dog { name @include(if: true) name @include(if: false) @@ -739,7 +724,8 @@ mod tests { #[test] fn same_aliases_allowed_on_nonoverlapping_fields() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment sameAliasesWithDifferentFieldTargets on Pet { ... on Dog { name @@ -770,58 +756,56 @@ mod tests { #[test] fn different_args_second_adds_an_argument() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment conflictingArgs on Dog { doesKnowCommand 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)])]); } #[test] fn different_args_second_missing_an_argument() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment conflictingArgs on Dog { doesKnowCommand(dogCommand: SIT) 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)])]); } #[test] fn conflicting_args() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment conflictingArgs on Dog { doesKnowCommand(dogCommand: SIT) 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)])]); } #[test] fn allows_different_args_where_no_conflict_is_possible() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment conflictingArgs on Pet { ... on Dog { name(surname: true) @@ -835,7 +819,8 @@ mod tests { #[test] fn encounters_conflict_in_fragments() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { ...A ...B @@ -847,18 +832,17 @@ 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)])]); } #[test] fn reports_each_conflict_once() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { f1 { ...A @@ -881,28 +865,27 @@ mod tests { x: b } "#, - &[ - RuleError::new( - &error_message("x", &Message("c and a are different fields".to_owned())), &[ - SourcePosition::new(220, 13, 14), - SourcePosition::new(294, 17, 12), - ]), - RuleError::new( - &error_message("x", &Message("c and b are different fields".to_owned())), &[ - SourcePosition::new(220, 13, 14), - SourcePosition::new(354, 20, 12), - ]), - RuleError::new( - &error_message("x", &Message("a and b are different fields".to_owned())), &[ - SourcePosition::new(294, 17, 12), - SourcePosition::new(354, 20, 12), - ]), - ]); + &[RuleError::new(&error_message("x", + &Message("c and a are different fields" + .to_owned())), + &[SourcePosition::new(220, 13, 14), + SourcePosition::new(294, 17, 12)]), + RuleError::new(&error_message("x", + &Message("c and b are different fields" + .to_owned())), + &[SourcePosition::new(220, 13, 14), + SourcePosition::new(354, 20, 12)]), + RuleError::new(&error_message("x", + &Message("a and b are different fields" + .to_owned())), + &[SourcePosition::new(294, 17, 12), + SourcePosition::new(354, 20, 12)])]); } #[test] fn deep_conflict() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { field { x: a @@ -912,26 +895,23 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("field", - &Nested(vec![ + &[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), - ]), - ]); + ])), + &[SourcePosition::new(25, 2, 12), + SourcePosition::new(47, 3, 14), + SourcePosition::new(79, 5, 12), + SourcePosition::new(101, 6, 14)])]); } #[test] fn deep_conflict_with_multiple_issues() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { field { x: a @@ -943,10 +923,8 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("field", - &Nested(vec![ + &[RuleError::new(&error_message("field", + &Nested(vec![ ConflictReason( "x".to_owned(), Message("a and b are different fields".to_owned()) @@ -955,20 +933,19 @@ mod tests { "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), - ]), - ]); + ])), + &[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)])]); } #[test] fn very_deep_conflict() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { field { deepField { @@ -982,10 +959,8 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("field", - &Nested(vec![ + &[RuleError::new(&error_message("field", + &Nested(vec![ ConflictReason( "deepField".to_owned(), Nested(vec![ @@ -995,20 +970,19 @@ mod tests { ) ]) ), - ])), &[ - 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), - ]), - ]); + ])), + &[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)])]); } #[test] fn reports_deep_conflict_to_nearest_common_ancestor() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { field { deepField { @@ -1025,26 +999,23 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("deepField", - &Nested(vec![ + &[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), - ]), - ]); + ])), + &[SourcePosition::new(47, 3, 14), + SourcePosition::new(75, 4, 16), + SourcePosition::new(110, 6, 14), + SourcePosition::new(138, 7, 16)])]); } #[test] fn reports_deep_conflict_to_nearest_common_ancestor_in_fragments() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { field { ...F @@ -1069,26 +1040,23 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message("deeperField", - &Nested(vec![ + &[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), - ]), - ]); + ])), + &[SourcePosition::new(197, 11, 14), + SourcePosition::new(227, 12, 16), + SourcePosition::new(262, 14, 14), + SourcePosition::new(292, 15, 16)])]); } #[test] fn reports_deep_conflict_in_nested_fragments() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { field { ...F @@ -1112,10 +1080,8 @@ mod tests { x: b } "#, - &[ - RuleError::new( - &error_message("field", - &Nested(vec![ + &[RuleError::new(&error_message("field", + &Nested(vec![ ConflictReason( "x".to_owned(), Message("a and b are different fields".to_owned()) @@ -1124,20 +1090,19 @@ mod tests { "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), - ]), - ]); + ])), + &[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)])]); } #[test] fn ignores_unknown_fragments() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { field ...Unknown @@ -1171,13 +1136,10 @@ mod tests { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry.field::>("deepBox"), - registry.field::>("unrelatedField"), - ]; + let fields = &[registry.field::>("deepBox"), + registry.field::>("unrelatedField")]; - registry.build_interface_type::(fields) - .into_meta() + registry.build_interface_type::(fields).into_meta() } } @@ -1189,19 +1151,16 @@ mod tests { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry.field::>("scalar"), - registry.field::>("deepBox"), - registry.field::>("unrelatedField"), - registry.field::>>>("listStringBox"), - registry.field::>("stringBox"), - registry.field::>("intBox"), - ]; + let fields = &[registry.field::>("scalar"), + registry.field::>("deepBox"), + registry.field::>("unrelatedField"), + registry.field::>>>("listStringBox"), + registry.field::>("stringBox"), + registry.field::>("intBox")]; - registry.build_object_type::(fields) - .interfaces(&[ - registry.get_type::(), - ]) + registry + .build_object_type::(fields) + .interfaces(&[registry.get_type::()]) .into_meta() } } @@ -1214,19 +1173,16 @@ mod tests { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry.field::>("scalar"), - registry.field::>("deepBox"), - registry.field::>("unrelatedField"), - registry.field::>>>("listStringBox"), - registry.field::>("stringBox"), - registry.field::>("intBox"), - ]; + let fields = &[registry.field::>("scalar"), + registry.field::>("deepBox"), + registry.field::>("unrelatedField"), + registry.field::>>>("listStringBox"), + registry.field::>("stringBox"), + registry.field::>("intBox")]; - registry.build_object_type::(fields) - .interfaces(&[ - registry.get_type::(), - ]) + registry + .build_object_type::(fields) + .interfaces(&[registry.get_type::()]) .into_meta() } } @@ -1239,12 +1195,9 @@ mod tests { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry.field::("scalar"), - ]; + let fields = &[registry.field::("scalar")]; - registry.build_interface_type::(fields) - .into_meta() + registry.build_interface_type::(fields).into_meta() } } @@ -1256,17 +1209,14 @@ mod tests { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry.field::("scalar"), - registry.field::>("deepBox"), - registry.field::>("unrelatedField"), - ]; + let fields = &[registry.field::("scalar"), + registry.field::>("deepBox"), + registry.field::>("unrelatedField")]; - registry.build_object_type::(fields) - .interfaces(&[ - registry.get_type::(), - registry.get_type::(), - ]) + registry + .build_object_type::(fields) + .interfaces(&[registry.get_type::(), + registry.get_type::()]) .into_meta() } } @@ -1279,12 +1229,9 @@ mod tests { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry.field::("scalar"), - ]; + let fields = &[registry.field::("scalar")]; - registry.build_interface_type::(fields) - .into_meta() + registry.build_interface_type::(fields).into_meta() } } @@ -1296,17 +1243,14 @@ mod tests { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry.field::("scalar"), - registry.field::>("deepBox"), - registry.field::>("unrelatedField"), - ]; + let fields = &[registry.field::("scalar"), + registry.field::>("deepBox"), + registry.field::>("unrelatedField")]; - registry.build_object_type::(fields) - .interfaces(&[ - registry.get_type::(), - registry.get_type::(), - ]) + registry + .build_object_type::(fields) + .interfaces(&[registry.get_type::(), + registry.get_type::()]) .into_meta() } } @@ -1319,13 +1263,10 @@ mod tests { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry.field::>("id"), - registry.field::>("name"), - ]; + let fields = &[registry.field::>("id"), + registry.field::>("name")]; - registry.build_object_type::(fields) - .into_meta() + registry.build_object_type::(fields).into_meta() } } @@ -1337,12 +1278,9 @@ mod tests { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry.field::>("node"), - ]; + let fields = &[registry.field::>("node")]; - registry.build_object_type::(fields) - .into_meta() + registry.build_object_type::(fields).into_meta() } } @@ -1354,12 +1292,9 @@ mod tests { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry.field::>>>("edges"), - ]; + let fields = &[registry.field::>>>("edges")]; - registry.build_object_type::(fields) - .into_meta() + registry.build_object_type::(fields).into_meta() } } @@ -1376,12 +1311,9 @@ mod tests { registry.get_type::(); registry.get_type::(); - let fields = &[ - registry.field::>("someBox"), - registry.field::>("connection"), - ]; - registry.build_object_type::(fields) - .into_meta() + let fields = &[registry.field::>("someBox"), + registry.field::>("connection")]; + registry.build_object_type::(fields).into_meta() } } @@ -1412,7 +1344,9 @@ mod tests { #[test] fn compatible_return_shapes_on_different_return_types() { - expect_passes_rule_with_schema(QueryRoot, factory, r#" + expect_passes_rule_with_schema(QueryRoot, + factory, + r#" { someBox { ... on SomeBox { @@ -1457,7 +1391,9 @@ mod tests { #[test] fn reports_correctly_when_a_non_exclusive_follows_an_exclusive() { - expect_fails_rule_with_schema(QueryRoot, factory, r#" + expect_fails_rule_with_schema(QueryRoot, + factory, + r#" { someBox { ... on IntBox { @@ -1501,22 +1437,17 @@ mod tests { scalar: unrelatedField } "#, - &[ - RuleError::new( - &error_message( - "other", - &Nested(vec![ + &[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), - ]), - ]); + ])), + &[SourcePosition::new(703, 30, 14), + SourcePosition::new(889, 38, 14), + SourcePosition::new(771, 33, 14), + SourcePosition::new(960, 41, 14)])]); } #[test] @@ -1631,7 +1562,9 @@ mod tests { #[test] fn disallows_differing_deep_return_types_despite_no_overlap() { - expect_fails_rule_with_schema(QueryRoot, factory, r#" + expect_fails_rule_with_schema(QueryRoot, + factory, + r#" { someBox { ... on IntBox { @@ -1647,27 +1580,24 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message( - "box", - &Nested(vec![ + &[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), - ]), - ]); + ])), + &[SourcePosition::new(89, 4, 18), + SourcePosition::new(126, 5, 20), + SourcePosition::new(224, 9, 18), + SourcePosition::new(258, 10, 20)])]); } #[test] fn allows_non_conflicting_overlapping_types() { - expect_passes_rule_with_schema(QueryRoot, factory, r#" + expect_passes_rule_with_schema(QueryRoot, + factory, + r#" { someBox { ... on IntBox { @@ -1683,7 +1613,9 @@ mod tests { #[test] fn same_wrapped_scalar_return_types() { - expect_passes_rule_with_schema(QueryRoot, factory, r#" + expect_passes_rule_with_schema(QueryRoot, + factory, + r#" { someBox { ...on NonNullStringBox1 { @@ -1699,7 +1631,9 @@ mod tests { #[test] fn allows_inline_typeless_fragments() { - expect_passes_rule_with_schema(QueryRoot, factory, r#" + expect_passes_rule_with_schema(QueryRoot, + factory, + r#" { a ... { @@ -1711,7 +1645,9 @@ mod tests { #[test] fn compares_deep_types_including_list() { - expect_fails_rule_with_schema(QueryRoot, factory, r#" + expect_fails_rule_with_schema(QueryRoot, + factory, + r#" { connection { ...edgeID @@ -1731,11 +1667,8 @@ mod tests { } } "#, - &[ - RuleError::new( - &error_message( - "edges", - &Nested(vec![ + &[RuleError::new(&error_message("edges", + &Nested(vec![ ConflictReason( "node".to_owned(), Nested(vec![ @@ -1745,20 +1678,20 @@ mod tests { ) ]), ) - ])), &[ - 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), - ]), - ]); + ])), + &[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)])]); } #[test] fn ignores_unknown_types() { - expect_passes_rule_with_schema(QueryRoot, factory, r#" + expect_passes_rule_with_schema(QueryRoot, + factory, + r#" { someBox { ...on UnknownType { diff --git a/juniper/src/validation/rules/possible_fragment_spreads.rs b/juniper/src/validation/rules/possible_fragment_spreads.rs index 71730f76..e308e825 100644 --- a/juniper/src/validation/rules/possible_fragment_spreads.rs +++ b/juniper/src/validation/rules/possible_fragment_spreads.rs @@ -9,9 +9,7 @@ pub struct PossibleFragmentSpreads<'a> { } pub fn factory<'a>() -> PossibleFragmentSpreads<'a> { - PossibleFragmentSpreads { - fragment_types: HashMap::new(), - } + PossibleFragmentSpreads { fragment_types: HashMap::new() } } impl<'a> Visitor<'a> for PossibleFragmentSpreads<'a> { @@ -25,32 +23,34 @@ impl<'a> Visitor<'a> for PossibleFragmentSpreads<'a> { } } - fn enter_inline_fragment(&mut self, ctx: &mut ValidatorContext<'a>, frag: &'a Spanning) { - if let (Some(parent_type), Some(frag_type)) - = (ctx.parent_type(), frag.item.type_condition.as_ref().and_then(|s| ctx.schema.concrete_type_by_name(s.item))) - { + fn enter_inline_fragment(&mut self, + ctx: &mut ValidatorContext<'a>, + frag: &'a Spanning) { + if let (Some(parent_type), Some(frag_type)) = + (ctx.parent_type(), + frag.item + .type_condition + .as_ref() + .and_then(|s| ctx.schema.concrete_type_by_name(s.item))) { if !ctx.schema.type_overlap(parent_type, frag_type) { - ctx.report_error( - &error_message( - None, - parent_type.name().unwrap_or(""), - frag_type.name().unwrap_or("")), - &[frag.start.clone()]); + ctx.report_error(&error_message(None, + parent_type.name().unwrap_or(""), + frag_type.name().unwrap_or("")), + &[frag.start.clone()]); } } } - fn enter_fragment_spread(&mut self, ctx: &mut ValidatorContext<'a>, spread: &'a Spanning) { - if let (Some(parent_type), Some(frag_type)) - = (ctx.parent_type(), self.fragment_types.get(spread.item.name.item)) - { + fn enter_fragment_spread(&mut self, + ctx: &mut ValidatorContext<'a>, + spread: &'a Spanning) { + if let (Some(parent_type), Some(frag_type)) = + (ctx.parent_type(), self.fragment_types.get(spread.item.name.item)) { if !ctx.schema.type_overlap(parent_type, frag_type) { - ctx.report_error( - &error_message( - Some(spread.item.name.item), - parent_type.name().unwrap_or(""), - frag_type.name().unwrap_or("")), - &[spread.start.clone()]); + ctx.report_error(&error_message(Some(spread.item.name.item), + parent_type.name().unwrap_or(""), + frag_type.name().unwrap_or("")), + &[spread.start.clone()]); } } } @@ -62,8 +62,7 @@ fn error_message(frag_name: Option<&str>, parent_type_name: &str, frag_type: &st "Fragment \"{}\" cannot be spread here as objects of type \ \"{}\" can never be of type \"{}\"", frag_name, parent_type_name, frag_type) - } - else { + } else { format!( "Fragment cannot be spread here as objects of type \"{}\" \ can never be of type \"{}\"", @@ -80,7 +79,8 @@ mod tests { #[test] fn of_the_same_object() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment objectWithinObject on Dog { ...dogFragment } fragment dogFragment on Dog { barkVolume } "#); @@ -88,14 +88,16 @@ mod tests { #[test] fn of_the_same_object_with_inline_fragment() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment objectWithinObjectAnon on Dog { ... on Dog { barkVolume } } "#); } #[test] fn object_into_an_implemented_interface() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment objectWithinInterface on Pet { ...dogFragment } fragment dogFragment on Dog { barkVolume } "#); @@ -103,7 +105,8 @@ mod tests { #[test] fn object_into_containing_union() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment objectWithinUnion on CatOrDog { ...dogFragment } fragment dogFragment on Dog { barkVolume } "#); @@ -111,7 +114,8 @@ mod tests { #[test] fn union_into_contained_object() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment unionWithinObject on Dog { ...catOrDogFragment } fragment catOrDogFragment on CatOrDog { __typename } "#); @@ -119,7 +123,8 @@ mod tests { #[test] fn union_into_overlapping_interface() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment unionWithinInterface on Pet { ...catOrDogFragment } fragment catOrDogFragment on CatOrDog { __typename } "#); @@ -127,7 +132,8 @@ mod tests { #[test] fn union_into_overlapping_union() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment unionWithinUnion on DogOrHuman { ...catOrDogFragment } fragment catOrDogFragment on CatOrDog { __typename } "#); @@ -135,7 +141,8 @@ mod tests { #[test] fn interface_into_implemented_object() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment interfaceWithinObject on Dog { ...petFragment } fragment petFragment on Pet { name } "#); @@ -143,7 +150,8 @@ mod tests { #[test] fn interface_into_overlapping_interface() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment interfaceWithinInterface on Pet { ...beingFragment } fragment beingFragment on Being { name } "#); @@ -151,14 +159,16 @@ mod tests { #[test] fn interface_into_overlapping_interface_in_inline_fragment() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment interfaceWithinInterface on Pet { ... on Being { name } } "#); } #[test] fn interface_into_overlapping_union() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment interfaceWithinUnion on CatOrDog { ...petFragment } fragment petFragment on Pet { name } "#); @@ -166,149 +176,141 @@ mod tests { #[test] fn different_object_into_object() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" 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)])]); } #[test] fn different_object_into_object_in_inline_fragment() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment invalidObjectWithinObjectAnon on Cat { ... 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)])]); } #[test] fn object_into_not_implementing_interface() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" 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)])]); } #[test] fn object_into_not_containing_union() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" 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)])]); } #[test] fn union_into_not_contained_object() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" 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)])]); } #[test] fn union_into_non_overlapping_interface() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" 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)])]); } #[test] fn union_into_non_overlapping_union() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" 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)])]); } #[test] fn interface_into_non_implementing_object() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" 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)])]); } #[test] fn interface_into_non_overlapping_interface() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment invalidInterfaceWithinInterface on Pet { ...intelligentFragment } 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)])]); } #[test] fn interface_into_non_overlapping_interface_in_inline_fragment() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment invalidInterfaceWithinInterfaceAnon on Pet { ...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)])]); } #[test] fn interface_into_non_overlapping_union() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" 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 b79d9082..552751b1 100644 --- a/juniper/src/validation/rules/provided_non_null_arguments.rs +++ b/juniper/src/validation/rules/provided_non_null_arguments.rs @@ -1,11 +1,10 @@ use ast::{Field, Directive}; use validation::{ValidatorContext, Visitor}; use parser::Spanning; -use schema::meta::{Field as FieldType}; +use schema::meta::Field as FieldType; use schema::model::DirectiveType; -pub struct ProvidedNonNullArguments { -} +pub struct ProvidedNonNullArguments {} pub fn factory() -> ProvidedNonNullArguments { ProvidedNonNullArguments {} @@ -15,30 +14,44 @@ impl<'a> Visitor<'a> for ProvidedNonNullArguments { fn enter_field(&mut self, ctx: &mut ValidatorContext<'a>, field: &'a Spanning) { let field_name = &field.item.name.item; - if let Some(&FieldType { arguments: Some(ref meta_args), ..}) = ctx.parent_type().and_then(|t| t.field_by_name(field_name)) { + if let Some(&FieldType { arguments: Some(ref meta_args), .. }) = + ctx.parent_type().and_then(|t| t.field_by_name(field_name)) { for meta_arg in meta_args { - if meta_arg.arg_type.is_non_null() - && field.item.arguments.as_ref().and_then(|args| args.item.get(&meta_arg.name)).is_none() - { - ctx.report_error( - &field_error_message(field_name, &meta_arg.name, &format!("{}", meta_arg.arg_type)), - &[field.start.clone()]); + if meta_arg.arg_type.is_non_null() && + field + .item + .arguments + .as_ref() + .and_then(|args| args.item.get(&meta_arg.name)) + .is_none() { + ctx.report_error(&field_error_message(field_name, + &meta_arg.name, + &format!("{}", meta_arg.arg_type)), + &[field.start.clone()]); } } } } - fn enter_directive(&mut self, ctx: &mut ValidatorContext<'a>, directive: &'a Spanning) { + fn enter_directive(&mut self, + ctx: &mut ValidatorContext<'a>, + directive: &'a Spanning) { let directive_name = &directive.item.name.item; - if let Some(&DirectiveType { arguments: ref meta_args, ..}) = ctx.schema.directive_by_name(directive_name) { + if let Some(&DirectiveType { arguments: ref meta_args, .. }) = + ctx.schema.directive_by_name(directive_name) { for meta_arg in meta_args { - if meta_arg.arg_type.is_non_null() - && directive.item.arguments.as_ref().and_then(|args| args.item.get(&meta_arg.name)).is_none() - { - ctx.report_error( - &directive_error_message(directive_name, &meta_arg.name, &format!("{}", meta_arg.arg_type)), - &[directive.start.clone()]); + if meta_arg.arg_type.is_non_null() && + directive + .item + .arguments + .as_ref() + .and_then(|args| args.item.get(&meta_arg.name)) + .is_none() { + ctx.report_error(&directive_error_message(directive_name, + &meta_arg.name, + &format!("{}", meta_arg.arg_type)), + &[directive.start.clone()]); } } } @@ -66,7 +79,8 @@ mod tests { #[test] fn ignores_unknown_arguments() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { dog { isHousetrained(unknownArgument: true) @@ -77,7 +91,8 @@ mod tests { #[test] fn arg_on_optional_arg() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { dog { isHousetrained(atOtherHomes: true) @@ -88,7 +103,8 @@ mod tests { #[test] fn no_arg_on_optional_arg() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { dog { isHousetrained @@ -99,7 +115,8 @@ mod tests { #[test] fn multiple_args() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { multipleReqs(req1: 1, req2: 2) @@ -110,7 +127,8 @@ mod tests { #[test] fn multiple_args_reverse_order() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { multipleReqs(req2: 2, req1: 1) @@ -121,7 +139,8 @@ mod tests { #[test] fn no_args_on_multiple_optional() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { multipleOpts @@ -132,7 +151,8 @@ mod tests { #[test] fn one_arg_on_multiple_optional() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { multipleOpts(opt1: 1) @@ -143,7 +163,8 @@ mod tests { #[test] fn second_arg_on_multiple_optional() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { multipleOpts(opt2: 1) @@ -154,7 +175,8 @@ mod tests { #[test] fn muliple_reqs_on_mixed_list() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { multipleOptAndReq(req1: 3, req2: 4) @@ -165,7 +187,8 @@ mod tests { #[test] fn multiple_reqs_and_one_opt_on_mixed_list() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { multipleOptAndReq(req1: 3, req2: 4, opt1: 5) @@ -176,7 +199,8 @@ mod tests { #[test] fn all_reqs_on_opts_on_mixed_list() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { complicatedArgs { multipleOptAndReq(req1: 3, req2: 4, opt1: 5, opt2: 6) @@ -187,58 +211,52 @@ mod tests { #[test] fn missing_one_non_nullable_argument() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { multipleReqs(req2: 2) } } "#, - &[ - 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)])]); } #[test] fn missing_multiple_non_nullable_arguments() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { multipleReqs } } "#, - &[ - RuleError::new(&field_error_message("multipleReqs", "req1", "Int!"), &[ - SourcePosition::new(63, 3, 16), - ]), - RuleError::new(&field_error_message("multipleReqs", "req2", "Int!"), &[ - SourcePosition::new(63, 3, 16), - ]), - ]); + &[RuleError::new(&field_error_message("multipleReqs", "req1", "Int!"), + &[SourcePosition::new(63, 3, 16)]), + RuleError::new(&field_error_message("multipleReqs", "req2", "Int!"), + &[SourcePosition::new(63, 3, 16)])]); } #[test] fn incorrect_value_and_missing_argument() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { complicatedArgs { multipleReqs(req1: "one") } } "#, - &[ - 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)])]); } #[test] fn ignores_unknown_directives() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { dog @unknown } @@ -247,7 +265,8 @@ mod tests { #[test] fn with_directives_of_valid_types() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { dog @include(if: true) { name @@ -261,20 +280,17 @@ mod tests { #[test] fn with_directive_with_missing_types() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { dog @include { name @skip } } "#, - &[ - RuleError::new(&directive_error_message("include", "if", "Boolean!"), &[ - SourcePosition::new(33, 2, 18), - ]), - RuleError::new(&directive_error_message("skip", "if", "Boolean!"), &[ - SourcePosition::new(65, 3, 21), - ]), - ]); + &[RuleError::new(&directive_error_message("include", "if", "Boolean!"), + &[SourcePosition::new(33, 2, 18)]), + RuleError::new(&directive_error_message("skip", "if", "Boolean!"), + &[SourcePosition::new(65, 3, 21)])]); } } diff --git a/juniper/src/validation/rules/scalar_leafs.rs b/juniper/src/validation/rules/scalar_leafs.rs index dfd2f527..eb7265e0 100644 --- a/juniper/src/validation/rules/scalar_leafs.rs +++ b/juniper/src/validation/rules/scalar_leafs.rs @@ -12,7 +12,8 @@ impl<'a> Visitor<'a> for ScalarLeafs { fn enter_field(&mut self, ctx: &mut ValidatorContext<'a>, field: &'a Spanning) { let field_name = &field.item.name.item; - let error = if let (Some(field_type), Some(field_type_literal)) = (ctx.current_type(), ctx.current_type_literal()) { + let error = if let (Some(field_type), Some(field_type_literal)) = + (ctx.current_type(), ctx.current_type_literal()) { match (field_type.is_leaf(), &field.item.selection_set) { (true, &Some(_)) => Some(RuleError::new( &no_allowed_error_message(field_name, &format!("{}", field_type_literal)), @@ -22,7 +23,9 @@ impl<'a> Visitor<'a> for ScalarLeafs { &[field.start.clone()])), _ => None, } - } else { None }; + } else { + None + }; if let Some(error) = error { ctx.append_errors(vec![error]); @@ -51,7 +54,8 @@ mod tests { #[test] fn valid_scalar_selection() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment scalarSelection on Dog { barks } @@ -60,35 +64,32 @@ mod tests { #[test] fn object_type_missing_selection() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query directQueryOnObjectWithoutSubFields { 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)])]); } #[test] fn interface_type_missing_selection() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { 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)])]); } #[test] fn valid_scalar_selection_with_args() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment scalarSelectionWithArgs on Dog { doesKnowCommand(dogCommand: SIT) } @@ -97,72 +98,64 @@ mod tests { #[test] fn scalar_selection_not_allowed_on_boolean() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment scalarSelectionsNotAllowedOnBoolean on Dog { 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)])]); } #[test] fn scalar_selection_not_allowed_on_enum() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment scalarSelectionsNotAllowedOnEnum on Cat { 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)])]); } #[test] fn scalar_selection_not_allowed_with_args() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment scalarSelectionsNotAllowedWithArgs on Dog { 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)])]); } #[test] fn scalar_selection_not_allowed_with_directives() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment scalarSelectionsNotAllowedWithDirectives on Dog { 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)])]); } #[test] fn scalar_selection_not_allowed_with_directives_and_args() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment scalarSelectionsNotAllowedWithDirectivesAndArgs on Dog { 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 54e9dfb7..e657a9bb 100644 --- a/juniper/src/validation/rules/unique_argument_names.rs +++ b/juniper/src/validation/rules/unique_argument_names.rs @@ -9,9 +9,7 @@ pub struct UniqueArgumentNames<'a> { } pub fn factory<'a>() -> UniqueArgumentNames<'a> { - UniqueArgumentNames { - known_names: HashMap::new(), - } + UniqueArgumentNames { known_names: HashMap::new() } } impl<'a> Visitor<'a> for UniqueArgumentNames<'a> { @@ -23,12 +21,13 @@ impl<'a> Visitor<'a> for UniqueArgumentNames<'a> { self.known_names = HashMap::new(); } - fn enter_argument(&mut self, ctx: &mut ValidatorContext<'a>, &(ref arg_name, _): &'a (Spanning<&'a str>, Spanning)) { + fn enter_argument(&mut self, + ctx: &mut ValidatorContext<'a>, + &(ref arg_name, _): &'a (Spanning<&'a str>, Spanning)) { match self.known_names.entry(arg_name.item) { Entry::Occupied(e) => { - ctx.report_error( - &error_message(arg_name.item), - &[e.get().clone(), arg_name.start.clone()]); + ctx.report_error(&error_message(arg_name.item), + &[e.get().clone(), arg_name.start.clone()]); } Entry::Vacant(e) => { e.insert(arg_name.start.clone()); @@ -50,7 +49,8 @@ mod tests { #[test] fn no_arguments_on_field() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { field } @@ -59,7 +59,8 @@ mod tests { #[test] fn no_arguments_on_directive() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { field @directive } @@ -68,7 +69,8 @@ mod tests { #[test] fn argument_on_field() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { field(arg: "value") } @@ -77,7 +79,8 @@ mod tests { #[test] fn argument_on_directive() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { field @directive(arg: "value") } @@ -86,7 +89,8 @@ mod tests { #[test] fn same_argument_on_two_fields() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { one: field(arg: "value") two: field(arg: "value") @@ -96,7 +100,8 @@ mod tests { #[test] fn same_argument_on_field_and_directive() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { field(arg: "value") @directive(arg: "value") } @@ -105,7 +110,8 @@ mod tests { #[test] fn same_argument_on_two_directives() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { field @directive1(arg: "value") @directive2(arg: "value") } @@ -114,7 +120,8 @@ mod tests { #[test] fn multiple_field_arguments() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { field(arg1: "value", arg2: "value", arg3: "value") } @@ -123,7 +130,8 @@ mod tests { #[test] fn multiple_directive_arguments() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { field @directive(arg1: "value", arg2: "value", arg3: "value") } @@ -132,70 +140,60 @@ mod tests { #[test] fn duplicate_field_arguments() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { 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)])]); } #[test] fn many_duplicate_field_arguments() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { field(arg1: "value", 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(61, 2, 48), - ]), - ]); + &[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(61, 2, 48)])]); } #[test] fn duplicate_directive_arguments() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { 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)])]); } #[test] fn many_duplicate_directive_arguments() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { field @directive(arg1: "value", 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(72, 2, 59), - ]), - ]); + &[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(72, 2, 59)])]); } } diff --git a/juniper/src/validation/rules/unique_fragment_names.rs b/juniper/src/validation/rules/unique_fragment_names.rs index f966d39e..df9886bd 100644 --- a/juniper/src/validation/rules/unique_fragment_names.rs +++ b/juniper/src/validation/rules/unique_fragment_names.rs @@ -9,18 +9,17 @@ pub struct UniqueFragmentNames<'a> { } pub fn factory<'a>() -> UniqueFragmentNames<'a> { - UniqueFragmentNames { - names: HashMap::new(), - } + UniqueFragmentNames { names: HashMap::new() } } impl<'a> Visitor<'a> for UniqueFragmentNames<'a> { - fn enter_fragment_definition(&mut self, context: &mut ValidatorContext<'a>, f: &'a Spanning) { + fn enter_fragment_definition(&mut self, + context: &mut ValidatorContext<'a>, + f: &'a Spanning) { match self.names.entry(f.item.name.item) { Entry::Occupied(e) => { - context.report_error( - &duplicate_message(f.item.name.item), - &[e.get().clone(), f.item.name.start.clone()]); + context.report_error(&duplicate_message(f.item.name.item), + &[e.get().clone(), f.item.name.start.clone()]); } Entry::Vacant(e) => { e.insert(f.item.name.start.clone()); @@ -42,7 +41,8 @@ mod tests { #[test] fn no_fragments() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { field } @@ -51,7 +51,8 @@ mod tests { #[test] fn one_fragment() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { ...fragA } @@ -64,7 +65,8 @@ mod tests { #[test] fn many_fragments() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { ...fragA ...fragB @@ -84,7 +86,8 @@ mod tests { #[test] fn inline_fragments_always_unique() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { ...on Type { fieldA @@ -98,7 +101,8 @@ mod tests { #[test] fn fragment_and_operation_named_the_same() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo { ...Foo } @@ -110,7 +114,8 @@ mod tests { #[test] fn fragments_named_the_same() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { ...fragA } @@ -121,17 +126,15 @@ 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)])]); } #[test] fn fragments_named_the_same_no_reference() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment fragA on Type { fieldA } @@ -139,11 +142,8 @@ 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 da407a6c..84dcd5c6 100644 --- a/juniper/src/validation/rules/unique_input_field_names.rs +++ b/juniper/src/validation/rules/unique_input_field_names.rs @@ -9,27 +9,30 @@ pub struct UniqueInputFieldNames<'a> { } pub fn factory<'a>() -> UniqueInputFieldNames<'a> { - UniqueInputFieldNames { - known_name_stack: Vec::new(), - } + UniqueInputFieldNames { known_name_stack: Vec::new() } } impl<'a> Visitor<'a> for UniqueInputFieldNames<'a> { - fn enter_object_value(&mut self, _: &mut ValidatorContext<'a>, _: Spanning<&'a Vec<(Spanning, Spanning)>>) { + fn enter_object_value(&mut self, + _: &mut ValidatorContext<'a>, + _: Spanning<&'a Vec<(Spanning, Spanning)>>) { self.known_name_stack.push(HashMap::new()); } - fn exit_object_value(&mut self, _: &mut ValidatorContext<'a>, _: Spanning<&'a Vec<(Spanning, Spanning)>>) { + fn exit_object_value(&mut self, + _: &mut ValidatorContext<'a>, + _: Spanning<&'a Vec<(Spanning, Spanning)>>) { self.known_name_stack.pop(); } - fn enter_object_field(&mut self, ctx: &mut ValidatorContext<'a>, &(ref field_name, _): &'a (Spanning, Spanning)) { + fn enter_object_field(&mut self, + ctx: &mut ValidatorContext<'a>, + &(ref field_name, _): &'a (Spanning, Spanning)) { if let Some(ref mut known_names) = self.known_name_stack.last_mut() { match known_names.entry(&field_name.item) { Entry::Occupied(e) => { - ctx.report_error( - &error_message(&field_name.item), - &[e.get().clone(), field_name.start.clone()]); + ctx.report_error(&error_message(&field_name.item), + &[e.get().clone(), field_name.start.clone()]); } Entry::Vacant(e) => { e.insert(field_name.start.clone()); @@ -52,7 +55,8 @@ mod tests { #[test] fn input_object_with_fields() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { field(arg: { f: true }) } @@ -61,7 +65,8 @@ mod tests { #[test] fn same_input_object_within_two_args() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { field(arg1: { f: true }, arg2: { f: true }) } @@ -70,7 +75,8 @@ mod tests { #[test] fn multiple_input_object_fields() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { field(arg: { f1: "value", f2: "value", f3: "value" }) } @@ -79,7 +85,8 @@ mod tests { #[test] fn allows_for_nested_input_objects_with_similar_fields() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { field(arg: { deep: { @@ -96,36 +103,31 @@ mod tests { #[test] fn duplicate_input_object_fields() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { 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)])]); } #[test] fn many_duplicate_input_object_fields() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" { field(arg: { f1: "value", 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(64, 2, 51), - ]), - ]); + &[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(64, 2, 51)])]); } } diff --git a/juniper/src/validation/rules/unique_operation_names.rs b/juniper/src/validation/rules/unique_operation_names.rs index 6e99096b..d7f958d2 100644 --- a/juniper/src/validation/rules/unique_operation_names.rs +++ b/juniper/src/validation/rules/unique_operation_names.rs @@ -9,19 +9,18 @@ pub struct UniqueOperationNames<'a> { } pub fn factory<'a>() -> UniqueOperationNames<'a> { - UniqueOperationNames { - names: HashMap::new(), - } + UniqueOperationNames { names: HashMap::new() } } impl<'a> Visitor<'a> for UniqueOperationNames<'a> { - fn enter_operation_definition(&mut self, ctx: &mut ValidatorContext<'a>, op: &'a Spanning) { + fn enter_operation_definition(&mut self, + ctx: &mut ValidatorContext<'a>, + op: &'a Spanning) { if let Some(ref op_name) = op.item.name { match self.names.entry(op_name.item) { Entry::Occupied(e) => { - ctx.report_error( - &error_message(op_name.item), - &[e.get().clone(), op.start.clone()]); + ctx.report_error(&error_message(op_name.item), + &[e.get().clone(), op.start.clone()]); } Entry::Vacant(e) => { e.insert(op.start.clone()); @@ -44,7 +43,8 @@ mod tests { #[test] fn no_operations() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment fragA on Type { field } @@ -53,7 +53,8 @@ mod tests { #[test] fn one_anon_operation() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" { field } @@ -62,7 +63,8 @@ mod tests { #[test] fn one_named_operation() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo { field } @@ -71,7 +73,8 @@ mod tests { #[test] fn multiple_operations() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo { field } @@ -84,7 +87,8 @@ mod tests { #[test] fn multiple_operations_of_different_types() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo { field } @@ -97,7 +101,8 @@ mod tests { #[test] fn fragment_and_operation_named_the_same() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo { ...Foo } @@ -109,7 +114,8 @@ mod tests { #[test] fn multiple_operations_of_same_name() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Foo { fieldA } @@ -117,17 +123,15 @@ 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)])]); } #[test] fn multiple_ops_of_same_name_of_different_types() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Foo { fieldA } @@ -135,11 +139,8 @@ 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/unique_variable_names.rs b/juniper/src/validation/rules/unique_variable_names.rs index bf81dcc6..73658dce 100644 --- a/juniper/src/validation/rules/unique_variable_names.rs +++ b/juniper/src/validation/rules/unique_variable_names.rs @@ -9,22 +9,23 @@ pub struct UniqueVariableNames<'a> { } pub fn factory<'a>() -> UniqueVariableNames<'a> { - UniqueVariableNames { - names: HashMap::new(), - } + UniqueVariableNames { names: HashMap::new() } } impl<'a> Visitor<'a> for UniqueVariableNames<'a> { - fn enter_operation_definition(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) { + fn enter_operation_definition(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a Spanning) { self.names = HashMap::new(); } - fn enter_variable_definition(&mut self, ctx: &mut ValidatorContext<'a>, &(ref var_name, _): &'a (Spanning<&'a str>, VariableDefinition)) { + fn enter_variable_definition(&mut self, + ctx: &mut ValidatorContext<'a>, + &(ref var_name, _): &'a (Spanning<&'a str>, VariableDefinition)) { match self.names.entry(var_name.item) { Entry::Occupied(e) => { - ctx.report_error( - &error_message(var_name.item), - &[e.get().clone(), var_name.start.clone()]); + ctx.report_error(&error_message(var_name.item), + &[e.get().clone(), var_name.start.clone()]); } Entry::Vacant(e) => { e.insert(var_name.start.clone()); @@ -46,7 +47,8 @@ mod tests { #[test] fn unique_variable_names() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query A($x: Int, $y: String) { __typename } query B($x: String, $y: Int) { __typename } "#); @@ -54,28 +56,23 @@ mod tests { #[test] fn duplicate_variable_names() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query A($x: Int, $x: Int, $x: String) { __typename } query B($x: String, $x: Int) { __typename } query C($x: Int, $x: Int) { __typename } "#, - &[ - RuleError::new(&error_message("x"), &[ - SourcePosition::new(19, 1, 18), - SourcePosition::new(28, 1, 27), - ]), - RuleError::new(&error_message("x"), &[ - SourcePosition::new(19, 1, 18), - SourcePosition::new(37, 1, 36), - ]), - RuleError::new(&error_message("x"), &[ - SourcePosition::new(82, 2, 18), - SourcePosition::new(94, 2, 30), - ]), - RuleError::new(&error_message("x"), &[ - SourcePosition::new(136, 3, 18), - SourcePosition::new(145, 3, 27), - ]), - ]); + &[RuleError::new(&error_message("x"), + &[SourcePosition::new(19, 1, 18), + SourcePosition::new(28, 1, 27)]), + RuleError::new(&error_message("x"), + &[SourcePosition::new(19, 1, 18), + SourcePosition::new(37, 1, 36)]), + RuleError::new(&error_message("x"), + &[SourcePosition::new(82, 2, 18), + SourcePosition::new(94, 2, 30)]), + RuleError::new(&error_message("x"), + &[SourcePosition::new(136, 3, 18), + SourcePosition::new(145, 3, 27)])]); } } diff --git a/juniper/src/validation/rules/variables_are_input_types.rs b/juniper/src/validation/rules/variables_are_input_types.rs index 5137110b..c859ae60 100644 --- a/juniper/src/validation/rules/variables_are_input_types.rs +++ b/juniper/src/validation/rules/variables_are_input_types.rs @@ -9,12 +9,16 @@ pub fn factory() -> UniqueVariableNames { } impl<'a> Visitor<'a> for UniqueVariableNames { - fn enter_variable_definition(&mut self, ctx: &mut ValidatorContext<'a>, &(ref var_name, ref var_def): &'a (Spanning<&'a str>, VariableDefinition)) { - if let Some(var_type) = ctx.schema.concrete_type_by_name(var_def.var_type.item.innermost_name()) { + fn enter_variable_definition(&mut self, + ctx: &mut ValidatorContext<'a>, + &(ref var_name, ref var_def): &'a (Spanning<&'a str>, + VariableDefinition)) { + if let Some(var_type) = ctx.schema + .concrete_type_by_name(var_def.var_type.item.innermost_name()) { if !var_type.is_input() { - ctx.report_error( - &error_message(var_name.item, &format!("{}", var_def.var_type.item)), - &[var_def.var_type.start.clone()]); + ctx.report_error(&error_message(var_name.item, + &format!("{}", var_def.var_type.item)), + &[var_def.var_type.start.clone()]); } } } @@ -33,7 +37,8 @@ mod tests { #[test] fn input_types_are_valid() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Foo($a: String, $b: [Boolean!]!, $c: ComplexInput) { field(a: $a, b: $b, c: $c) } @@ -42,21 +47,17 @@ mod tests { #[test] fn output_types_are_invalid() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Foo($a: Dog, $b: [[CatOrDog!]]!, $c: Pet) { field(a: $a, b: $b, c: $c) } "#, - &[ - RuleError::new(&error_message("a", "Dog"), &[ - SourcePosition::new(25, 1, 24), - ]), - RuleError::new(&error_message("b", "[[CatOrDog!]]!"), &[ - SourcePosition::new(34, 1, 33), - ]), - RuleError::new(&error_message("c", "Pet"), &[ - SourcePosition::new(54, 1, 53), - ]), - ]); + &[RuleError::new(&error_message("a", "Dog"), + &[SourcePosition::new(25, 1, 24)]), + RuleError::new(&error_message("b", "[[CatOrDog!]]!"), + &[SourcePosition::new(34, 1, 33)]), + RuleError::new(&error_message("c", "Pet"), + &[SourcePosition::new(54, 1, 53)])]); } } diff --git a/juniper/src/validation/rules/variables_in_allowed_position.rs b/juniper/src/validation/rules/variables_in_allowed_position.rs index b9f396ce..81e6864f 100644 --- a/juniper/src/validation/rules/variables_in_allowed_position.rs +++ b/juniper/src/validation/rules/variables_in_allowed_position.rs @@ -27,14 +27,11 @@ pub fn factory<'a>() -> VariableInAllowedPosition<'a> { } impl<'a> VariableInAllowedPosition<'a> { - fn collect_incorrect_usages( - &self, - from: &Scope<'a>, - var_defs: &Vec<&'a (Spanning<&'a str>, VariableDefinition)>, - ctx: &mut ValidatorContext<'a>, - visited: &mut HashSet>, - ) - { + fn collect_incorrect_usages(&self, + from: &Scope<'a>, + var_defs: &Vec<&'a (Spanning<&'a str>, VariableDefinition)>, + ctx: &mut ValidatorContext<'a>, + visited: &mut HashSet>) { if visited.contains(from) { return; } @@ -43,10 +40,10 @@ impl<'a> VariableInAllowedPosition<'a> { if let Some(usages) = self.variable_usages.get(from) { for &(ref var_name, ref var_type) in usages { - if let Some(&&(ref var_def_name, ref var_def)) = var_defs - .iter() - .find(|&&&(ref n, _)| &n.item == var_name.item) - { + if let Some(&&(ref var_def_name, ref var_def)) = + var_defs + .iter() + .find(|&&&(ref n, _)| &n.item == var_name.item) { let expected_type = match (&var_def.default_value, &var_def.var_type.item) { (&Some(_), &Type::List(ref inner)) => Type::NonNullList(inner.clone()), (&Some(_), &Type::Named(inner)) => Type::NonNullNamed(inner), @@ -54,9 +51,10 @@ impl<'a> VariableInAllowedPosition<'a> { }; if !ctx.schema.is_subtype(&expected_type, var_type) { - ctx.report_error( - &error_message(var_name.item, &format!("{}", expected_type), &format!("{}", var_type)), - &[var_def_name.start.clone(), var_name.start.clone()]); + ctx.report_error(&error_message(var_name.item, + &format!("{}", expected_type), + &format!("{}", var_type)), + &[var_def_name.start.clone(), var_name.start.clone()]); } } } @@ -77,15 +75,21 @@ impl<'a> Visitor<'a> for VariableInAllowedPosition<'a> { } } - fn enter_fragment_definition(&mut self, _: &mut ValidatorContext<'a>, fragment: &'a Spanning) { + fn enter_fragment_definition(&mut self, + _: &mut ValidatorContext<'a>, + fragment: &'a Spanning) { self.current_scope = Some(Scope::Fragment(fragment.item.name.item)); } - fn enter_operation_definition(&mut self, _: &mut ValidatorContext<'a>, op: &'a Spanning) { + fn enter_operation_definition(&mut self, + _: &mut ValidatorContext<'a>, + op: &'a Spanning) { self.current_scope = Some(Scope::Operation(op.item.name.as_ref().map(|s| s.item))); } - fn enter_fragment_spread(&mut self, _: &mut ValidatorContext<'a>, spread: &'a Spanning) { + fn enter_fragment_spread(&mut self, + _: &mut ValidatorContext<'a>, + spread: &'a Spanning) { if let Some(ref scope) = self.current_scope { self.spreads .entry(scope.clone()) @@ -94,7 +98,9 @@ impl<'a> Visitor<'a> for VariableInAllowedPosition<'a> { } } - fn enter_variable_definition(&mut self, _: &mut ValidatorContext<'a>, def: &'a (Spanning<&'a str>, VariableDefinition)) { + fn enter_variable_definition(&mut self, + _: &mut ValidatorContext<'a>, + def: &'a (Spanning<&'a str>, VariableDefinition)) { if let Some(ref scope) = self.current_scope { self.variable_defs .entry(scope.clone()) @@ -103,12 +109,16 @@ impl<'a> Visitor<'a> for VariableInAllowedPosition<'a> { } } - fn enter_variable_value(&mut self, ctx: &mut ValidatorContext<'a>, var_name: Spanning<&'a String>) { - if let (&Some(ref scope), Some(input_type)) = (&self.current_scope, ctx.current_input_type_literal()) { + fn enter_variable_value(&mut self, + ctx: &mut ValidatorContext<'a>, + var_name: Spanning<&'a String>) { + if let (&Some(ref scope), Some(input_type)) = + (&self.current_scope, ctx.current_input_type_literal()) { self.variable_usages .entry(scope.clone()) .or_insert_with(Vec::new) - .push((Spanning::start_end(&var_name.start, &var_name.end, var_name.item), input_type.clone())); + .push((Spanning::start_end(&var_name.start, &var_name.end, var_name.item), + input_type.clone())); } } } @@ -128,7 +138,8 @@ mod tests { #[test] fn boolean_into_boolean() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Query($booleanArg: Boolean) { complicatedArgs { @@ -140,7 +151,8 @@ mod tests { #[test] fn boolean_into_boolean_within_fragment() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment booleanArgFrag on ComplicatedArgs { booleanArgField(booleanArg: $booleanArg) } @@ -152,7 +164,8 @@ mod tests { } "#); - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Query($booleanArg: Boolean) { complicatedArgs { @@ -167,7 +180,8 @@ mod tests { #[test] fn non_null_boolean_into_boolean() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Query($nonNullBooleanArg: Boolean!) { complicatedArgs { @@ -179,7 +193,8 @@ mod tests { #[test] fn non_null_boolean_into_boolean_within_fragment() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" fragment booleanArgFrag on ComplicatedArgs { booleanArgField(booleanArg: $nonNullBooleanArg) } @@ -195,7 +210,8 @@ mod tests { #[test] fn int_into_non_null_int_with_default() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Query($intArg: Int = 1) { complicatedArgs { @@ -207,7 +223,8 @@ mod tests { #[test] fn string_list_into_string_list() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Query($stringListVar: [String]) { complicatedArgs { @@ -219,7 +236,8 @@ mod tests { #[test] fn non_null_string_list_into_string_list() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Query($stringListVar: [String!]) { complicatedArgs { @@ -231,7 +249,8 @@ mod tests { #[test] fn string_into_string_list_in_item_position() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Query($stringVar: String) { complicatedArgs { @@ -243,7 +262,8 @@ mod tests { #[test] fn non_null_string_into_string_list_in_item_position() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Query($stringVar: String!) { complicatedArgs { @@ -255,7 +275,8 @@ mod tests { #[test] fn complex_input_into_complex_input() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Query($complexVar: ComplexInput) { complicatedArgs { @@ -267,7 +288,8 @@ mod tests { #[test] fn complex_input_into_complex_input_in_field_position() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Query($boolVar: Boolean = false) { complicatedArgs { @@ -279,7 +301,8 @@ mod tests { #[test] fn non_null_boolean_into_non_null_boolean_in_directive() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Query($boolVar: Boolean!) { dog @include(if: $boolVar) @@ -289,7 +312,8 @@ mod tests { #[test] fn boolean_in_non_null_in_directive_with_default() { - expect_passes_rule(factory, r#" + expect_passes_rule(factory, + r#" query Query($boolVar: Boolean = false) { dog @include(if: $boolVar) @@ -299,24 +323,23 @@ mod tests { #[test] fn int_into_non_null_int() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Query($intArg: Int) { complicatedArgs { nonNullIntArgField(nonNullIntArg: $intArg) } } "#, - &[ - 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)])]); } #[test] fn int_into_non_null_int_within_fragment() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment nonNullIntArgFieldFrag on ComplicatedArgs { nonNullIntArgField(nonNullIntArg: $intArg) } @@ -327,17 +350,15 @@ 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)])]); } #[test] fn int_into_non_null_int_within_nested_fragment() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" fragment outerFrag on ComplicatedArgs { ...nonNullIntArgFieldFrag } @@ -352,75 +373,64 @@ 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)])]); } #[test] fn string_over_boolean() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Query($stringVar: String) { complicatedArgs { booleanArgField(booleanArg: $stringVar) } } "#, - &[ - 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)])]); } #[test] fn string_into_string_list() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Query($stringVar: String) { complicatedArgs { stringListArgField(stringListArg: $stringVar) } } "#, - &[ - 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)])]); } #[test] fn boolean_into_non_null_boolean_in_directive() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Query($boolVar: Boolean) { 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)])]); } #[test] fn string_into_non_null_boolean_in_directive() { - expect_fails_rule(factory, r#" + expect_fails_rule(factory, + r#" query Query($stringVar: String) { 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 04b23c76..5a3074f4 100644 --- a/juniper/src/validation/test_harness.rs +++ b/juniper/src/validation/test_harness.rs @@ -59,13 +59,11 @@ impl GraphQLType for Being { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let fields =&[ - registry.field::>("name") - .argument(registry.arg::>("surname")), - ]; + let fields = &[registry + .field::>("name") + .argument(registry.arg::>("surname"))]; - registry.build_interface_type::(fields) - .into_meta() + registry.build_interface_type::(fields).into_meta() } } @@ -77,13 +75,11 @@ impl GraphQLType for Pet { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry.field::>("name") - .argument(registry.arg::>("surname")), - ]; + let fields = &[registry + .field::>("name") + .argument(registry.arg::>("surname"))]; - registry.build_interface_type::(fields) - .into_meta() + registry.build_interface_type::(fields).into_meta() } } @@ -95,13 +91,11 @@ impl GraphQLType for Canine { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry.field::>("name") - .argument(registry.arg::>("surname")), - ]; + let fields = &[registry + .field::>("name") + .argument(registry.arg::>("surname"))]; - registry.build_interface_type::(fields) - .into_meta() + registry.build_interface_type::(fields).into_meta() } } @@ -113,11 +107,11 @@ impl GraphQLType for DogCommand { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - registry.build_enum_type::(&[ - EnumValue::new("SIT"), - EnumValue::new("HEEL"), - EnumValue::new("DOWN"), - ]).into_meta() + registry + .build_enum_type::(&[EnumValue::new("SIT"), + EnumValue::new("HEEL"), + EnumValue::new("DOWN")]) + .into_meta() } } @@ -140,27 +134,28 @@ impl GraphQLType for Dog { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry.field::>("name") - .argument(registry.arg::>("surname")), - registry.field::>("nickname"), - registry.field::>("barkVolume"), - registry.field::>("barks"), - registry.field::>("doesKnowCommand") - .argument(registry.arg::>("dogCommand")), - registry.field::>("isHousetrained") - .argument(registry.arg_with_default("atOtherHomes", &true)), - registry.field::>("isAtLocation") - .argument(registry.arg::>("x")) - .argument(registry.arg::>("y")), - ]; + let fields = &[registry + .field::>("name") + .argument(registry.arg::>("surname")), + registry.field::>("nickname"), + registry.field::>("barkVolume"), + registry.field::>("barks"), + registry + .field::>("doesKnowCommand") + .argument(registry.arg::>("dogCommand")), + registry + .field::>("isHousetrained") + .argument(registry.arg_with_default("atOtherHomes", &true)), + registry + .field::>("isAtLocation") + .argument(registry.arg::>("x")) + .argument(registry.arg::>("y"))]; - registry.build_object_type::(fields) - .interfaces(&[ - registry.get_type::(), - registry.get_type::(), - registry.get_type::(), - ]) + registry + .build_object_type::(fields) + .interfaces(&[registry.get_type::(), + registry.get_type::(), + registry.get_type::()]) .into_meta() } } @@ -173,12 +168,11 @@ impl GraphQLType for FurColor { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - registry.build_enum_type::(&[ - EnumValue::new("BROWN"), - EnumValue::new("BLACK"), - EnumValue::new("TAN"), - EnumValue::new("SPOTTED"), - ]) + registry + .build_enum_type::(&[EnumValue::new("BROWN"), + EnumValue::new("BLACK"), + EnumValue::new("TAN"), + EnumValue::new("SPOTTED")]) .into_meta() } } @@ -203,20 +197,17 @@ impl GraphQLType for Cat { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry.field::>("name") - .argument(registry.arg::>("surname")), - registry.field::>("nickname"), - registry.field::>("meows"), - registry.field::>("meowVolume"), - registry.field::>("furColor"), - ]; + let fields = &[registry + .field::>("name") + .argument(registry.arg::>("surname")), + registry.field::>("nickname"), + registry.field::>("meows"), + registry.field::>("meowVolume"), + registry.field::>("furColor")]; - registry.build_object_type::(fields) - .interfaces(&[ - registry.get_type::(), - registry.get_type::(), - ]) + registry + .build_object_type::(fields) + .interfaces(&[registry.get_type::(), registry.get_type::()]) .into_meta() } } @@ -229,13 +220,9 @@ impl GraphQLType for CatOrDog { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let types = &[ - registry.get_type::(), - registry.get_type::(), - ]; + let types = &[registry.get_type::(), registry.get_type::()]; - registry.build_union_type::(types) - .into_meta() + registry.build_union_type::(types).into_meta() } } @@ -247,12 +234,9 @@ impl GraphQLType for Intelligent { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry.field::>("iq"), - ]; + let fields = &[registry.field::>("iq")]; - registry.build_interface_type::(fields) - .into_meta() + registry.build_interface_type::(fields).into_meta() } } @@ -264,18 +248,16 @@ impl GraphQLType for Human { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry.field::>("name") - .argument(registry.arg::>("surname")), - registry.field::>>>("pets"), - registry.field::>>("relatives"), - registry.field::>("iq"), - ]; - registry.build_object_type::(fields) - .interfaces(&[ - registry.get_type::(), - registry.get_type::(), - ]) + let fields = &[registry + .field::>("name") + .argument(registry.arg::>("surname")), + registry.field::>>>("pets"), + registry.field::>>("relatives"), + registry.field::>("iq")]; + registry + .build_object_type::(fields) + .interfaces(&[registry.get_type::(), + registry.get_type::()]) .into_meta() } } @@ -288,18 +270,16 @@ impl GraphQLType for Alien { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry.field::>("name") - .argument(registry.arg::>("surname")), - registry.field::>("iq"), - registry.field::>("numEyes"), - ]; + let fields = &[registry + .field::>("name") + .argument(registry.arg::>("surname")), + registry.field::>("iq"), + registry.field::>("numEyes")]; - registry.build_object_type::(fields) - .interfaces(&[ - registry.get_type::(), - registry.get_type::(), - ]) + registry + .build_object_type::(fields) + .interfaces(&[registry.get_type::(), + registry.get_type::()]) .into_meta() } } @@ -312,13 +292,9 @@ impl GraphQLType for DogOrHuman { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let types = &[ - registry.get_type::(), - registry.get_type::(), - ]; + let types = &[registry.get_type::(), registry.get_type::()]; - registry.build_union_type::(types) - .into_meta() + registry.build_union_type::(types).into_meta() } } @@ -330,13 +306,9 @@ impl GraphQLType for HumanOrAlien { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let types = &[ - registry.get_type::(), - registry.get_type::(), - ]; + let types = &[registry.get_type::(), registry.get_type::()]; - registry.build_union_type::(types) - .into_meta() + registry.build_union_type::(types).into_meta() } } @@ -348,16 +320,13 @@ impl GraphQLType for ComplexInput { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry.arg::("requiredField"), - registry.arg::>("intField"), - registry.arg::>("stringField"), - registry.arg::>("booleanField"), - registry.arg::>>>("stringListField"), - ]; + let fields = &[registry.arg::("requiredField"), + registry.arg::>("intField"), + registry.arg::>("stringField"), + registry.arg::>("booleanField"), + registry.arg::>>>("stringListField")]; - registry.build_input_object_type::(fields) - .into_meta() + registry.build_input_object_type::(fields).into_meta() } } @@ -369,15 +338,15 @@ impl FromInputValue for ComplexInput { }; Some(ComplexInput { - required_field: match obj.get("requiredField").and_then(|v| v.convert()) { - Some(f) => f, - None => return None, - }, - int_field: obj.get("intField").and_then(|v| v.convert()), - string_field: obj.get("stringField").and_then(|v| v.convert()), - boolean_field: obj.get("booleanField").and_then(|v| v.convert()), - string_list_field: obj.get("stringListField").and_then(|v| v.convert()), - }) + required_field: match obj.get("requiredField").and_then(|v| v.convert()) { + Some(f) => f, + None => return None, + }, + int_field: obj.get("intField").and_then(|v| v.convert()), + string_field: obj.get("stringField").and_then(|v| v.convert()), + boolean_field: obj.get("booleanField").and_then(|v| v.convert()), + string_list_field: obj.get("stringListField").and_then(|v| v.convert()), + }) } } @@ -389,40 +358,50 @@ impl GraphQLType for ComplicatedArgs { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry.field::>("intArgField") - .argument(registry.arg::>("intArg")), - registry.field::>("nonNullIntArgField") - .argument(registry.arg::("nonNullIntArg")), - registry.field::>("stringArgField") - .argument(registry.arg::>("stringArg")), - registry.field::>("booleanArgField") - .argument(registry.arg::>("booleanArg")), - registry.field::>("enumArgField") - .argument(registry.arg::>("enumArg")), - registry.field::>("floatArgField") - .argument(registry.arg::>("floatArg")), - registry.field::>("idArgField") - .argument(registry.arg::>("idArg")), - registry.field::>("stringListArgField") - .argument(registry.arg::>>>("stringListArg")), - registry.field::>("complexArgField") - .argument(registry.arg::>("complexArg")), - registry.field::>("multipleReqs") - .argument(registry.arg::("req1")) - .argument(registry.arg::("req2")), - registry.field::>("multipleOpts") - .argument(registry.arg_with_default("opt1", &0i32)) - .argument(registry.arg_with_default("opt2", &0i32)), - registry.field::>("multipleOptAndReq") - .argument(registry.arg::("req1")) - .argument(registry.arg::("req2")) - .argument(registry.arg_with_default("opt1", &0i32)) - .argument(registry.arg_with_default("opt2", &0i32)), - ]; + let fields = + &[registry + .field::>("intArgField") + .argument(registry.arg::>("intArg")), + registry + .field::>("nonNullIntArgField") + .argument(registry.arg::("nonNullIntArg")), + registry + .field::>("stringArgField") + .argument(registry.arg::>("stringArg")), + registry + .field::>("booleanArgField") + .argument(registry.arg::>("booleanArg")), + registry + .field::>("enumArgField") + .argument(registry.arg::>("enumArg")), + registry + .field::>("floatArgField") + .argument(registry.arg::>("floatArg")), + registry + .field::>("idArgField") + .argument(registry.arg::>("idArg")), + registry + .field::>("stringListArgField") + .argument(registry.arg::>>>("stringListArg")), + registry + .field::>("complexArgField") + .argument(registry.arg::>("complexArg")), + registry + .field::>("multipleReqs") + .argument(registry.arg::("req1")) + .argument(registry.arg::("req2")), + registry + .field::>("multipleOpts") + .argument(registry.arg_with_default("opt1", &0i32)) + .argument(registry.arg_with_default("opt2", &0i32)), + registry + .field::>("multipleOptAndReq") + .argument(registry.arg::("req1")) + .argument(registry.arg::("req2")) + .argument(registry.arg_with_default("opt1", &0i32)) + .argument(registry.arg_with_default("opt2", &0i32))]; - registry.build_object_type::(fields) - .into_meta() + registry.build_object_type::(fields).into_meta() } } @@ -434,44 +413,50 @@ impl GraphQLType for QueryRoot { } fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> { - let fields = &[ - registry.field::>("human") - .argument(registry.arg::>("id")), - registry.field::>("alien"), - registry.field::>("dog"), - registry.field::>("cat"), - registry.field::>("pet"), - registry.field::>("catOrDog"), - registry.field::>("dorOrHuman"), - registry.field::>("humanOrAlien"), - registry.field::>("complicatedArgs"), - ]; + let fields = &[registry + .field::>("human") + .argument(registry.arg::>("id")), + registry.field::>("alien"), + registry.field::>("dog"), + registry.field::>("cat"), + registry.field::>("pet"), + registry.field::>("catOrDog"), + registry.field::>("dorOrHuman"), + registry.field::>("humanOrAlien"), + registry.field::>("complicatedArgs")]; - registry.build_object_type::(fields) - .into_meta() + registry.build_object_type::(fields).into_meta() } } -pub fn validate<'a, R, V, F>(r: R, q: &'a str, factory: F) - -> Vec +pub fn validate<'a, R, V, F>(r: R, q: &'a str, factory: F) -> Vec where R: GraphQLType, V: Visitor<'a> + 'a, F: Fn() -> V { let mut root = RootNode::new(r, EmptyMutation::<()>::new()); - root.schema.add_directive(DirectiveType::new("onQuery", &[DirectiveLocation::Query], &[])); - root.schema.add_directive(DirectiveType::new("onMutation", &[DirectiveLocation::Mutation], &[])); - root.schema.add_directive(DirectiveType::new("onField", &[DirectiveLocation::Field], &[])); - root.schema.add_directive(DirectiveType::new("onFragmentDefinition", &[DirectiveLocation::FragmentDefinition], &[])); - root.schema.add_directive(DirectiveType::new("onFragmentSpread", &[DirectiveLocation::FragmentSpread], &[])); - root.schema.add_directive(DirectiveType::new("onInlineFragment", &[DirectiveLocation::InlineFragment], &[])); + root.schema + .add_directive(DirectiveType::new("onQuery", &[DirectiveLocation::Query], &[])); + root.schema + .add_directive(DirectiveType::new("onMutation", &[DirectiveLocation::Mutation], &[])); + root.schema + .add_directive(DirectiveType::new("onField", &[DirectiveLocation::Field], &[])); + root.schema + .add_directive(DirectiveType::new("onFragmentDefinition", + &[DirectiveLocation::FragmentDefinition], + &[])); + root.schema + .add_directive(DirectiveType::new("onFragmentSpread", + &[DirectiveLocation::FragmentSpread], + &[])); + root.schema + .add_directive(DirectiveType::new("onInlineFragment", + &[DirectiveLocation::InlineFragment], + &[])); - let doc = parse_document_source(q) - .expect(&format!("Parse error on input {:#?}", q)); - let mut ctx = ValidatorContext::new( - unsafe { ::std::mem::transmute(&root.schema) }, - &doc); + let doc = parse_document_source(q).expect(&format!("Parse error on input {:#?}", q)); + let mut ctx = ValidatorContext::new(unsafe { ::std::mem::transmute(&root.schema) }, &doc); let mut mv = MultiVisitorNil.with(factory()); visit(&mut mv, &mut ctx, unsafe { ::std::mem::transmute(&doc) }); @@ -506,7 +491,10 @@ pub fn expect_fails_rule<'a, V, F>(factory: F, q: &'a str, expected_errors: &[Ru expect_fails_rule_with_schema(QueryRoot, factory, q, expected_errors); } -pub fn expect_fails_rule_with_schema<'a, R, V, F>(r: R, factory: F, q: &'a str, expected_errors: &[RuleError]) +pub fn expect_fails_rule_with_schema<'a, R, V, F>(r: R, + factory: F, + q: &'a str, + expected_errors: &[RuleError]) where R: GraphQLType, V: Visitor<'a> + 'a, F: Fn() -> V @@ -515,8 +503,7 @@ pub fn expect_fails_rule_with_schema<'a, R, V, F>(r: R, factory: F, q: &'a str, if errs.is_empty() { panic!("Expected rule to fail, but no errors were found"); - } - else if errs != expected_errors { + } else if errs != expected_errors { println!("==> Expected errors:"); print_errors(expected_errors); diff --git a/juniper/src/validation/traits.rs b/juniper/src/validation/traits.rs index b8c531a4..35f2c0cc 100644 --- a/juniper/src/validation/traits.rs +++ b/juniper/src/validation/traits.rs @@ -1,5 +1,5 @@ -use ast::{Document, Operation, Fragment, VariableDefinition, Selection, - Directive, InputValue, Field, FragmentSpread, InlineFragment}; +use ast::{Document, Operation, Fragment, VariableDefinition, Selection, Directive, InputValue, + Field, FragmentSpread, InlineFragment}; use parser::Spanning; use validation::ValidatorContext; @@ -9,20 +9,44 @@ pub trait Visitor<'a> { fn enter_document(&mut self, _: &mut ValidatorContext<'a>, _: &'a Document) {} fn exit_document(&mut self, _: &mut ValidatorContext<'a>, _: &'a Document) {} - fn enter_operation_definition(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) {} - fn exit_operation_definition(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) {} + fn enter_operation_definition(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a Spanning) { + } + fn exit_operation_definition(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a Spanning) { + } - fn enter_fragment_definition(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) {} - fn exit_fragment_definition(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) {} + fn enter_fragment_definition(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a Spanning) { + } + fn exit_fragment_definition(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a Spanning) { + } - fn enter_variable_definition(&mut self, _: &mut ValidatorContext<'a>, _: &'a (Spanning<&'a str>, VariableDefinition)) {} - fn exit_variable_definition(&mut self, _: &mut ValidatorContext<'a>, _: &'a (Spanning<&'a str>, VariableDefinition)) {} + fn enter_variable_definition(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a (Spanning<&'a str>, VariableDefinition)) { + } + fn exit_variable_definition(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a (Spanning<&'a str>, VariableDefinition)) { + } fn enter_directive(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) {} fn exit_directive(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) {} - fn enter_argument(&mut self, _: &mut ValidatorContext<'a>, _: &'a (Spanning<&'a str>, Spanning)) {} - fn exit_argument(&mut self, _: &mut ValidatorContext<'a>, _: &'a (Spanning<&'a str>, Spanning)) {} + fn enter_argument(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a (Spanning<&'a str>, Spanning)) { + } + fn exit_argument(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a (Spanning<&'a str>, Spanning)) { + } fn enter_selection_set(&mut self, _: &mut ValidatorContext<'a>, _: &'a Vec) {} fn exit_selection_set(&mut self, _: &mut ValidatorContext<'a>, _: &'a Vec) {} @@ -30,11 +54,23 @@ pub trait Visitor<'a> { fn enter_field(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) {} fn exit_field(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) {} - fn enter_fragment_spread(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) {} - fn exit_fragment_spread(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) {} + fn enter_fragment_spread(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a Spanning) { + } + fn exit_fragment_spread(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a Spanning) { + } - fn enter_inline_fragment(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) {} - fn exit_inline_fragment(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning) {} + fn enter_inline_fragment(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a Spanning) { + } + fn exit_inline_fragment(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a Spanning) { + } fn enter_null_value(&mut self, _: &mut ValidatorContext<'a>, _: Spanning<()>) {} fn exit_null_value(&mut self, _: &mut ValidatorContext<'a>, _: Spanning<()>) {} @@ -57,12 +93,30 @@ pub trait Visitor<'a> { fn enter_variable_value(&mut self, _: &mut ValidatorContext<'a>, _: Spanning<&'a String>) {} fn exit_variable_value(&mut self, _: &mut ValidatorContext<'a>, _: Spanning<&'a String>) {} - fn enter_list_value(&mut self, _: &mut ValidatorContext<'a>, _: Spanning<&'a Vec>>) {} - fn exit_list_value(&mut self, _: &mut ValidatorContext<'a>, _: Spanning<&'a Vec>>) {} + fn enter_list_value(&mut self, + _: &mut ValidatorContext<'a>, + _: Spanning<&'a Vec>>) { + } + fn exit_list_value(&mut self, + _: &mut ValidatorContext<'a>, + _: Spanning<&'a Vec>>) { + } - fn enter_object_value(&mut self, _: &mut ValidatorContext<'a>, _: Spanning<&'a Vec<(Spanning, Spanning)>>) {} - fn exit_object_value(&mut self, _: &mut ValidatorContext<'a>, _: Spanning<&'a Vec<(Spanning, Spanning)>>) {} + fn enter_object_value(&mut self, + _: &mut ValidatorContext<'a>, + _: Spanning<&'a Vec<(Spanning, Spanning)>>) { + } + fn exit_object_value(&mut self, + _: &mut ValidatorContext<'a>, + _: Spanning<&'a Vec<(Spanning, Spanning)>>) { + } - fn enter_object_field(&mut self, _: &mut ValidatorContext<'a>, _: &'a (Spanning, Spanning)) {} - fn exit_object_field(&mut self, _: &mut ValidatorContext<'a>, _: &'a (Spanning, Spanning)) {} + fn enter_object_field(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a (Spanning, Spanning)) { + } + fn exit_object_field(&mut self, + _: &mut ValidatorContext<'a>, + _: &'a (Spanning, Spanning)) { + } } diff --git a/juniper/src/validation/visitor.rs b/juniper/src/validation/visitor.rs index 92b926d1..1e97b1e0 100644 --- a/juniper/src/validation/visitor.rs +++ b/juniper/src/validation/visitor.rs @@ -1,6 +1,5 @@ -use ast::{Definition, Document, Fragment, VariableDefinitions, Type, InputValue, - Directive, Arguments, Selection, Field, FragmentSpread, InlineFragment, - Operation, OperationType}; +use ast::{Definition, Document, Fragment, VariableDefinitions, Type, InputValue, Directive, + Arguments, Selection, Field, FragmentSpread, InlineFragment, Operation, OperationType}; use schema::meta::Argument; use parser::Spanning; use validation::{Visitor, ValidatorContext}; @@ -12,19 +11,31 @@ pub fn visit<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a>, d: & v.exit_document(ctx, d); } -fn visit_definitions<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a>, d: &'a Vec) { +fn visit_definitions<'a, V: Visitor<'a>>(v: &mut V, + ctx: &mut ValidatorContext<'a>, + d: &'a Vec) { for def in d { - let def_type = match *def { + let def_type = + match *def { Definition::Fragment(Spanning { - item: Fragment { type_condition: Spanning { item: name, .. }, .. }, .. }) => - Some(Type::NonNullNamed(name)), + item: Fragment { + type_condition: Spanning { item: name, .. }, .. + }, + .. + }) => Some(Type::NonNullNamed(name)), Definition::Operation(Spanning { item: Operation { operation_type: OperationType::Query, .. }, .. }) => Some(Type::NonNullNamed(ctx.schema.concrete_query_type().name().unwrap())), Definition::Operation(Spanning { - item: Operation { operation_type: OperationType::Mutation, .. }, .. }) => - ctx.schema.concrete_mutation_type() - .map(|t| Type::NonNullNamed(t.name().unwrap())), + item: Operation { + operation_type: OperationType::Mutation, .. + }, + .. + }) => { + ctx.schema + .concrete_mutation_type() + .map(|t| Type::NonNullNamed(t.name().unwrap())) + } }; ctx.with_pushed_type(def_type.as_ref(), |ctx| { @@ -35,35 +46,43 @@ fn visit_definitions<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<' } } -fn enter_definition<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a>, def: &'a Definition) { +fn enter_definition<'a, V: Visitor<'a>>(v: &mut V, + ctx: &mut ValidatorContext<'a>, + def: &'a Definition) { match *def { Definition::Operation(ref op) => v.enter_operation_definition(ctx, op), Definition::Fragment(ref f) => v.enter_fragment_definition(ctx, f), } } -fn exit_definition<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a>, def: &'a Definition) { +fn exit_definition<'a, V: Visitor<'a>>(v: &mut V, + ctx: &mut ValidatorContext<'a>, + def: &'a Definition) { match *def { Definition::Operation(ref op) => v.exit_operation_definition(ctx, op), Definition::Fragment(ref f) => v.exit_fragment_definition(ctx, f), } } -fn visit_definition<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a>, def: &'a Definition) { +fn visit_definition<'a, V: Visitor<'a>>(v: &mut V, + ctx: &mut ValidatorContext<'a>, + def: &'a Definition) { match *def { Definition::Operation(ref op) => { visit_variable_definitions(v, ctx, &op.item.variable_definitions); visit_directives(v, ctx, &op.item.directives); visit_selection_set(v, ctx, &op.item.selection_set); - }, + } Definition::Fragment(ref f) => { visit_directives(v, ctx, &f.item.directives); visit_selection_set(v, ctx, &f.item.selection_set); - }, + } } } -fn visit_variable_definitions<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a>, defs: &'a Option>) { +fn visit_variable_definitions<'a, V: Visitor<'a>>(v: &mut V, + ctx: &mut ValidatorContext<'a>, + defs: &'a Option>) { if let Some(ref defs) = *defs { for def in defs.item.iter() { let var_type = def.1.var_type.item.clone(); @@ -81,10 +100,14 @@ fn visit_variable_definitions<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut Validator } } -fn visit_directives<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a>, directives: &'a Option>>) { +fn visit_directives<'a, V: Visitor<'a>>(v: &mut V, + ctx: &mut ValidatorContext<'a>, + directives: &'a Option>>) { if let Some(ref directives) = *directives { for directive in directives { - let directive_arguments = ctx.schema.directive_by_name(directive.item.name.item).map(|d| &d.arguments); + let directive_arguments = ctx.schema + .directive_by_name(directive.item.name.item) + .map(|d| &d.arguments); v.enter_directive(ctx, directive); visit_arguments(v, ctx, &directive_arguments, &directive.item.arguments); @@ -93,7 +116,10 @@ fn visit_directives<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a } } -fn visit_arguments<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a>, meta_args: &Option<&Vec>>, arguments: &'a Option>) { +fn visit_arguments<'a, V: Visitor<'a>>(v: &mut V, + ctx: &mut ValidatorContext<'a>, + meta_args: &Option<&Vec>>, + arguments: &'a Option>) { if let Some(ref arguments) = *arguments { for argument in arguments.item.iter() { let arg_type = meta_args @@ -111,7 +137,9 @@ fn visit_arguments<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a> } } -fn visit_selection_set<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a>, selection_set: &'a Vec) { +fn visit_selection_set<'a, V: Visitor<'a>>(v: &mut V, + ctx: &mut ValidatorContext<'a>, + selection_set: &'a Vec) { ctx.with_pushed_parent_type(|ctx| { v.enter_selection_set(ctx, selection_set); @@ -123,7 +151,9 @@ fn visit_selection_set<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext }); } -fn visit_selection<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a>, selection: &'a Selection) { +fn visit_selection<'a, V: Visitor<'a>>(v: &mut V, + ctx: &mut ValidatorContext<'a>, + selection: &'a Selection) { match *selection { Selection::Field(ref field) => visit_field(v, ctx, field), Selection::FragmentSpread(ref spread) => visit_fragment_spread(v, ctx, spread), @@ -131,7 +161,9 @@ fn visit_selection<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a> } } -fn visit_field<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a>, field: &'a Spanning) { +fn visit_field<'a, V: Visitor<'a>>(v: &mut V, + ctx: &mut ValidatorContext<'a>, + field: &'a Spanning) { let meta_field = ctx.parent_type() .and_then(|t| t.field_by_name(field.item.name.item)); @@ -152,7 +184,9 @@ fn visit_field<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a>, fi }); } -fn visit_fragment_spread<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a>, spread: &'a Spanning) { +fn visit_fragment_spread<'a, V: Visitor<'a>>(v: &mut V, + ctx: &mut ValidatorContext<'a>, + spread: &'a Spanning) { v.enter_fragment_spread(ctx, spread); visit_directives(v, ctx, &spread.item.directives); @@ -160,7 +194,9 @@ fn visit_fragment_spread<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorConte v.exit_fragment_spread(ctx, spread); } -fn visit_inline_fragment<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a>, fragment: &'a Spanning) { +fn visit_inline_fragment<'a, V: Visitor<'a>>(v: &mut V, + ctx: &mut ValidatorContext<'a>, + fragment: &'a Spanning) { let mut visit_fn = move |ctx: &mut ValidatorContext<'a>| { v.enter_inline_fragment(ctx, fragment); @@ -172,13 +208,14 @@ fn visit_inline_fragment<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorConte if let Some(Spanning { item: type_name, .. }) = fragment.item.type_condition { ctx.with_pushed_type(Some(&Type::NonNullNamed(type_name)), visit_fn); - } - else { + } else { visit_fn(ctx); } } -fn visit_input_value<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a>, input_value: &'a Spanning) { +fn visit_input_value<'a, V: Visitor<'a>>(v: &mut V, + ctx: &mut ValidatorContext<'a>, + input_value: &'a Spanning) { enter_input_value(v, ctx, input_value); match input_value.item { @@ -186,10 +223,10 @@ fn visit_input_value<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<' for field in fields { let inner_type = ctx.current_input_type_literal() .and_then(|t| match *t { - Type::NonNullNamed(name) | Type::Named(name) => - ctx.schema.concrete_type_by_name(name), - _ => None, - }) + Type::NonNullNamed(name) | + Type::Named(name) => ctx.schema.concrete_type_by_name(name), + _ => None, + }) .and_then(|ct| ct.input_field_by_name(&field.0.item)) .map(|f| &f.arg_type); @@ -201,16 +238,15 @@ fn visit_input_value<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<' } } InputValue::List(ref ls) => { - let inner_type = ctx.current_input_type_literal().and_then(|t| match *t { - Type::List(ref inner) | Type::NonNullList(ref inner) => - Some(inner.as_ref().clone()), - _ => None, - }); + let inner_type = ctx.current_input_type_literal() + .and_then(|t| match *t { + Type::List(ref inner) | + Type::NonNullList(ref inner) => Some(inner.as_ref().clone()), + _ => None, + }); - ctx.with_pushed_input_type(inner_type.as_ref(), |ctx| { - for value in ls { - visit_input_value(v, ctx, value); - } + ctx.with_pushed_input_type(inner_type.as_ref(), |ctx| for value in ls { + visit_input_value(v, ctx, value); }) } _ => (), @@ -219,7 +255,9 @@ fn visit_input_value<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<' exit_input_value(v, ctx, input_value); } -fn enter_input_value<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a>, input_value: &'a Spanning) { +fn enter_input_value<'a, V: Visitor<'a>>(v: &mut V, + ctx: &mut ValidatorContext<'a>, + input_value: &'a Spanning) { use InputValue::*; let start = &input_value.start; @@ -238,7 +276,9 @@ fn enter_input_value<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<' } } -fn exit_input_value<'a, V: Visitor<'a>>(v: &mut V, ctx: &mut ValidatorContext<'a>, input_value: &'a Spanning) { +fn exit_input_value<'a, V: Visitor<'a>>(v: &mut V, + ctx: &mut ValidatorContext<'a>, + input_value: &'a Spanning) { use InputValue::*; let start = &input_value.start; diff --git a/juniper/src/value.rs b/juniper/src/value.rs index 80809bd4..44a6944d 100644 --- a/juniper/src/value.rs +++ b/juniper/src/value.rs @@ -29,30 +29,40 @@ impl Value { // CONSTRUCTORS /// Construct a null value. - pub fn null() -> Value { Value::Null } + pub fn null() -> Value { + Value::Null + } /// Construct an integer value. - pub fn int(i: i32) -> Value { Value::Int(i) } + pub fn int(i: i32) -> Value { + Value::Int(i) + } /// Construct a floating point value. - pub fn float(f: f64) -> Value { Value::Float(f) } + pub fn float(f: f64) -> Value { + Value::Float(f) + } /// Construct a string value. - pub fn string>(s: T) -> Value { Value::String(s.as_ref().to_owned()) } + pub fn string>(s: T) -> Value { + Value::String(s.as_ref().to_owned()) + } /// Construct a boolean value. - pub fn boolean(b: bool) -> Value { Value::Boolean(b) } + pub fn boolean(b: bool) -> Value { + Value::Boolean(b) + } /// Construct a list value. - pub fn list(l: Vec) -> Value { Value::List(l) } + pub fn list(l: Vec) -> Value { + Value::List(l) + } /// Construct an object value. pub fn object(o: HashMap) -> Value where K: Into + Eq + Hash { - Value::Object( - o.into_iter().map(|(k, v)| (k.into(), v)).collect() - ) + Value::Object(o.into_iter().map(|(k, v)| (k.into(), v)).collect()) } // DISCRIMINATORS @@ -106,10 +116,17 @@ impl ToInputValue for Value { Value::Float(f) => InputValue::Float(f), Value::String(ref s) => InputValue::String(s.clone()), Value::Boolean(b) => InputValue::Boolean(b), - Value::List(ref l) => InputValue::List(l.iter().map(|x| - Spanning::unlocated(x.to())).collect()), - Value::Object(ref o) => InputValue::Object(o.iter().map(|(k,v)| - (Spanning::unlocated(k.clone()), Spanning::unlocated(v.to()))).collect()), + Value::List(ref l) => { + InputValue::List(l.iter().map(|x| Spanning::unlocated(x.to())).collect()) + } + Value::Object(ref o) => { + InputValue::Object(o.iter() + .map(|(k, v)| { + (Spanning::unlocated(k.clone()), + Spanning::unlocated(v.to())) + }) + .collect()) + } } } } diff --git a/juniper_iron/Cargo.toml b/juniper_iron/Cargo.toml new file mode 100644 index 00000000..8ca5dde8 --- /dev/null +++ b/juniper_iron/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "juniper_iron" +version = "0.1.0" +authors = ["Magnus Hallin "] +description = "Iron integration for juniper" +license = "BSD-2-Clause" +documentation = "https://docs.rs/juniper_iron" +repository = "https://github.com/mhallin/juniper" + +[dependencies] +serde = { version = "^1.0.2" } +serde_json = { version = "^1.0.2" } +urlencoded = { version = "^0.5.0" } +iron = "^0.5.1" +juniper = { version = "0.8.1", path = "../juniper" } + +[dev-dependencies] +iron-test = "^0.5.0" +router = "^0.5.0" +mount = "^0.3.0" +logger = "^0.3.0" +juniper = { version = "0.8.1", path = "../juniper" , features = ["expose-test-schema", "serde_json"] } + +[badges] +travis-ci = { repository = "mhallin/juniper" } +appveyor = { repository = "mhallin/juniper" } diff --git a/juniper/examples/server.rs b/juniper_iron/examples/iron_server.rs similarity index 92% rename from juniper/examples/server.rs rename to juniper_iron/examples/iron_server.rs index a68d63ef..9fa4f0ab 100644 --- a/juniper/examples/server.rs +++ b/juniper_iron/examples/iron_server.rs @@ -3,6 +3,7 @@ extern crate mount; extern crate logger; extern crate serde; extern crate juniper; +extern crate juniper_iron; use std::env; @@ -10,7 +11,7 @@ use mount::Mount; use logger::Logger; use iron::prelude::*; use juniper::EmptyMutation; -use juniper::iron_handlers::{GraphQLHandler, GraphiQLHandler}; +use juniper_iron::{GraphQLHandler, GraphiQLHandler}; use juniper::tests::model::Database; fn context_factory(_: &mut Request) -> Database { diff --git a/juniper/src/integrations/iron_handlers.rs b/juniper_iron/src/lib.rs similarity index 69% rename from juniper/src/integrations/iron_handlers.rs rename to juniper_iron/src/lib.rs index 97567aa5..89aab940 100644 --- a/juniper/src/integrations/iron_handlers.rs +++ b/juniper_iron/src/lib.rs @@ -1,7 +1,103 @@ -//! Optional handlers for the [Iron](http://ironframework.io) framework. Requires the `iron-handlers` feature enabled. -//! -//! See the [server.rs](https://github.com/mhallin/juniper/blob/master/examples/server.rs) -//! example for more information on how to use these handlers. +/*! + +[Juniper][1] handlers for the [Iron][2] framework. + +## Integrating with Iron + + + +For example, continuing from the schema created above and using Iron to expose +the schema on an HTTP endpoint supporting both GET and POST requests: + +```rust,no_run +extern crate iron; +# #[macro_use] extern crate juniper; +# extern crate juniper_iron; +# use std::collections::HashMap; + +use iron::prelude::*; +use juniper_iron::GraphQLHandler; +use juniper::{Context, EmptyMutation}; + +# use juniper::FieldResult; +# +# struct User { id: String, name: String, friend_ids: Vec } +# struct QueryRoot; +# struct Database { users: HashMap } +# +# graphql_object!(User: Database |&self| { +# field id() -> FieldResult<&String> { +# Ok(&self.id) +# } +# +# field name() -> FieldResult<&String> { +# Ok(&self.name) +# } +# +# field friends(&executor) -> FieldResult> { +# Ok(self.friend_ids.iter() +# .filter_map(|id| executor.context().users.get(id)) +# .collect()) +# } +# }); +# +# graphql_object!(QueryRoot: Database |&self| { +# field user(&executor, id: String) -> FieldResult> { +# Ok(executor.context().users.get(&id)) +# } +# }); + +// This function is executed for every request. Here, we would realistically +// provide a database connection or similar. For this example, we'll be +// creating the database from scratch. +fn context_factory(_: &mut Request) -> Database { + Database { + users: vec![ + ( "1000".to_owned(), User { + id: "1000".to_owned(), name: "Robin".to_owned(), + friend_ids: vec!["1001".to_owned()] } ), + ( "1001".to_owned(), User { + id: "1001".to_owned(), name: "Max".to_owned(), + friend_ids: vec!["1000".to_owned()] } ), + ].into_iter().collect() + } +} + +impl Context for Database {} + +fn main() { + // GraphQLHandler takes a context factory function, the root object, + // and the mutation object. If we don't have any mutations to expose, we + // can use the empty tuple () to indicate absence. + let graphql_endpoint = GraphQLHandler::new( + context_factory, QueryRoot, EmptyMutation::::new()); + + // Start serving the schema at the root on port 8080. + Iron::new(graphql_endpoint).http("localhost:8080").unwrap(); +} + +``` + +See the [iron_server.rs][5] +example for more information on how to use these handlers. + +See the the [`GraphQLHandler`][3] documentation for more information on what request methods are +supported. +There's also a built-in [GraphiQL][4] handler included. + +[1]: https://github.com/mhallin/Juniper +[2]: http://ironframework.io +[3]: ./struct.GraphQLHandler.html +[4]: https://github.com/graphql/graphiql +[5]: https://github.com/mhallin/juniper/blob/master/juniper_iron/examples/iron_server.rs + +*/ + +extern crate serde_json; +extern crate juniper; +extern crate urlencoded; +#[macro_use] extern crate iron; +#[cfg(test)] extern crate iron_test; use iron::prelude::*; use iron::middleware::Handler; @@ -14,11 +110,10 @@ use std::io::Read; use std::error::Error; use std::fmt; -use serde_json; use serde_json::error::Error as SerdeError; -use ::{InputValue, GraphQLType, RootNode}; -use ::http; +use juniper::{InputValue, GraphQLType, RootNode}; +use juniper::http; /// Handler that executes GraphQL queries in the given schema /// @@ -50,18 +145,18 @@ fn get_single_value(mut values: Vec) -> IronResult { if values.len() == 1 { Ok(values.remove(0)) } - else { - Err(GraphQLIronError::InvalidData("Duplicate URL query parameter").into()) - } + else { + Err(GraphQLIronError::InvalidData("Duplicate URL query parameter").into()) + } } fn parse_url_param(params: Option>) -> IronResult> { if let Some(values) = params { get_single_value(values).map(Some) } - else { - Ok(None) - } + else { + Ok(None) + } } fn parse_variable_param(params: Option>) -> IronResult> { @@ -70,14 +165,14 @@ fn parse_variable_param(params: Option>) -> IronResult - GraphQLHandler<'a, CtxFactory, Query, Mutation, CtxT> +GraphQLHandler<'a, CtxFactory, Query, Mutation, CtxT> where CtxFactory: Fn(&mut Request) -> CtxT + Send + Sync + 'static, CtxT: 'static, Query: GraphQLType + Send + Sync + 'static, @@ -100,7 +195,7 @@ impl<'a, CtxFactory, Query, Mutation, CtxT> fn handle_get(&self, req: &mut Request) -> IronResult { let url_query_string = req.get_mut::() .map_err(|e| GraphQLIronError::Url(e))?; - + let input_query = parse_url_param(url_query_string.remove("query"))? .ok_or_else(|| GraphQLIronError::InvalidData("No query provided"))?; let operation_name = parse_url_param(url_query_string.remove("operationName"))?; @@ -112,7 +207,7 @@ impl<'a, CtxFactory, Query, Mutation, CtxT> fn handle_post(&self, req: &mut Request) -> IronResult { let mut request_payload = String::new(); itry!(req.body.read_to_string(&mut request_payload)); - + Ok(serde_json::from_str::(request_payload.as_str()) .map_err(|err| GraphQLIronError::Serde(err))?) } @@ -142,8 +237,8 @@ impl GraphiQLHandler { } impl<'a, CtxFactory, Query, Mutation, CtxT> - Handler - for GraphQLHandler<'a, CtxFactory, Query, Mutation, CtxT> +Handler +for GraphQLHandler<'a, CtxFactory, Query, Mutation, CtxT> where CtxFactory: Fn(&mut Request) -> CtxT + Send + Sync + 'static, CtxT: 'static, Query: GraphQLType + Send + Sync + 'static, @@ -169,7 +264,7 @@ impl Handler for GraphiQLHandler { Ok(Response::with(( content_type, status::Ok, - ::graphiql::graphiql_source(&self.graphql_url), + juniper::graphiql::graphiql_source(&self.graphql_url), ))) } } @@ -193,11 +288,11 @@ impl fmt::Display for GraphQLIronError { impl Error for GraphQLIronError { fn description(&self) -> &str { - match *self { - GraphQLIronError::Serde(ref err) => err.description(), - GraphQLIronError::Url(ref err) => err.description(), - GraphQLIronError::InvalidData(ref err) => err, - } + match *self { + GraphQLIronError::Serde(ref err) => err.description(), + GraphQLIronError::Url(ref err) => err.description(), + GraphQLIronError::InvalidData(ref err) => err, + } } fn cause(&self) -> Option<&Error> { @@ -216,16 +311,15 @@ impl From for IronError { } } - #[cfg(test)] mod tests { use iron::prelude::*; use iron_test::{request, response}; use iron::{Handler, Headers}; - use ::tests::model::Database; + use juniper::tests::model::Database; use ::http::tests as http_tests; - use types::scalars::EmptyMutation; + use juniper::EmptyMutation; use super::GraphQLHandler; diff --git a/juniper_rocket/Cargo.toml b/juniper_rocket/Cargo.toml new file mode 100644 index 00000000..67b73e43 --- /dev/null +++ b/juniper_rocket/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "juniper_rocket" +version = "0.0.1" +authors = ["Magnus Hallin "] +description = "Juniper GraphQL integration with Rocket" +license = "BSD-2-Clause" +documentation = "https://docs.rs/juniper_rocket" +repository = "https://github.com/mhallin/juniper" + +[dependencies] +serde = { version = "^1.0.8" } +serde_derive = {version="^1.0.8" } +serde_json = { version = "^1.0.2" } +rocket = { version = "^0.3.0" } +rocket_codegen = { version = "^0.3.0" } +juniper = { version = "0.8.1", path = "../juniper" } +juniper_codegen = { version = "0.8.1", path = "../juniper_codegen" } + +[badges] +travis-ci = { repository = "mhallin/juniper" } +appveyor = { repository = "mhallin/juniper" } + +[dev-dependencies] +juniper = { version = "0.8.1", path = "../juniper", features=["expose-test-schema", "serde_json"] } diff --git a/juniper_rocket/Makefile.toml b/juniper_rocket/Makefile.toml new file mode 100644 index 00000000..d01df41f --- /dev/null +++ b/juniper_rocket/Makefile.toml @@ -0,0 +1,41 @@ +[tasks.build-verbose] +command = "cargo" +args = ["build", "--verbose"] +condition_script = [ +''' +if [ "$CARGO_MAKE_RUST_CHANNEL" = "nightly" ]; then + exit 0 +else + exit 1 +fi +''' +] + +[tasks.build-verbose.windows] +command = "cargo" +args = ["build", "--verbose"] +condition_script = [ + '''IF "%CARGO_MAKE_RUST_CHANNEL%"=="nightly" (exit 0) ELSE (exit 1)''' +] + +[tasks.test-verbose] +command = "cargo" +args = ["test", "--verbose"] +dependencies = ["build-verbose"] +condition_script = [ +''' +if [ "$CARGO_MAKE_RUST_CHANNEL" = "nightly" ]; then + exit 0 +else + exit 1 +fi +''' +] + +[tasks.test-verbose.windows] +command = "cargo" +args = ["test", "--verbose"] +dependencies = ["build-verbose"] +condition_script = [ + '''IF "%CARGO_MAKE_RUST_CHANNEL%"=="nightly" (exit 0) ELSE (exit 1)''' +] diff --git a/juniper/examples/rocket-server.rs b/juniper_rocket/examples/rocket-server.rs similarity index 74% rename from juniper/examples/rocket-server.rs rename to juniper_rocket/examples/rocket-server.rs index ab6acf7a..b6db016e 100644 --- a/juniper/examples/rocket-server.rs +++ b/juniper_rocket/examples/rocket-server.rs @@ -3,6 +3,7 @@ extern crate rocket; extern crate juniper; +extern crate juniper_rocket; use rocket::response::content; use rocket::State; @@ -10,30 +11,28 @@ use rocket::State; use juniper::tests::model::Database; use juniper::{EmptyMutation, RootNode}; -use juniper::rocket_handlers; - type Schema = RootNode<'static, Database, EmptyMutation>; #[get("/")] -fn graphiql() -> content::HTML { - rocket_handlers::graphiql_source("/graphql") +fn graphiql() -> content::Html { + juniper_rocket::graphiql_source("/graphql") } #[get("/graphql?")] fn get_graphql_handler( context: State, - request: rocket_handlers::GraphQLRequest, + request: juniper_rocket::GraphQLRequest, schema: State, -) -> rocket_handlers::GraphQLResponse { +) -> juniper_rocket::GraphQLResponse { request.execute(&schema, &context) } #[post("/graphql", data="")] fn post_graphql_handler( context: State, - request: rocket_handlers::GraphQLRequest, + request: juniper_rocket::GraphQLRequest, schema: State, -) -> rocket_handlers::GraphQLResponse { +) -> juniper_rocket::GraphQLResponse { request.execute(&schema, &context) } @@ -43,4 +42,4 @@ fn main() { .manage(Schema::new(Database::new(), EmptyMutation::::new())) .mount("/", routes![graphiql, get_graphql_handler, post_graphql_handler]) .launch(); -} \ No newline at end of file +} diff --git a/juniper/src/integrations/rocket_handlers.rs b/juniper_rocket/src/lib.rs similarity index 83% rename from juniper/src/integrations/rocket_handlers.rs rename to juniper_rocket/src/lib.rs index b7e97f77..681cff50 100644 --- a/juniper/src/integrations/rocket_handlers.rs +++ b/juniper_rocket/src/lib.rs @@ -1,30 +1,26 @@ -//! Optional helper functions for the [Rocket](https://rocket.rs) framework. Requires the "rocket-handlers" feature enabled. -//! -//! The two exposed types in this module are simple wrapper around the -//! types exposed by the `http` module, but they are better suited for use -//! in handler functions in the Rocket framework. -//! -//! See the [rocket-server.rs](https://github.com/mhallin/juniper/blob/master/examples/rocket-server.rs) -//! example for how to use these tools. +#![feature(plugin)] +#![plugin(rocket_codegen)] + +extern crate juniper; +extern crate serde_json; +extern crate rocket; use std::io::{Cursor, Read}; use std::error::Error; -use serde_json; - use rocket::Request; -use rocket::request::{FromForm, FormItems, FromFormValue}; +use rocket::request::{FromForm, FormItems}; use rocket::data::{FromData, Outcome as FromDataOutcome}; use rocket::response::{Responder, Response, content}; use rocket::http::{ContentType, Status}; use rocket::Data; use rocket::Outcome::{Forward, Failure, Success}; -use ::InputValue; -use ::http; +use juniper::InputValue; +use juniper::http; -use types::base::GraphQLType; -use schema::model::RootNode; +use juniper::GraphQLType; +use juniper::RootNode; /// Simple wrapper around an incoming GraphQL request /// @@ -37,8 +33,8 @@ pub struct GraphQLRequest(http::GraphQLRequest); pub struct GraphQLResponse(Status, String); /// Generate an HTML page containing GraphiQL -pub fn graphiql_source(graphql_endpoint_url: &str) -> content::HTML { - content::HTML(::graphiql::graphiql_source(graphql_endpoint_url)) +pub fn graphiql_source(graphql_endpoint_url: &str) -> content::Html { + content::Html(juniper::graphiql::graphiql_source(graphql_endpoint_url)) } impl GraphQLRequest { @@ -63,19 +59,22 @@ impl GraphQLRequest { impl<'f> FromForm<'f> for GraphQLRequest { type Error = String; - fn from_form_items(form_items: &mut FormItems<'f>) -> Result { + fn from_form( + form_items: &mut FormItems<'f>, + strict: bool + ) -> Result { let mut query = None; let mut operation_name = None; let mut variables = None; for (key, value) in form_items { - match key { + match key.as_str() { "query" => { if query.is_some() { return Err("Query parameter must not occur more than once".to_owned()); } else { - query = Some(String::from_form_value(value)?); + query = Some(value.as_str().to_string()); } } "operation_name" => { @@ -83,7 +82,7 @@ impl<'f> FromForm<'f> for GraphQLRequest { return Err("Operation name parameter must not occur more than once".to_owned()); } else { - operation_name = Some(String::from_form_value(value)?); + operation_name = Some(value.as_str().to_string()); } } "variables" => { @@ -91,11 +90,15 @@ impl<'f> FromForm<'f> for GraphQLRequest { return Err("Variables parameter must not occur more than once".to_owned()); } else { - variables = Some(serde_json::from_str::(&String::from_form_value(value)?) + variables = Some(serde_json::from_str::(value.as_str()) .map_err(|err| err.description().to_owned())?); } } - _ => {} + _ => { + if strict { + return Err(format!("Prohibited extra field '{}'", key).to_owned()); + } + } } } @@ -115,7 +118,7 @@ impl<'f> FromForm<'f> for GraphQLRequest { impl FromData for GraphQLRequest { type Error = String; - fn from_data(request: &Request, data: Data) -> FromDataOutcome { + fn from_data(request: &Request, data: Data) -> FromDataOutcome { if !request.content_type().map_or(false, |ct| ct.is_json()) { return Forward(data); } @@ -135,7 +138,7 @@ impl FromData for GraphQLRequest { } impl<'r> Responder<'r> for GraphQLResponse { - fn respond(self) -> Result, Status> { + fn respond_to(self, _: &Request) -> Result, Status> { let GraphQLResponse(status, body) = self; Ok(Response::build() @@ -148,19 +151,20 @@ impl<'r> Responder<'r> for GraphQLResponse { #[cfg(test)] mod tests { + use rocket; use rocket::Rocket; use rocket::http::{ContentType, Method}; use rocket::State; - use rocket::testing::MockRequest; - use ::RootNode; - use ::tests::model::Database; - use ::http::tests as http_tests; - use types::scalars::EmptyMutation; + use juniper::RootNode; + use juniper::tests::model::Database; + use juniper::http::tests as http_tests; + use juniper::EmptyMutation; type Schema = RootNode<'static, Database, EmptyMutation>; + #[get("/?")] fn get_graphql_handler( context: State, @@ -183,6 +187,8 @@ mod tests { rocket: Rocket, } + /* + impl http_tests::HTTPIntegration for TestRocketIntegration { fn get(&self, url: &str) -> http_tests::TestResponse { @@ -230,4 +236,6 @@ mod tests { content_type: content_type, } } -} \ No newline at end of file + + */ +}