Rebase onto master
This commit is contained in:
parent
4834349310
commit
09d9513da9
21 changed files with 219 additions and 50 deletions
127
benches/bench.rs
Normal file
127
benches/bench.rs
Normal file
|
@ -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::<Database>::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::<Database>::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);
|
|
@ -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.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "juniper"
|
||||
version = "0.14.0"
|
||||
version = "0.14.1"
|
||||
authors = [
|
||||
"Magnus Hallin <mhallin@fastmail.com>",
|
||||
"Christoph Herzog <chris@theduke.at>",
|
||||
|
@ -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 }
|
||||
|
|
|
@ -210,20 +210,6 @@ impl<S> FieldError<S> {
|
|||
/// The result of resolving the value of a field of type `T`
|
||||
pub type FieldResult<T, S = DefaultScalarValue> = Result<T, FieldError<S>>;
|
||||
|
||||
/*
|
||||
pub enum ResolvedValue<'a, S = DefaultScalarValue> {
|
||||
Value(Value<S>),
|
||||
Future(crate::BoxFuture<'a, Value<S>>),
|
||||
}
|
||||
|
||||
impl<'a, S> From<Value<S>> for ResolvedValue<'a, S> {
|
||||
#[inline]
|
||||
fn from(value: Value<S>) -> Self {
|
||||
ResolvedValue::Value(value)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/// The result of resolving an unspecified field
|
||||
pub type ExecutionResult<S = DefaultScalarValue> = Result<Value<S>, FieldError<S>>;
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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::<QueryWithoutFloat, EmptyMutation<()>>(&(), &());
|
||||
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")
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -343,7 +343,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub fn resolve_selection_set_into<T, CtxT, S>(
|
||||
pub(crate) fn resolve_selection_set_into<T, CtxT, S>(
|
||||
instance: &T,
|
||||
info: &T::TypeInfo,
|
||||
selection_set: &[Selection<S>],
|
||||
|
|
|
@ -308,6 +308,9 @@ impl<T> EmptyMutation<T> {
|
|||
}
|
||||
}
|
||||
|
||||
// This is safe due to never using `T`.
|
||||
unsafe impl<T> Send for EmptyMutation<T> {}
|
||||
|
||||
impl<S, T> GraphQLType<S> for EmptyMutation<T>
|
||||
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<T: Send>() {}
|
||||
check_if_send::<EmptyMutation<()>>();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -260,8 +260,6 @@ pub enum DefaultScalarValue {
|
|||
Boolean(bool),
|
||||
}
|
||||
|
||||
trait S: Send + Sync {}
|
||||
|
||||
impl ScalarValue for DefaultScalarValue {
|
||||
type Visitor = DefaultScalarValueVisitor;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "juniper_codegen"
|
||||
version = "0.14.0"
|
||||
version = "0.14.1"
|
||||
authors = [
|
||||
"Magnus Hallin <mhallin@fastmail.com>",
|
||||
"Christoph Herzog <chris@theduke.at>",
|
||||
|
@ -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" }
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "juniper_hyper"
|
||||
version = "0.5.0"
|
||||
version = "0.5.1"
|
||||
authors = ["Damir Vandic <info@dvic.io>"]
|
||||
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"
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "juniper_iron"
|
||||
version = "0.6.0"
|
||||
version = "0.6.1"
|
||||
authors = [
|
||||
"Magnus Hallin <mhallin@fastmail.com>",
|
||||
"Christoph Herzog <chris@theduke.at>",
|
||||
|
@ -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"
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "juniper_rocket"
|
||||
version = "0.5.0"
|
||||
version = "0.5.1"
|
||||
authors = [
|
||||
"Magnus Hallin <mhallin@fastmail.com>",
|
||||
"Christoph Herzog <chris@theduke.at>",
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "juniper_warp"
|
||||
version = "0.5.0"
|
||||
version = "0.5.1"
|
||||
authors = ["Tom Houlé <tom@tomhoule.com>"]
|
||||
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"
|
||||
|
|
|
@ -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<S>: Deserialize<'de>")]
|
||||
|
|
Loading…
Reference in a new issue