From 09d9513da99ba1211699de3060980906686c0215 Mon Sep 17 00:00:00 2001 From: nWacky Date: Wed, 6 Nov 2019 11:37:35 +0300 Subject: [PATCH] Rebase onto `master` --- benches/bench.rs | 127 +++++++++++++++++++++++++++ juniper/CHANGELOG.md | 5 ++ juniper/Cargo.toml | 4 +- juniper/src/executor/mod.rs | 14 --- juniper/src/lib.rs | 7 +- juniper/src/parser/parser.rs | 4 + juniper/src/parser/tests/document.rs | 21 +++++ juniper/src/parser/value.rs | 31 ++++--- juniper/src/types/base.rs | 2 +- juniper/src/types/scalars.rs | 11 ++- juniper/src/value/scalar.rs | 2 - juniper_codegen/Cargo.toml | 4 +- juniper_hyper/CHANGELOG.md | 4 + juniper_hyper/Cargo.toml | 6 +- juniper_iron/CHANGELOG.md | 4 + juniper_iron/Cargo.toml | 6 +- juniper_rocket/CHANGELOG.md | 4 + juniper_rocket/Cargo.toml | 2 +- juniper_warp/CHANGELOG.md | 4 + juniper_warp/Cargo.toml | 4 +- juniper_warp/src/lib.rs | 3 +- 21 files changed, 219 insertions(+), 50 deletions(-) create mode 100644 benches/bench.rs diff --git a/benches/bench.rs b/benches/bench.rs new file mode 100644 index 00000000..5d707527 --- /dev/null +++ b/benches/bench.rs @@ -0,0 +1,127 @@ +#[macro_use] extern crate bencher; +extern crate juniper; + +use bencher::Bencher; + +use juniper::{execute, RootNode, EmptyMutation, Variables}; +use juniper::tests::model::Database; + +fn query_type_name(b: &mut Bencher) { + let database = Database::new(); + let schema = RootNode::new(&database, EmptyMutation::::new()); + + let doc = r#" + query IntrospectionQueryTypeQuery { + __schema { + queryType { + name + } + } + }"#; + + b.iter(|| execute(doc, None, &schema, &Variables::new(), &database)); +} + +fn introspection_query(b: &mut Bencher) { + let database = Database::new(); + let schema = RootNode::new(&database, EmptyMutation::::new()); + + let doc = r#" + query IntrospectionQuery { + __schema { + queryType { name } + mutationType { name } + subscriptionType { name } + types { + ...FullType + } + directives { + name + description + locations + args { + ...InputValue + } + } + } + } + + fragment FullType on __Type { + kind + name + description + fields(includeDeprecated: true) { + name + description + args { + ...InputValue + } + type { + ...TypeRef + } + isDeprecated + deprecationReason + } + inputFields { + ...InputValue + } + interfaces { + ...TypeRef + } + enumValues(includeDeprecated: true) { + name + description + isDeprecated + deprecationReason + } + possibleTypes { + ...TypeRef + } + } + + fragment InputValue on __InputValue { + name + description + type { ...TypeRef } + defaultValue + } + + fragment TypeRef on __Type { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + } + } + } + } + } + } + } + } +"#; + + b.iter(|| execute(doc, None, &schema, &Variables::new(), &database)); +} + +benchmark_group!(queries, query_type_name, introspection_query); +benchmark_main!(queries); diff --git a/juniper/CHANGELOG.md b/juniper/CHANGELOG.md index 3af51898..dc6ad7ed 100644 --- a/juniper/CHANGELOG.md +++ b/juniper/CHANGELOG.md @@ -2,6 +2,11 @@ - No changes yet +# [[0.14.1] 2019-10-24](https://github.com/graphql-rust/juniper/releases/tag/juniper-0.14.1) + +- Fix panic when an invalid scalar is used by a client [#434](https://github.com/graphql-rust/juniper/pull/434) +- `EmptyMutation` now implements `Send` [#443](https://github.com/graphql-rust/juniper/pull/443) + # [[0.14.0] 2019-09-29](https://github.com/graphql-rust/juniper/releases/tag/juniper-0.14.0) - Require `url` 2.x if `url` feature is enabled. diff --git a/juniper/Cargo.toml b/juniper/Cargo.toml index 1fdee863..a0eb926a 100644 --- a/juniper/Cargo.toml +++ b/juniper/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "juniper" -version = "0.14.0" +version = "0.14.1" authors = [ "Magnus Hallin ", "Christoph Herzog ", @@ -33,7 +33,7 @@ default = [ ] [dependencies] -juniper_codegen = { version = "0.14.0", path = "../juniper_codegen" } +juniper_codegen = { version = "0.14.1", path = "../juniper_codegen" } async-trait = "0.1.16" chrono = { version = "0.4.0", optional = true } diff --git a/juniper/src/executor/mod.rs b/juniper/src/executor/mod.rs index 2fdcd4fd..c080f9d4 100644 --- a/juniper/src/executor/mod.rs +++ b/juniper/src/executor/mod.rs @@ -210,20 +210,6 @@ impl FieldError { /// The result of resolving the value of a field of type `T` pub type FieldResult = Result>; -/* -pub enum ResolvedValue<'a, S = DefaultScalarValue> { - Value(Value), - Future(crate::BoxFuture<'a, Value>), -} - -impl<'a, S> From> for ResolvedValue<'a, S> { - #[inline] - fn from(value: Value) -> Self { - ResolvedValue::Value(value) - } -} -*/ - /// The result of resolving an unspecified field pub type ExecutionResult = Result, FieldError>; diff --git a/juniper/src/lib.rs b/juniper/src/lib.rs index 18bba937..5e1f4f92 100644 --- a/juniper/src/lib.rs +++ b/juniper/src/lib.rs @@ -88,7 +88,7 @@ Juniper has not reached 1.0 yet, thus some API instability should be expected. [chrono]: https://crates.io/crates/chrono */ -#![doc(html_root_url = "https://docs.rs/juniper/0.14.0")] +#![doc(html_root_url = "https://docs.rs/juniper/0.14.1")] #![warn(missing_docs)] #[doc(hidden)] @@ -151,6 +151,7 @@ mod executor_tests; pub use crate::util::to_camel_case; use crate::{ + executor::{execute_validated_query, execute_validated_query_async}, introspection::{INTROSPECTION_QUERY, INTROSPECTION_QUERY_WITHOUT_DESCRIPTIONS}, parser::{parse_document_source, ParseError, Spanning}, validation::{validate_input_values, visit_all_rules, ValidatorContext}, @@ -227,7 +228,7 @@ where } } - executor::execute_validated_query(document, operation_name, root_node, variables, context) + execute_validated_query(document, operation_name, root_node, variables, context) } /// Execute a query in a provided schema @@ -267,7 +268,7 @@ where } } - executor::execute_validated_query_async(document, operation_name, root_node, variables, context) + execute_validated_query_async(document, operation_name, root_node, variables, context) .await } diff --git a/juniper/src/parser/parser.rs b/juniper/src/parser/parser.rs index e010180d..095fc1e7 100644 --- a/juniper/src/parser/parser.rs +++ b/juniper/src/parser/parser.rs @@ -13,6 +13,9 @@ pub enum ParseError<'a> { /// An error during tokenization occurred LexerError(LexerError), + + /// A scalar of unexpected type occurred in the source + ExpectedScalarError(&'static str), } #[doc(hidden)] @@ -196,6 +199,7 @@ impl<'a> fmt::Display for ParseError<'a> { ParseError::UnexpectedToken(ref token) => write!(f, "Unexpected \"{}\"", token), ParseError::UnexpectedEndOfFile => write!(f, "Unexpected end of input"), ParseError::LexerError(ref err) => err.fmt(f), + ParseError::ExpectedScalarError(err) => err.fmt(f), } } } diff --git a/juniper/src/parser/tests/document.rs b/juniper/src/parser/tests/document.rs index 97b6c31d..cfe18d64 100644 --- a/juniper/src/parser/tests/document.rs +++ b/juniper/src/parser/tests/document.rs @@ -4,6 +4,7 @@ use crate::{ }, parser::{document::parse_document_source, ParseError, SourcePosition, Spanning, Token}, schema::model::SchemaType, + types::scalars::EmptyMutation, validation::test_harness::{MutationRoot, QueryRoot}, value::{DefaultScalarValue, ScalarRefValue, ScalarValue}, }; @@ -145,3 +146,23 @@ fn errors() { ) ); } + +#[test] +fn issue_427_panic_is_not_expected() { + struct QueryWithoutFloat; + + #[crate::object_internal] + impl QueryWithoutFloat { + fn echo(value: String) -> String { + value + } + } + + let schema = SchemaType::new::>(&(), &()); + let parse_result = parse_document_source(r##"{ echo(value: 123.0) }"##, &schema); + + assert_eq!( + parse_result.unwrap_err().item, + ParseError::ExpectedScalarError("There needs to be a Float type") + ); +} diff --git a/juniper/src/parser/value.rs b/juniper/src/parser/value.rs index 74dde9f9..260f9ec0 100644 --- a/juniper/src/parser/value.rs +++ b/juniper/src/parser/value.rs @@ -210,33 +210,36 @@ fn parse_scalar_literal_by_infered_type<'a, 'b, S>( where S: ScalarValue, { - match token { + let result = match token { ScalarToken::String(_) => { if let Some(&MetaType::Scalar(ref s)) = schema.concrete_type_by_name("String") { - (s.parse_fn)(token) - .map(|s| Spanning::start_end(start, end, InputValue::Scalar(s))) - .map_err(|e| Spanning::start_end(start, end, e)) + (s.parse_fn)(token).map(InputValue::Scalar) } else { - panic!("There needs to be a String type") + Err(ParseError::ExpectedScalarError( + "There needs to be a String type", + )) } } ScalarToken::Int(_) => { if let Some(&MetaType::Scalar(ref s)) = schema.concrete_type_by_name("Int") { - (s.parse_fn)(token) - .map(|s| Spanning::start_end(start, end, InputValue::Scalar(s))) - .map_err(|e| Spanning::start_end(start, end, e)) + (s.parse_fn)(token).map(InputValue::Scalar) } else { - panic!("There needs to be a Int type") + Err(ParseError::ExpectedScalarError( + "There needs to be an Int type", + )) } } ScalarToken::Float(_) => { if let Some(&MetaType::Scalar(ref s)) = schema.concrete_type_by_name("Float") { - (s.parse_fn)(token) - .map(|s| Spanning::start_end(start, end, InputValue::Scalar(s))) - .map_err(|e| Spanning::start_end(start, end, e)) + (s.parse_fn)(token).map(InputValue::Scalar) } else { - panic!("There needs to be a Float type") + Err(ParseError::ExpectedScalarError( + "There needs to be a Float type", + )) } } - } + }; + result + .map(|s| Spanning::start_end(start, end, s)) + .map_err(|e| Spanning::start_end(start, end, e)) } diff --git a/juniper/src/types/base.rs b/juniper/src/types/base.rs index 4a2e2315..b3705630 100644 --- a/juniper/src/types/base.rs +++ b/juniper/src/types/base.rs @@ -343,7 +343,7 @@ where } } -pub fn resolve_selection_set_into( +pub(crate) fn resolve_selection_set_into( instance: &T, info: &T::TypeInfo, selection_set: &[Selection], diff --git a/juniper/src/types/scalars.rs b/juniper/src/types/scalars.rs index 81d1c965..53876003 100644 --- a/juniper/src/types/scalars.rs +++ b/juniper/src/types/scalars.rs @@ -308,6 +308,9 @@ impl EmptyMutation { } } +// This is safe due to never using `T`. +unsafe impl Send for EmptyMutation {} + impl GraphQLType for EmptyMutation where S: ScalarValue, @@ -343,7 +346,7 @@ where #[cfg(test)] mod tests { - use super::ID; + use super::{EmptyMutation, ID}; use crate::{ parser::ScalarToken, value::{DefaultScalarValue, ParseScalarValue}, @@ -390,4 +393,10 @@ mod tests { "unicode \u{1234}\u{5678}\u{90ab}\u{cdef}", ); } + + #[test] + fn empty_mutation_is_send() { + fn check_if_send() {} + check_if_send::>(); + } } diff --git a/juniper/src/value/scalar.rs b/juniper/src/value/scalar.rs index d6a384ce..78042591 100644 --- a/juniper/src/value/scalar.rs +++ b/juniper/src/value/scalar.rs @@ -260,8 +260,6 @@ pub enum DefaultScalarValue { Boolean(bool), } -trait S: Send + Sync {} - impl ScalarValue for DefaultScalarValue { type Visitor = DefaultScalarValueVisitor; diff --git a/juniper_codegen/Cargo.toml b/juniper_codegen/Cargo.toml index f8ea341c..e22c7600 100644 --- a/juniper_codegen/Cargo.toml +++ b/juniper_codegen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "juniper_codegen" -version = "0.14.0" +version = "0.14.1" authors = [ "Magnus Hallin ", "Christoph Herzog ", @@ -24,7 +24,7 @@ quote = "1.0.2" proc-macro-error = "0.3.4" [dev-dependencies] -juniper = { version = "0.14.0", path = "../juniper" } +juniper = { version = "0.14.1", path = "../juniper" } [badges] travis-ci = { repository = "graphql-rust/juniper" } diff --git a/juniper_hyper/CHANGELOG.md b/juniper_hyper/CHANGELOG.md index d51be2c4..3735fcd6 100644 --- a/juniper_hyper/CHANGELOG.md +++ b/juniper_hyper/CHANGELOG.md @@ -2,6 +2,10 @@ - Compatibility with the latest `juniper`. +# [[0.5.1] 2019-10-24](https://github.com/graphql-rust/juniper/releases/tag/juniper_hyper-0.5.1) + +- Compatibility with the latest `juniper`. + # [[0.5.0] 2019-09-29](https://github.com/graphql-rust/juniper/releases/tag/juniper_hyper-0.5.0) - Compatibility with the latest `juniper`. diff --git a/juniper_hyper/Cargo.toml b/juniper_hyper/Cargo.toml index 28525061..2ac41d24 100644 --- a/juniper_hyper/Cargo.toml +++ b/juniper_hyper/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "juniper_hyper" -version = "0.5.0" +version = "0.5.1" authors = ["Damir Vandic "] description = "Juniper GraphQL integration with Hyper" license = "BSD-2-Clause" @@ -13,7 +13,7 @@ serde = "1.0" serde_json = "1.0" serde_derive = "1.0" url = "2" -juniper = { version = "0.14.0", default-features = false, path = "../juniper"} +juniper = { version = "0.14.1", default-features = false, path = "../juniper"} futures = "0.1" tokio = "0.1.8" @@ -25,6 +25,6 @@ pretty_env_logger = "0.2" reqwest = "0.9" [dev-dependencies.juniper] -version = "0.14.0" +version = "0.14.1" features = ["expose-test-schema", "serde_json"] path = "../juniper" diff --git a/juniper_iron/CHANGELOG.md b/juniper_iron/CHANGELOG.md index 60c8be81..00de0024 100644 --- a/juniper_iron/CHANGELOG.md +++ b/juniper_iron/CHANGELOG.md @@ -2,6 +2,10 @@ - Compatibility with the latest `juniper`. +# [[0.6.1] 2019-10-24](https://github.com/graphql-rust/juniper/releases/tag/juniper_iron-0.6.1) + +- Compatibility with the latest `juniper`. + # [[0.6.0] 2019-09-29](https://github.com/graphql-rust/juniper/releases/tag/juniper_iron-0.6.0) - Compatibility with the latest `juniper`. diff --git a/juniper_iron/Cargo.toml b/juniper_iron/Cargo.toml index 81ad40c2..1a53bc49 100644 --- a/juniper_iron/Cargo.toml +++ b/juniper_iron/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "juniper_iron" -version = "0.6.0" +version = "0.6.1" authors = [ "Magnus Hallin ", "Christoph Herzog ", @@ -15,7 +15,7 @@ edition = "2018" serde = { version = "1.0.2" } serde_json = { version = "1.0.2" } serde_derive = { version = "1.0.2" } -juniper = { version = "0.14.0", path = "../juniper" } +juniper = { version = "0.14.1", path = "../juniper" } urlencoded = { version = ">= 0.5, < 0.7" } iron = ">= 0.5, < 0.7" @@ -29,6 +29,6 @@ url = "2" percent-encoding = "2" [dev-dependencies.juniper] -version = "0.14.0" +version = "0.14.1" features = ["expose-test-schema", "serde_json"] path = "../juniper" diff --git a/juniper_rocket/CHANGELOG.md b/juniper_rocket/CHANGELOG.md index fd9e102e..01432d4b 100644 --- a/juniper_rocket/CHANGELOG.md +++ b/juniper_rocket/CHANGELOG.md @@ -2,6 +2,10 @@ - Compatibility with the latest `juniper`. +# [[0.5.1] 2019-10-24](https://github.com/graphql-rust/juniper/releases/tag/juniper_rocket-0.5.1) + +- Compatibility with the latest `juniper`. + # [[0.5.0] 2019-09-29](https://github.com/graphql-rust/juniper/releases/tag/juniper_rocket-0.5.0) - Compatibility with the latest `juniper`. diff --git a/juniper_rocket/Cargo.toml b/juniper_rocket/Cargo.toml index ad4cc5bc..84c493c6 100644 --- a/juniper_rocket/Cargo.toml +++ b/juniper_rocket/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "juniper_rocket" -version = "0.5.0" +version = "0.5.1" authors = [ "Magnus Hallin ", "Christoph Herzog ", diff --git a/juniper_warp/CHANGELOG.md b/juniper_warp/CHANGELOG.md index eee06a3e..be3a836a 100644 --- a/juniper_warp/CHANGELOG.md +++ b/juniper_warp/CHANGELOG.md @@ -2,6 +2,10 @@ - Compatibility with the latest `juniper`. +# [[0.5.1] 2019-10-24](https://github.com/graphql-rust/juniper/releases/tag/juniper_warp-0.5.1) + +- Compatibility with the latest `juniper`. + # [[0.5.0] 2019-09-29](https://github.com/graphql-rust/juniper/releases/tag/juniper_warp-0.5.0) - Compatibility with the latest `juniper`. diff --git a/juniper_warp/Cargo.toml b/juniper_warp/Cargo.toml index a1c1907c..ce65df0f 100644 --- a/juniper_warp/Cargo.toml +++ b/juniper_warp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "juniper_warp" -version = "0.5.0" +version = "0.5.1" authors = ["Tom Houlé "] description = "Juniper GraphQL integration with Warp" license = "BSD-2-Clause" @@ -24,7 +24,7 @@ tokio-threadpool = "0.1.7" futures03 = { version = "=0.3.0-alpha.19", optional = true, package = "futures-preview", features = ["compat"] } [dev-dependencies] -juniper = { version = "0.14.0", path = "../juniper", features = ["expose-test-schema", "serde_json"] } +juniper = { version = "0.14.1", path = "../juniper", features = ["expose-test-schema", "serde_json"] } env_logger = "0.5.11" log = "0.4.3" percent-encoding = "1.0" diff --git a/juniper_warp/src/lib.rs b/juniper_warp/src/lib.rs index 55d423fd..7e295a9c 100644 --- a/juniper_warp/src/lib.rs +++ b/juniper_warp/src/lib.rs @@ -41,6 +41,7 @@ Check the LICENSE file for details. #![doc(html_root_url = "https://docs.rs/juniper_warp/0.2.0")] use futures::{future::poll_fn, Future}; +use juniper::{DefaultScalarValue, InputValue, ScalarRefValue, ScalarValue}; use serde::Deserialize; use std::sync::Arc; use warp::{filters::BoxedFilter, Filter}; @@ -48,8 +49,6 @@ use warp::{filters::BoxedFilter, Filter}; #[cfg(feature = "async")] use futures03::future::{FutureExt, TryFutureExt}; -use juniper::{DefaultScalarValue, InputValue, ScalarRefValue, ScalarValue}; - #[derive(Debug, serde_derive::Deserialize, PartialEq)] #[serde(untagged)] #[serde(bound = "InputValue: Deserialize<'de>")]