From 82ecd920903e6d0e0150d41396f75fde0c99c9c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanko=20Krtali=C4=87?= Date: Fri, 28 Jul 2017 10:56:20 +0200 Subject: [PATCH 1/6] Fix Rocket integration Rocket's traits have changed in version 0.3.0, this commit adjusts the existing implementation to be compatible with the latest version of the traits. --- juniper/Cargo.toml | 4 +-- juniper/examples/rocket-server.rs | 4 +-- juniper/src/integrations/rocket_handlers.rs | 31 +++++++++++++-------- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/juniper/Cargo.toml b/juniper/Cargo.toml index a9565cd2..3f473010 100644 --- a/juniper/Cargo.toml +++ b/juniper/Cargo.toml @@ -45,8 +45,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 } +rocket = { version = "^0.3.0", optional = true } +rocket_codegen = { version = "^0.3.0", optional = true } [dev-dependencies] iron = "^0.5.1" diff --git a/juniper/examples/rocket-server.rs b/juniper/examples/rocket-server.rs index ab6acf7a..782f6d57 100644 --- a/juniper/examples/rocket-server.rs +++ b/juniper/examples/rocket-server.rs @@ -15,7 +15,7 @@ use juniper::rocket_handlers; type Schema = RootNode<'static, Database, EmptyMutation>; #[get("/")] -fn graphiql() -> content::HTML { +fn graphiql() -> content::Html { rocket_handlers::graphiql_source("/graphql") } @@ -43,4 +43,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/src/integrations/rocket_handlers.rs index b7e97f77..083af2b6 100644 --- a/juniper/src/integrations/rocket_handlers.rs +++ b/juniper/src/integrations/rocket_handlers.rs @@ -13,7 +13,7 @@ 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}; @@ -37,8 +37,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(::graphiql::graphiql_source(graphql_endpoint_url)) } impl GraphQLRequest { @@ -63,19 +63,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 +86,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 +94,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 +122,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 +142,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() @@ -230,4 +237,4 @@ mod tests { content_type: content_type, } } -} \ No newline at end of file +} From 2f62bc55e1e2eb30fca01670b1b975b816ad018e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanko=20Krtali=C4=87?= Date: Thu, 3 Aug 2017 10:11:56 +0200 Subject: [PATCH 2/6] Split out rocket_integration into separate crate This split still requires some work as the tests currently fail. This is caused by the fact that some previously private modules can't be accessed anymore, and that Rocket changet it's testing framework. --- Cargo.toml | 1 + juniper_rocket_integration/Cargo.toml | 21 +++ juniper_rocket_integration/src/lib.rs | 233 ++++++++++++++++++++++++++ 3 files changed, 255 insertions(+) create mode 100644 juniper_rocket_integration/Cargo.toml create mode 100644 juniper_rocket_integration/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index cc833d78..851b09f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,4 +3,5 @@ members = [ "juniper", "juniper_codegen", "juniper_tests", + "juniper_rocket_integration", ] diff --git a/juniper_rocket_integration/Cargo.toml b/juniper_rocket_integration/Cargo.toml new file mode 100644 index 00000000..f127afe0 --- /dev/null +++ b/juniper_rocket_integration/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "juniper_rocket_integration" +version = "0.0.1" +authors = ["Magnus Hallin "] +description = "Juniper GraphQL integration with Rocket" +license = "BSD-2-Clause" +documentation = "https://docs.rs/juniper" +repository = "https://github.com/mhallin/juniper" + +[dependencies] +juniper = { path = "../juniper" } +juniper_codegen = { path = "../juniper_codegen" } +rocket = { version = "^0.3.0" } +rocket_codegen = { version = "^0.3.0" } +serde = { version = "^1.0.8" } +serde_derive = {version="^1.0.8" } +serde_json = { version = "^1.0.2" } + +[badges] +travis-ci = { repository = "mhallin/juniper" } +appveyor = { repository = "mhallin/juniper" } diff --git a/juniper_rocket_integration/src/lib.rs b/juniper_rocket_integration/src/lib.rs new file mode 100644 index 00000000..a0b6dff1 --- /dev/null +++ b/juniper_rocket_integration/src/lib.rs @@ -0,0 +1,233 @@ +extern crate juniper; +extern crate serde_json; +extern crate rocket; + +use std::io::{Cursor, Read}; +use std::error::Error; + +use rocket::Request; +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 juniper::InputValue; +use juniper::http; + +use juniper::GraphQLType; +use juniper::RootNode; + +/// Simple wrapper around an incoming GraphQL request +/// +/// See the `http` module for more information. This type can be constructed +/// automatically from both GET and POST routes by implementing the `FromForm` +/// and `FromData` traits. +pub struct GraphQLRequest(http::GraphQLRequest); + +/// Simple wrapper around the result of executing a GraphQL query +pub struct GraphQLResponse(Status, String); + +/// Generate an HTML page containing GraphiQL +pub fn graphiql_source(graphql_endpoint_url: &str) -> content::Html { + content::Html(juniper::graphiql::graphiql_source(graphql_endpoint_url)) +} + +impl GraphQLRequest { + /// Execute an incoming GraphQL query + pub fn execute( + &self, + root_node: &RootNode, + context: &CtxT, + ) + -> GraphQLResponse + where QueryT: GraphQLType, + MutationT: GraphQLType, + { + let response = self.0.execute(root_node, context); + let status = if response.is_ok() { Status::Ok } else { Status::BadRequest }; + let json = serde_json::to_string_pretty(&response).unwrap(); + + GraphQLResponse(status, json) + } +} + +impl<'f> FromForm<'f> for GraphQLRequest { + type Error = String; + + 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.as_str() { + "query" => { + if query.is_some() { + return Err("Query parameter must not occur more than once".to_owned()); + } + else { + query = Some(value.as_str().to_string()); + } + } + "operation_name" => { + if operation_name.is_some() { + return Err("Operation name parameter must not occur more than once".to_owned()); + } + else { + operation_name = Some(value.as_str().to_string()); + } + } + "variables" => { + if variables.is_some() { + return Err("Variables parameter must not occur more than once".to_owned()); + } + else { + 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()); + } + } + } + } + + if let Some(query) = query { + Ok(GraphQLRequest(http::GraphQLRequest::new( + query, + operation_name, + variables + ))) + } + else { + Err("Query parameter missing".to_owned()) + } + } +} + +impl FromData for GraphQLRequest { + type Error = String; + + fn from_data(request: &Request, data: Data) -> FromDataOutcome { + if !request.content_type().map_or(false, |ct| ct.is_json()) { + return Forward(data); + } + + let mut body = String::new(); + if let Err(e) = data.open().read_to_string(&mut body) { + return Failure((Status::InternalServerError, format!("{:?}", e))); + } + + match serde_json::from_str(&body) { + Ok(value) => Success(GraphQLRequest(value)), + Err(failure) => return Failure( + (Status::BadRequest, format!("{}", failure)), + ), + } + } +} + +impl<'r> Responder<'r> for GraphQLResponse { + fn respond_to(self, _: &Request) -> Result, Status> { + let GraphQLResponse(status, body) = self; + + Ok(Response::build() + .header(ContentType::new("application", "json")) + .status(status) + .sized_body(Cursor::new(body)) + .finalize()) + } +} + +#[cfg(test)] +mod tests { + use rocket; + use rocket::Rocket; + use rocket::http::{ContentType, Method}; + use rocket::State; + use rocket::testing::MockRequest; + + use juniper::RootNode; + use juniper::tests::model::Database; + use juniper::http::tests as http_tests; + use juniper::types::scalars::EmptyMutation; + + type Schema = RootNode<'static, Database, EmptyMutation>; + + #[get("/?")] + fn get_graphql_handler( + context: State, + request: super::GraphQLRequest, + schema: State, + ) -> super::GraphQLResponse { + request.execute(&schema, &context) + } + + #[post("/", data="")] + fn post_graphql_handler( + context: State, + request: super::GraphQLRequest, + schema: State, + ) -> super::GraphQLResponse { + request.execute(&schema, &context) + } + + struct TestRocketIntegration { + rocket: Rocket, + } + + impl http_tests::HTTPIntegration for TestRocketIntegration + { + fn get(&self, url: &str) -> http_tests::TestResponse { + make_test_response(&self.rocket, MockRequest::new( + Method::Get, + url)) + } + + fn post(&self, url: &str, body: &str) -> http_tests::TestResponse { + make_test_response( + &self.rocket, + MockRequest::new( + Method::Post, + url, + ).header(ContentType::JSON).body(body)) + } + } + + #[test] + fn test_rocket_integration() { + let integration = TestRocketIntegration { + rocket: make_rocket(), + }; + + http_tests::run_http_test_suite(&integration); + } + + fn make_rocket() -> Rocket { + rocket::ignite() + .manage(Database::new()) + .manage(Schema::new(Database::new(), EmptyMutation::::new())) + .mount("/", routes![post_graphql_handler, get_graphql_handler]) + } + + fn make_test_response<'r>(rocket: &'r Rocket, mut request: MockRequest<'r>) -> http_tests::TestResponse { + let mut response = request.dispatch_with(&rocket); + let status_code = response.status().code as i32; + let content_type = response.header_values("content-type").collect::>().into_iter().next() + .expect("No content type header from handler").to_owned(); + let body = response.body().expect("No body returned from GraphQL handler").into_string(); + + http_tests::TestResponse { + status_code: status_code, + body: body, + content_type: content_type, + } + } +} From 619a2e57f984e5feea237a62043157308a6d8bb7 Mon Sep 17 00:00:00 2001 From: theduke Date: Sun, 6 Aug 2017 16:53:31 +0200 Subject: [PATCH 3/6] Extraction of iron and rocket features into separate crates. * Added juniper_iron crate * Fixed up juniper_rocket crate * Updated juniper/Cargo.toml * Updated docs (readme, module docs) * Export http integrator tests with export-test-schema feature * Update CI tests (Use cargo-make ) * Format parts of the code base --- .travis.yml | 40 +- CHANGELOG.md | 2 +- Cargo.toml | 3 +- README.md | 14 +- appveyor.yml | 29 +- juniper/Cargo.toml | 30 +- juniper/benches/bench.rs | 3 +- juniper/src/ast.rs | 125 +- juniper/src/executor.rs | 146 +-- juniper/src/executor_tests/directives.rs | 209 ++-- juniper/src/executor_tests/enums.rs | 62 +- juniper/src/executor_tests/executor.rs | 62 +- .../src/executor_tests/interfaces_unions.rs | 70 +- juniper/src/executor_tests/introspection.rs | 57 +- juniper/src/executor_tests/variables.rs | 493 ++++---- juniper/src/graphiql.rs | 2 +- juniper/src/http.rs | 71 +- juniper/src/integrations/mod.rs | 2 - juniper/src/integrations/rocket_handlers.rs | 240 ---- juniper/src/integrations/serde.rs | 57 +- juniper/src/lib.rs | 165 +-- juniper/src/macros/mod.rs | 27 +- juniper/src/macros/tests/args.rs | 41 +- juniper/src/macros/tests/enums.rs | 49 +- juniper/src/macros/tests/field.rs | 42 +- juniper/src/macros/tests/input_object.rs | 23 +- juniper/src/macros/tests/interface.rs | 30 +- juniper/src/macros/tests/mod.rs | 3 +- juniper/src/macros/tests/object.rs | 30 +- juniper/src/macros/tests/scalar.rs | 13 +- juniper/src/macros/tests/union.rs | 50 +- juniper/src/parser/document.rs | 322 ++--- juniper/src/parser/lexer.rs | 278 ++--- juniper/src/parser/parser.rs | 99 +- juniper/src/parser/tests/document.rs | 3 +- juniper/src/parser/tests/lexer.rs | 128 +- juniper/src/parser/tests/value.rs | 6 +- juniper/src/parser/utils.rs | 28 +- juniper/src/parser/value.rs | 83 +- juniper/src/schema/meta.rs | 75 +- juniper/src/schema/model.rs | 164 +-- juniper/src/schema/schema.rs | 24 +- juniper/src/tests/introspection_tests.rs | 28 +- juniper/src/tests/mod.rs | 6 +- juniper/src/tests/model.rs | 212 ++-- juniper/src/tests/query_tests.rs | 8 +- juniper/src/types/base.rs | 177 +-- juniper/src/types/containers.rs | 66 +- juniper/src/types/pointers.rs | 46 +- juniper/src/types/scalars.rs | 4 +- juniper/src/types/utilities.rs | 59 +- juniper/src/validation/context.rs | 37 +- juniper/src/validation/input_value.rs | 251 ++-- juniper/src/validation/mod.rs | 5 +- juniper/src/validation/multi_visitor.rs | 84 +- .../rules/arguments_of_correct_type.rs | 452 ++++--- .../rules/default_values_of_correct_type.rs | 96 +- .../rules/fields_on_correct_type.rs | 134 +-- .../rules/fragments_on_composite_types.rs | 81 +- .../validation/rules/known_argument_names.rs | 128 +- .../src/validation/rules/known_directives.rs | 110 +- .../validation/rules/known_fragment_names.rs | 32 +- .../src/validation/rules/known_type_names.rs | 39 +- .../rules/lone_anonymous_operation.rs | 55 +- .../validation/rules/no_fragment_cycles.rs | 175 ++- .../rules/no_undefined_variables.rs | 283 +++-- .../validation/rules/no_unused_fragments.rs | 76 +- .../validation/rules/no_unused_variables.rs | 147 +-- .../rules/overlapping_fields_can_be_merged.rs | 1047 ++++++++--------- .../rules/possible_fragment_spreads.rs | 206 ++-- .../rules/provided_non_null_arguments.rs | 138 ++- juniper/src/validation/rules/scalar_leafs.rs | 85 +- .../validation/rules/unique_argument_names.rs | 102 +- .../validation/rules/unique_fragment_names.rs | 52 +- .../rules/unique_input_field_names.rs | 64 +- .../rules/unique_operation_names.rs | 55 +- .../validation/rules/unique_variable_names.rs | 53 +- .../rules/variables_are_input_types.rs | 37 +- .../rules/variables_in_allowed_position.rs | 180 +-- juniper/src/validation/test_harness.rs | 365 +++--- juniper/src/validation/traits.rs | 94 +- juniper/src/validation/visitor.rs | 124 +- juniper/src/value.rs | 43 +- juniper_iron/Cargo.toml | 26 + .../examples/iron_server.rs | 3 +- .../src/lib.rs | 154 ++- .../Cargo.toml | 15 +- juniper_rocket/Makefile.toml | 41 + .../examples/rocket-server.rs | 13 +- .../src/lib.rs | 12 +- 90 files changed, 4592 insertions(+), 4508 deletions(-) delete mode 100644 juniper/src/integrations/rocket_handlers.rs create mode 100644 juniper_iron/Cargo.toml rename juniper/examples/server.rs => juniper_iron/examples/iron_server.rs (92%) rename juniper/src/integrations/iron_handlers.rs => juniper_iron/src/lib.rs (69%) rename {juniper_rocket_integration => juniper_rocket}/Cargo.toml (61%) create mode 100644 juniper_rocket/Makefile.toml rename {juniper => juniper_rocket}/examples/rocket-server.rs (78%) rename {juniper_rocket_integration => juniper_rocket}/src/lib.rs (98%) diff --git a/.travis.yml b/.travis.yml index d1ae2804..07b1dba4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,44 +19,8 @@ env: - 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 851b09f5..d6e64937 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,5 +3,6 @@ members = [ "juniper", "juniper_codegen", "juniper_tests", - "juniper_rocket_integration", + "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..7be26e64 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,6 @@ 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) + - cargo make ci-flow - # 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 diff --git a/juniper/Cargo.toml b/juniper/Cargo.toml index 3f473010..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.3.0", optional = true } -rocket_codegen = { version = "^0.3.0", 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/rocket_handlers.rs b/juniper/src/integrations/rocket_handlers.rs deleted file mode 100644 index 083af2b6..00000000 --- a/juniper/src/integrations/rocket_handlers.rs +++ /dev/null @@ -1,240 +0,0 @@ -//! 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. - -use std::io::{Cursor, Read}; -use std::error::Error; - -use serde_json; - -use rocket::Request; -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 types::base::GraphQLType; -use schema::model::RootNode; - -/// Simple wrapper around an incoming GraphQL request -/// -/// See the `http` module for more information. This type can be constructed -/// automatically from both GET and POST routes by implementing the `FromForm` -/// and `FromData` traits. -pub struct GraphQLRequest(http::GraphQLRequest); - -/// Simple wrapper around the result of executing a GraphQL query -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)) -} - -impl GraphQLRequest { - /// Execute an incoming GraphQL query - pub fn execute( - &self, - root_node: &RootNode, - context: &CtxT, - ) - -> GraphQLResponse - where QueryT: GraphQLType, - MutationT: GraphQLType, - { - let response = self.0.execute(root_node, context); - let status = if response.is_ok() { Status::Ok } else { Status::BadRequest }; - let json = serde_json::to_string_pretty(&response).unwrap(); - - GraphQLResponse(status, json) - } -} - -impl<'f> FromForm<'f> for GraphQLRequest { - type Error = String; - - 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.as_str() { - "query" => { - if query.is_some() { - return Err("Query parameter must not occur more than once".to_owned()); - } - else { - query = Some(value.as_str().to_string()); - } - } - "operation_name" => { - if operation_name.is_some() { - return Err("Operation name parameter must not occur more than once".to_owned()); - } - else { - operation_name = Some(value.as_str().to_string()); - } - } - "variables" => { - if variables.is_some() { - return Err("Variables parameter must not occur more than once".to_owned()); - } - else { - 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()); - } - } - } - } - - if let Some(query) = query { - Ok(GraphQLRequest(http::GraphQLRequest::new( - query, - operation_name, - variables - ))) - } - else { - Err("Query parameter missing".to_owned()) - } - } -} - -impl FromData for GraphQLRequest { - type Error = String; - - fn from_data(request: &Request, data: Data) -> FromDataOutcome { - if !request.content_type().map_or(false, |ct| ct.is_json()) { - return Forward(data); - } - - let mut body = String::new(); - if let Err(e) = data.open().read_to_string(&mut body) { - return Failure((Status::InternalServerError, format!("{:?}", e))); - } - - match serde_json::from_str(&body) { - Ok(value) => Success(GraphQLRequest(value)), - Err(failure) => return Failure( - (Status::BadRequest, format!("{}", failure)), - ), - } - } -} - -impl<'r> Responder<'r> for GraphQLResponse { - fn respond_to(self, _: &Request) -> Result, Status> { - let GraphQLResponse(status, body) = self; - - Ok(Response::build() - .header(ContentType::new("application", "json")) - .status(status) - .sized_body(Cursor::new(body)) - .finalize()) - } -} - -#[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; - - type Schema = RootNode<'static, Database, EmptyMutation>; - - #[get("/?")] - fn get_graphql_handler( - context: State, - request: super::GraphQLRequest, - schema: State, - ) -> super::GraphQLResponse { - request.execute(&schema, &context) - } - - #[post("/", data="")] - fn post_graphql_handler( - context: State, - request: super::GraphQLRequest, - schema: State, - ) -> super::GraphQLResponse { - request.execute(&schema, &context) - } - - struct TestRocketIntegration { - rocket: Rocket, - } - - impl http_tests::HTTPIntegration for TestRocketIntegration - { - fn get(&self, url: &str) -> http_tests::TestResponse { - make_test_response(&self.rocket, MockRequest::new( - Method::Get, - url)) - } - - fn post(&self, url: &str, body: &str) -> http_tests::TestResponse { - make_test_response( - &self.rocket, - MockRequest::new( - Method::Post, - url, - ).header(ContentType::JSON).body(body)) - } - } - - #[test] - fn test_rocket_integration() { - let integration = TestRocketIntegration { - rocket: make_rocket(), - }; - - http_tests::run_http_test_suite(&integration); - } - - fn make_rocket() -> Rocket { - rocket::ignite() - .manage(Database::new()) - .manage(Schema::new(Database::new(), EmptyMutation::::new())) - .mount("/", routes![post_graphql_handler, get_graphql_handler]) - } - - fn make_test_response<'r>(rocket: &'r Rocket, mut request: MockRequest<'r>) -> http_tests::TestResponse { - let mut response = request.dispatch_with(&rocket); - let status_code = response.status().code as i32; - let content_type = response.header_values("content-type").collect::>().into_iter().next() - .expect("No content type header from handler").to_owned(); - let body = response.body().expect("No body returned from GraphQL handler").into_string(); - - http_tests::TestResponse { - status_code: status_code, - body: body, - content_type: content_type, - } - } -} 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_integration/Cargo.toml b/juniper_rocket/Cargo.toml similarity index 61% rename from juniper_rocket_integration/Cargo.toml rename to juniper_rocket/Cargo.toml index f127afe0..67b73e43 100644 --- a/juniper_rocket_integration/Cargo.toml +++ b/juniper_rocket/Cargo.toml @@ -1,21 +1,24 @@ [package] -name = "juniper_rocket_integration" +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" +documentation = "https://docs.rs/juniper_rocket" repository = "https://github.com/mhallin/juniper" [dependencies] -juniper = { path = "../juniper" } -juniper_codegen = { path = "../juniper_codegen" } -rocket = { version = "^0.3.0" } -rocket_codegen = { version = "^0.3.0" } 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 78% rename from juniper/examples/rocket-server.rs rename to juniper_rocket/examples/rocket-server.rs index 782f6d57..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") + 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) } diff --git a/juniper_rocket_integration/src/lib.rs b/juniper_rocket/src/lib.rs similarity index 98% rename from juniper_rocket_integration/src/lib.rs rename to juniper_rocket/src/lib.rs index a0b6dff1..681cff50 100644 --- a/juniper_rocket_integration/src/lib.rs +++ b/juniper_rocket/src/lib.rs @@ -1,3 +1,6 @@ +#![feature(plugin)] +#![plugin(rocket_codegen)] + extern crate juniper; extern crate serde_json; extern crate rocket; @@ -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 juniper::RootNode; use juniper::tests::model::Database; use juniper::http::tests as http_tests; - use juniper::types::scalars::EmptyMutation; + 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, } } + + */ } From deacbd247e62f8477496d39294e80af5965769a9 Mon Sep 17 00:00:00 2001 From: theduke Date: Sun, 6 Aug 2017 17:29:12 +0200 Subject: [PATCH 4/6] Appveyor: temporarily disable cargo-make Due to cargo-make bug... --- appveyor.yml | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 7be26e64..bd2762a5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,23 +5,23 @@ environment: matrix: # Stable channel - - TARGET: i686-pc-windows-gnu - CHANNEL: stable - - TARGET: i686-pc-windows-msvc - CHANNEL: stable - - TARGET: x86_64-pc-windows-gnu - CHANNEL: stable - - TARGET: x86_64-pc-windows-msvc - CHANNEL: stable + # - TARGET: i686-pc-windows-gnu + # CHANNEL: stable + # - TARGET: i686-pc-windows-msvc + # CHANNEL: stable + # - TARGET: x86_64-pc-windows-gnu + # CHANNEL: stable + # - TARGET: x86_64-pc-windows-msvc + # CHANNEL: stable # Beta channel - - TARGET: i686-pc-windows-gnu - CHANNEL: beta - - TARGET: i686-pc-windows-msvc - CHANNEL: beta - - TARGET: x86_64-pc-windows-gnu - CHANNEL: beta - - TARGET: x86_64-pc-windows-msvc - CHANNEL: beta + # - TARGET: i686-pc-windows-gnu + # CHANNEL: beta + # - TARGET: i686-pc-windows-msvc + # CHANNEL: beta + # - TARGET: x86_64-pc-windows-gnu + # CHANNEL: beta + # - TARGET: x86_64-pc-windows-msvc + # CHANNEL: beta # Nightly channel - TARGET: i686-pc-windows-gnu CHANNEL: nightly @@ -49,6 +49,10 @@ install: build: false test_script: - - cargo make ci-flow + - ECHO.%TARGET% | FIND "msvc">Nul && ( IF "%CHANNEL%"=="nightly" (cd juniper_rocket && cargo build --verbose && cargo test --verbose) ) + - 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 .. From b22f7ff09a42b207704b8d6e827cc0b7c63e8356 Mon Sep 17 00:00:00 2001 From: theduke Date: Sun, 6 Aug 2017 17:30:26 +0200 Subject: [PATCH 5/6] Travis: stop allowing failures on nightly Rocket only works on nightly + Not done on appveyor anyway --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 07b1dba4..ccf04956 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,10 +10,6 @@ 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=" From b5d10f77220ed9d0fc77e8393771617b957051d2 Mon Sep 17 00:00:00 2001 From: theduke Date: Sun, 6 Aug 2017 19:06:00 +0200 Subject: [PATCH 6/6] Appveyor: only run rocket tests on nightly + msvc Rocket is only supported on nightly, and rocket depends on Ring, which does not support the gcc toolchain on Windows. --- appveyor.yml | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index bd2762a5..0fc876d2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,23 +5,23 @@ environment: matrix: # Stable channel - # - TARGET: i686-pc-windows-gnu - # CHANNEL: stable - # - TARGET: i686-pc-windows-msvc - # CHANNEL: stable - # - TARGET: x86_64-pc-windows-gnu - # CHANNEL: stable - # - TARGET: x86_64-pc-windows-msvc - # CHANNEL: stable + - TARGET: i686-pc-windows-gnu + CHANNEL: stable + - TARGET: i686-pc-windows-msvc + CHANNEL: stable + - TARGET: x86_64-pc-windows-gnu + CHANNEL: stable + - TARGET: x86_64-pc-windows-msvc + CHANNEL: stable # Beta channel - # - TARGET: i686-pc-windows-gnu - # CHANNEL: beta - # - TARGET: i686-pc-windows-msvc - # CHANNEL: beta - # - TARGET: x86_64-pc-windows-gnu - # CHANNEL: beta - # - TARGET: x86_64-pc-windows-msvc - # CHANNEL: beta + - TARGET: i686-pc-windows-gnu + CHANNEL: beta + - TARGET: i686-pc-windows-msvc + CHANNEL: beta + - TARGET: x86_64-pc-windows-gnu + CHANNEL: beta + - TARGET: x86_64-pc-windows-msvc + CHANNEL: beta # Nightly channel - TARGET: i686-pc-windows-gnu CHANNEL: nightly @@ -49,10 +49,9 @@ install: build: false test_script: - - ECHO.%TARGET% | FIND "msvc">Nul && ( IF "%CHANNEL%"=="nightly" (cd juniper_rocket && cargo build --verbose && cargo test --verbose) ) - 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 .. ) )