From 8b02019f191865c4de4e23bb6e3ab005c5662ae4 Mon Sep 17 00:00:00 2001 From: Audun Halland Date: Tue, 5 Mar 2024 02:45:25 +0100 Subject: [PATCH] refactor: use ArcStr for storing strings in Schema --- benches/src/lib.rs | 3 +- book/src/advanced/introspection.md | 1 - book/src/advanced/subscriptions.md | 2 +- book/src/quickstart.md | 4 +- juniper/Cargo.toml | 2 +- juniper/src/ast.rs | 21 +- juniper/src/executor/mod.rs | 99 ++--- juniper/src/executor/owned_executor.rs | 10 +- juniper/src/http/mod.rs | 6 +- juniper/src/lib.rs | 8 +- juniper/src/parser/document.rs | 89 ++-- juniper/src/parser/parser.rs | 2 - juniper/src/parser/tests/value.rs | 8 +- juniper/src/parser/value.rs | 28 +- juniper/src/schema/meta.rs | 248 ++++++----- juniper/src/schema/model.rs | 227 ++++++---- juniper/src/schema/schema.rs | 61 +-- .../src/schema/translate/graphql_parser.rs | 17 +- juniper/src/tests/subscriptions.rs | 3 +- juniper/src/tests/type_info_tests.rs | 18 +- juniper/src/types/async_await.rs | 2 +- juniper/src/types/base.rs | 29 +- juniper/src/types/containers.rs | 38 +- juniper/src/types/marker.rs | 3 + juniper/src/types/name.rs | 32 +- juniper/src/types/nullable.rs | 11 +- juniper/src/types/pointers.rs | 29 +- juniper/src/types/scalars.rs | 95 ++++- juniper/src/types/subscriptions.rs | 2 +- juniper/src/types/utilities.rs | 10 +- juniper/src/validation/context.rs | 37 +- juniper/src/validation/input_value.rs | 6 +- .../rules/arguments_of_correct_type.rs | 6 +- .../rules/default_values_of_correct_type.rs | 3 +- .../validation/rules/known_argument_names.rs | 2 +- .../rules/overlapping_fields_can_be_merged.rs | 194 ++++----- .../rules/possible_fragment_spreads.rs | 2 +- .../rules/variables_in_allowed_position.rs | 13 +- juniper/src/validation/test_harness.rs | 394 ++++++++---------- juniper/src/validation/visitor.rs | 52 +-- juniper_actix/examples/subscription.rs | 2 +- juniper_actix/src/lib.rs | 17 +- juniper_axum/examples/custom.rs | 2 +- juniper_axum/examples/simple.rs | 2 +- juniper_axum/src/extract.rs | 2 +- juniper_axum/src/lib.rs | 2 +- juniper_axum/src/subscriptions.rs | 12 +- juniper_axum/tests/http_test_suite.rs | 2 +- juniper_axum/tests/ws_test_suite.rs | 2 +- juniper_codegen/src/common/deprecation.rs | 11 +- juniper_codegen/src/common/description.rs | 6 +- juniper_codegen/src/common/field/arg.rs | 4 +- juniper_codegen/src/common/field/mod.rs | 2 +- juniper_codegen/src/graphql_enum/mod.rs | 15 +- .../src/graphql_input_object/mod.rs | 18 +- juniper_codegen/src/graphql_interface/mod.rs | 13 +- juniper_codegen/src/graphql_object/mod.rs | 13 +- juniper_codegen/src/graphql_scalar/mod.rs | 16 +- .../src/graphql_subscription/mod.rs | 2 +- juniper_codegen/src/graphql_union/mod.rs | 13 +- .../src/graphql_transport_ws/mod.rs | 2 +- juniper_graphql_ws/src/graphql_ws/mod.rs | 2 +- juniper_graphql_ws/src/schema.rs | 10 +- juniper_hyper/src/lib.rs | 8 +- juniper_rocket/examples/simple.rs | 2 +- juniper_rocket/src/lib.rs | 6 +- juniper_rocket/tests/http_test_suite.rs | 2 +- juniper_subscriptions/examples/basic.rs | 2 +- juniper_subscriptions/src/lib.rs | 12 +- juniper_warp/examples/subscription.rs | 2 +- juniper_warp/src/lib.rs | 32 +- juniper_warp/src/subscriptions.rs | 6 +- .../derive_incompatible_field_type.stderr | 6 +- .../attr_field_non_output_return_type.stderr | 2 +- ...derive_field_non_output_return_type.stderr | 2 +- .../trait/argument_non_input_type.stderr | 6 +- .../trait/field_non_output_return_type.stderr | 2 +- .../object/argument_non_input_type.stderr | 6 +- .../attr_field_non_output_return_type.stderr | 2 +- ...derive_field_non_output_return_type.stderr | 2 +- .../argument_non_input_type.stderr | 6 +- .../field_non_output_return_type.stderr | 2 +- .../fail/union/enum_non_object_variant.stderr | 8 +- .../union/struct_non_object_variant.stderr | 8 +- .../union/trait_non_object_variant.stderr | 8 +- .../tests/codegen_subscription_attr.rs | 18 +- tests/integration/tests/common/mod.rs | 14 +- tests/integration/tests/cve_2022_31173.rs | 2 +- tests/integration/tests/explicit_null.rs | 2 +- tests/integration/tests/issue_371.rs | 2 +- tests/integration/tests/issue_398.rs | 2 +- tests/integration/tests/issue_407.rs | 2 +- tests/integration/tests/issue_500.rs | 2 +- tests/integration/tests/issue_798.rs | 2 +- tests/integration/tests/issue_914.rs | 2 +- tests/integration/tests/issue_922.rs | 2 +- tests/integration/tests/issue_925.rs | 2 +- tests/integration/tests/issue_945.rs | 2 +- tests/integration/tests/pre_parse.rs | 2 +- 99 files changed, 1095 insertions(+), 1080 deletions(-) diff --git a/benches/src/lib.rs b/benches/src/lib.rs index c8ad5b512..24d481034 100644 --- a/benches/src/lib.rs +++ b/benches/src/lib.rs @@ -89,8 +89,7 @@ impl Query { } } -pub fn new_schema() -> RootNode<'static, Query, EmptyMutation, EmptySubscription> -{ +pub fn new_schema() -> RootNode, EmptySubscription> { RootNode::new(Query, EmptyMutation::new(), EmptySubscription::new()) } diff --git a/book/src/advanced/introspection.md b/book/src/advanced/introspection.md index d7bc7c2f8..3643bc710 100644 --- a/book/src/advanced/introspection.md +++ b/book/src/advanced/introspection.md @@ -58,7 +58,6 @@ impl Query { } type Schema = juniper::RootNode< - 'static, Query, EmptyMutation, EmptySubscription diff --git a/book/src/advanced/subscriptions.md b/book/src/advanced/subscriptions.md index 9aaa93635..9a1e99f7e 100644 --- a/book/src/advanced/subscriptions.md +++ b/book/src/advanced/subscriptions.md @@ -124,7 +124,7 @@ where [`Connection`][Connection] is a `Stream` of values returned by the operati # Box::pin(stream) # } # } -type Schema = RootNode<'static, Query, EmptyMutation, Subscription>; +type Schema = RootNode, Subscription>; fn schema() -> Schema { Schema::new(Query, EmptyMutation::new(), Subscription) diff --git a/book/src/quickstart.md b/book/src/quickstart.md index a8633414e..180151c8b 100644 --- a/book/src/quickstart.md +++ b/book/src/quickstart.md @@ -127,7 +127,7 @@ impl Mutation { // A root schema consists of a query, a mutation, and a subscription. // Request queries can be executed against a RootNode. -type Schema = juniper::RootNode<'static, Query, Mutation, EmptySubscription>; +type Schema = juniper::RootNode>; # # fn main() { # let _ = Schema::new(Query, Mutation, EmptySubscription::new()); @@ -175,7 +175,7 @@ impl Query { // A root schema consists of a query, a mutation, and a subscription. // Request queries can be executed against a RootNode. -type Schema = juniper::RootNode<'static, Query, EmptyMutation, EmptySubscription>; +type Schema = juniper::RootNode, EmptySubscription>; fn main() { // Create a context object. diff --git a/juniper/Cargo.toml b/juniper/Cargo.toml index cc709507c..99d037e3a 100644 --- a/juniper/Cargo.toml +++ b/juniper/Cargo.toml @@ -48,6 +48,7 @@ uuid = ["dep:uuid"] [dependencies] anyhow = { version = "1.0.47", optional = true } +arcstr = "1" async-trait = "0.1.39" auto_enums = "0.8" bigdecimal = { version = "0.4", optional = true } @@ -63,7 +64,6 @@ rust_decimal = { version = "1.20", default-features = false, optional = true } ryu = { version = "1.0", optional = true } serde = { version = "1.0.122", features = ["derive"] } serde_json = { version = "1.0.18", features = ["std"], default-features = false, optional = true } -smartstring = "1.0" static_assertions = "1.1" time = { version = "0.3", features = ["formatting", "macros", "parsing"], optional = true } url = { version = "2.0", optional = true } diff --git a/juniper/src/ast.rs b/juniper/src/ast.rs index 3a3c4de31..b8c30bf1a 100644 --- a/juniper/src/ast.rs +++ b/juniper/src/ast.rs @@ -3,6 +3,7 @@ use std::{borrow::Cow, fmt, hash::Hash, slice, vec}; use indexmap::IndexMap; use crate::{ + ArcStr, executor::Variables, parser::Spanning, value::{DefaultScalarValue, ScalarValue}, @@ -13,19 +14,19 @@ use crate::{ /// This enum carries no semantic information and might refer to types that do /// not exist. #[derive(Clone, Eq, PartialEq, Debug)] -pub enum Type<'a> { +pub enum Type { /// A nullable named type, e.g. `String` - Named(Cow<'a, str>), + Named(N), /// A nullable list type, e.g. `[String]` /// /// The list itself is what's nullable, the containing type might be non-null. - List(Box>, Option), + List(Box>, Option), /// A non-null named type, e.g. `String!` - NonNullNamed(Cow<'a, str>), + NonNullNamed(N), /// A non-null list type, e.g. `[String]!`. /// /// The list itself is what's non-null, the containing type might be null. - NonNullList(Box>, Option), + NonNullList(Box>, Option), } /// A JSON-like value that can be passed into the query execution, either @@ -47,7 +48,7 @@ pub enum InputValue { #[derive(Clone, PartialEq, Debug)] pub struct VariableDefinition<'a, S> { - pub var_type: Spanning>, + pub var_type: Spanning>, pub default_value: Option>>, pub directives: Option>>>, } @@ -194,13 +195,13 @@ pub trait ToInputValue: Sized { fn to_input_value(&self) -> InputValue; } -impl<'a> Type<'a> { +impl> Type { /// Get the name of a named type. /// /// Only applies to named types; lists will return `None`. pub fn name(&self) -> Option<&str> { match *self { - Type::Named(ref n) | Type::NonNullNamed(ref n) => Some(n), + Type::Named(ref n) | Type::NonNullNamed(ref n) => Some(n.as_ref()), _ => None, } } @@ -210,7 +211,7 @@ impl<'a> Type<'a> { /// All type literals contain exactly one named type. pub fn innermost_name(&self) -> &str { match *self { - Type::Named(ref n) | Type::NonNullNamed(ref n) => n, + Type::Named(ref n) | Type::NonNullNamed(ref n) => n.as_ref(), Type::List(ref l, _) | Type::NonNullList(ref l, _) => l.innermost_name(), } } @@ -221,7 +222,7 @@ impl<'a> Type<'a> { } } -impl<'a> fmt::Display for Type<'a> { +impl fmt::Display for Type { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Named(n) => write!(f, "{n}"), diff --git a/juniper/src/executor/mod.rs b/juniper/src/executor/mod.rs index d091bbf8d..4ea03c835 100644 --- a/juniper/src/executor/mod.rs +++ b/juniper/src/executor/mod.rs @@ -8,6 +8,7 @@ use std::{ sync::{Arc, RwLock}, }; +use arcstr::ArcStr; use fnv::FnvHashMap; use futures::Stream; @@ -16,6 +17,7 @@ use crate::{ Definition, Document, Fragment, FromInputValue, InputValue, Operation, OperationType, Selection, ToInputValue, Type, }, + literal, parser::{SourcePosition, Spanning}, schema::{ meta::{ @@ -23,7 +25,7 @@ use crate::{ InterfaceMeta, ListMeta, MetaType, NullableMeta, ObjectMeta, PlaceholderMeta, ScalarMeta, UnionMeta, }, - model::{RootNode, SchemaType, TypeType}, + model::{AsDynType, RootNode, SchemaType, TypeType}, }, types::{ async_await::{GraphQLTypeAsync, GraphQLValueAsync}, @@ -51,9 +53,9 @@ mod owned_executor; /// The registry gathers metadata for all types in a schema. It provides /// convenience methods to convert types implementing the `GraphQLType` trait /// into `Type` instances and automatically registers them. -pub struct Registry<'r, S = DefaultScalarValue> { +pub struct Registry { /// Currently registered types - pub types: FnvHashMap>, + pub types: FnvHashMap>, } #[allow(missing_docs)] @@ -77,7 +79,7 @@ where current_selection_set: Option<&'r [Selection<'a, S>]>, parent_selection_set: Option<&'r [Selection<'a, S>]>, current_type: TypeType<'a, S>, - schema: &'a SchemaType<'a, S>, + schema: &'a SchemaType, context: &'a CtxT, errors: &'r RwLock>>, field_path: Arc>, @@ -578,12 +580,12 @@ where current_selection_set: selection_set, parent_selection_set: self.current_selection_set, current_type: self.schema.make_type( - &self - .current_type + self.current_type .innermost_concrete() .field_by_name(field_name) .expect("Field not found on inner type") - .field_type, + .field_type + .as_dyn_type(), ), schema: self.schema, context: self.context, @@ -898,7 +900,7 @@ where pub async fn execute_validated_query_async<'a, 'b, QueryT, MutationT, SubscriptionT, S>( document: &'b Document<'a, S>, operation: &'b Spanning>, - root_node: &RootNode<'a, QueryT, MutationT, SubscriptionT, S>, + root_node: &RootNode, variables: &Variables, context: &QueryT::Context, ) -> Result<(Value, Vec>), GraphQLError> @@ -1042,7 +1044,7 @@ pub async fn resolve_validated_subscription< >( document: &Document<'d, S>, operation: &Spanning>, - root_node: &'r RootNode<'r, QueryT, MutationT, SubscriptionT, S>, + root_node: &'r RootNode, variables: &Variables, context: &'r QueryT::Context, ) -> Result<(Value>, Vec>), GraphQLError> @@ -1138,9 +1140,9 @@ where Ok((value, errors)) } -impl<'r, S: 'r> Registry<'r, S> { +impl<'r, S: 'r> Registry { /// Constructs a new [`Registry`] out of the given `types`. - pub fn new(types: FnvHashMap>) -> Self { + pub fn new(types: FnvHashMap>) -> Self { Self { types } } @@ -1149,35 +1151,32 @@ impl<'r, S: 'r> Registry<'r, S> { /// /// If this [`Registry`] hasn't seen a [`Type`] with such /// [`GraphQLType::name`] before, it will construct the one and store it. - pub fn get_type(&mut self, info: &T::TypeInfo) -> Type<'r> + pub fn get_type(&mut self, info: &T::TypeInfo) -> Type where T: GraphQLType + ?Sized, S: ScalarValue, { if let Some(name) = T::name(info) { - let validated_name = name.parse::().unwrap(); - if !self.types.contains_key(name) { - self.insert_placeholder( - validated_name.clone(), - Type::NonNullNamed(Cow::Owned(name.into())), - ); + let validated_name = Name::new(name.clone()).unwrap(); + if !self.types.contains_key(&name) { + self.insert_placeholder(validated_name.clone(), Type::NonNullNamed(name.clone())); let meta = T::meta(info, self); self.types.insert(validated_name, meta); } - self.types[name].as_type() + self.types[&name].as_type() } else { T::meta(info, self).as_type() } } /// Creates a [`Field`] with the provided `name`. - pub fn field(&mut self, name: &str, info: &T::TypeInfo) -> Field<'r, S> + pub fn field(&mut self, name: ArcStr, info: &T::TypeInfo) -> Field where T: GraphQLType + ?Sized, S: ScalarValue, { Field { - name: smartstring::SmartString::from(name), + name, description: None, arguments: None, field_type: self.get_type::(info), @@ -1188,15 +1187,15 @@ impl<'r, S: 'r> Registry<'r, S> { #[doc(hidden)] pub fn field_convert<'a, T: IntoResolvable<'a, S, I, C>, I, C>( &mut self, - name: &str, + name: ArcStr, info: &I::TypeInfo, - ) -> Field<'r, S> + ) -> Field where I: GraphQLType, S: ScalarValue, { Field { - name: name.into(), + name, description: None, arguments: None, field_type: self.get_type::(info), @@ -1205,7 +1204,7 @@ impl<'r, S: 'r> Registry<'r, S> { } /// Creates an [`Argument`] with the provided `name`. - pub fn arg(&mut self, name: &str, info: &T::TypeInfo) -> Argument<'r, S> + pub fn arg(&mut self, name: ArcStr, info: &T::TypeInfo) -> Argument where T: GraphQLType + FromInputValue, S: ScalarValue, @@ -1216,10 +1215,10 @@ impl<'r, S: 'r> Registry<'r, S> { /// Creates an [`Argument`] with the provided default `value`. pub fn arg_with_default( &mut self, - name: &str, + name: ArcStr, value: &T, info: &T::TypeInfo, - ) -> Argument<'r, S> + ) -> Argument where T: GraphQLType + ToInputValue + FromInputValue, S: ScalarValue, @@ -1227,14 +1226,14 @@ impl<'r, S: 'r> Registry<'r, S> { Argument::new(name, self.get_type::(info)).default_value(value.to_input_value()) } - fn insert_placeholder(&mut self, name: Name, of_type: Type<'r>) { + fn insert_placeholder(&mut self, name: Name, of_type: Type) { self.types .entry(name) .or_insert(MetaType::Placeholder(PlaceholderMeta { of_type })); } /// Creates a [`ScalarMeta`] type. - pub fn build_scalar_type(&mut self, info: &T::TypeInfo) -> ScalarMeta<'r, S> + pub fn build_scalar_type(&mut self, info: &T::TypeInfo) -> ScalarMeta where T: GraphQLType + FromInputValue + ParseScalarValue, T::Error: IntoFieldError, @@ -1242,7 +1241,7 @@ impl<'r, S: 'r> Registry<'r, S> { { let name = T::name(info).expect("Scalar types must be named. Implement `name()`"); - ScalarMeta::new::(Cow::Owned(name.into())) + ScalarMeta::new::(name) } /// Creates a [`ListMeta`] type. @@ -1253,7 +1252,7 @@ impl<'r, S: 'r> Registry<'r, S> { &mut self, info: &T::TypeInfo, expected_size: Option, - ) -> ListMeta<'r> + ) -> ListMeta where T: GraphQLType + ?Sized, S: ScalarValue, @@ -1263,7 +1262,7 @@ impl<'r, S: 'r> Registry<'r, S> { } /// Creates a [`NullableMeta`] type. - pub fn build_nullable_type(&mut self, info: &T::TypeInfo) -> NullableMeta<'r> + pub fn build_nullable_type(&mut self, info: &T::TypeInfo) -> NullableMeta where T: GraphQLType + ?Sized, S: ScalarValue, @@ -1273,11 +1272,7 @@ impl<'r, S: 'r> Registry<'r, S> { } /// Creates an [`ObjectMeta`] type with the given `fields`. - pub fn build_object_type( - &mut self, - info: &T::TypeInfo, - fields: &[Field<'r, S>], - ) -> ObjectMeta<'r, S> + pub fn build_object_type(&mut self, info: &T::TypeInfo, fields: &[Field]) -> ObjectMeta where T: GraphQLType + ?Sized, S: ScalarValue, @@ -1285,16 +1280,12 @@ impl<'r, S: 'r> Registry<'r, S> { let name = T::name(info).expect("Object types must be named. Implement name()"); let mut v = fields.to_vec(); - v.push(self.field::("__typename", &())); - ObjectMeta::new(Cow::Owned(name.into()), &v) + v.push(self.field::(literal!("__typename"), &())); + ObjectMeta::new(name, &v) } /// Creates an [`EnumMeta`] type out of the provided `values`. - pub fn build_enum_type( - &mut self, - info: &T::TypeInfo, - values: &[EnumValue], - ) -> EnumMeta<'r, S> + pub fn build_enum_type(&mut self, info: &T::TypeInfo, values: &[EnumValue]) -> EnumMeta where T: GraphQLType + FromInputValue, T::Error: IntoFieldError, @@ -1302,15 +1293,15 @@ impl<'r, S: 'r> Registry<'r, S> { { let name = T::name(info).expect("Enum types must be named. Implement `name()`"); - EnumMeta::new::(Cow::Owned(name.into()), values) + EnumMeta::new::(name, values) } /// Creates an [`InterfaceMeta`] type with the given `fields`. pub fn build_interface_type( &mut self, info: &T::TypeInfo, - fields: &[Field<'r, S>], - ) -> InterfaceMeta<'r, S> + fields: &[Field], + ) -> InterfaceMeta where T: GraphQLType + ?Sized, S: ScalarValue, @@ -1318,27 +1309,27 @@ impl<'r, S: 'r> Registry<'r, S> { let name = T::name(info).expect("Interface types must be named. Implement name()"); let mut v = fields.to_vec(); - v.push(self.field::("__typename", &())); - InterfaceMeta::new(Cow::Owned(name.into()), &v) + v.push(self.field::(literal!("__typename"), &())); + InterfaceMeta::new(name, &v) } /// Creates an [`UnionMeta`] type of the given `types`. - pub fn build_union_type(&mut self, info: &T::TypeInfo, types: &[Type<'r>]) -> UnionMeta<'r> + pub fn build_union_type(&mut self, info: &T::TypeInfo, types: &[Type]) -> UnionMeta where T: GraphQLType + ?Sized, S: ScalarValue, { let name = T::name(info).expect("Union types must be named. Implement name()"); - UnionMeta::new(Cow::Owned(name.into()), types) + UnionMeta::new(name, types) } /// Creates an [`InputObjectMeta`] type with the given `args`. pub fn build_input_object_type( &mut self, info: &T::TypeInfo, - args: &[Argument<'r, S>], - ) -> InputObjectMeta<'r, S> + args: &[Argument], + ) -> InputObjectMeta where T: GraphQLType + FromInputValue, T::Error: IntoFieldError, @@ -1346,6 +1337,6 @@ impl<'r, S: 'r> Registry<'r, S> { { let name = T::name(info).expect("Input object types must be named. Implement name()"); - InputObjectMeta::new::(Cow::Owned(name.into()), args) + InputObjectMeta::new::(name, args) } } diff --git a/juniper/src/executor/owned_executor.rs b/juniper/src/executor/owned_executor.rs index cce1a208e..7446b3036 100644 --- a/juniper/src/executor/owned_executor.rs +++ b/juniper/src/executor/owned_executor.rs @@ -7,7 +7,7 @@ use crate::{ ast::Fragment, executor::FieldPath, parser::SourcePosition, - schema::model::{SchemaType, TypeType}, + schema::model::{AsDynType, SchemaType, TypeType}, ExecutionError, Executor, Selection, Variables, }; @@ -19,7 +19,7 @@ pub struct OwnedExecutor<'a, CtxT, S> { pub(super) current_selection_set: Option>>, pub(super) parent_selection_set: Option>>, pub(super) current_type: TypeType<'a, S>, - pub(super) schema: &'a SchemaType<'a, S>, + pub(super) schema: &'a SchemaType, pub(super) context: &'a CtxT, pub(super) errors: RwLock>>, pub(super) field_path: Arc>, @@ -91,12 +91,12 @@ where current_selection_set: selection_set, parent_selection_set: self.current_selection_set.clone(), current_type: self.schema.make_type( - &self - .current_type + self.current_type .innermost_concrete() .field_by_name(field_name) .expect("Field not found on inner type") - .field_type, + .field_type + .as_dyn_type(), ), schema: self.schema, context: self.context, diff --git a/juniper/src/http/mod.rs b/juniper/src/http/mod.rs index 38ef764f2..a8a47837a 100644 --- a/juniper/src/http/mod.rs +++ b/juniper/src/http/mod.rs @@ -110,7 +110,7 @@ where /// top level of this crate. pub async fn execute<'a, QueryT, MutationT, SubscriptionT>( &'a self, - root_node: &'a RootNode<'a, QueryT, MutationT, SubscriptionT, S>, + root_node: &'a RootNode, context: &'a QueryT::Context, ) -> GraphQLResponse where @@ -136,7 +136,7 @@ where /// level of this crate. pub async fn resolve_into_stream<'req, 'rn, 'ctx, 'a, QueryT, MutationT, SubscriptionT, S>( req: &'req GraphQLRequest, - root_node: &'rn RootNode<'a, QueryT, MutationT, SubscriptionT, S>, + root_node: &'rn RootNode, context: &'ctx QueryT::Context, ) -> Result<(Value>, Vec>), GraphQLError> where @@ -296,7 +296,7 @@ where /// GraphQLRequest pub async fn execute<'a, QueryT, MutationT, SubscriptionT>( &'a self, - root_node: &'a RootNode<'a, QueryT, MutationT, SubscriptionT, S>, + root_node: &'a RootNode, context: &'a QueryT::Context, ) -> GraphQLBatchResponse where diff --git a/juniper/src/lib.rs b/juniper/src/lib.rs index 7b8bc4f73..58a92ace1 100644 --- a/juniper/src/lib.rs +++ b/juniper/src/lib.rs @@ -26,6 +26,10 @@ pub use juniper_codegen::{ GraphQLEnum, GraphQLInputObject, GraphQLInterface, GraphQLObject, GraphQLScalar, GraphQLUnion, }; +pub use arcstr::literal; + +pub use arcstr::ArcStr; + #[doc(hidden)] #[macro_use] pub mod macros; @@ -193,7 +197,7 @@ where pub async fn execute<'a, S, QueryT, MutationT, SubscriptionT>( document_source: &'a str, operation_name: Option<&str>, - root_node: &'a RootNode<'a, QueryT, MutationT, SubscriptionT, S>, + root_node: &'a RootNode, variables: &Variables, context: &QueryT::Context, ) -> Result<(Value, Vec>), GraphQLError> @@ -244,7 +248,7 @@ where pub async fn resolve_into_stream<'a, S, QueryT, MutationT, SubscriptionT>( document_source: &'a str, operation_name: Option<&str>, - root_node: &'a RootNode<'a, QueryT, MutationT, SubscriptionT, S>, + root_node: &'a RootNode, variables: &Variables, context: &'a QueryT::Context, ) -> Result<(Value>, Vec>), GraphQLError> diff --git a/juniper/src/parser/document.rs b/juniper/src/parser/document.rs index 4ace75abc..fd65cd537 100644 --- a/juniper/src/parser/document.rs +++ b/juniper/src/parser/document.rs @@ -1,5 +1,3 @@ -use std::borrow::Cow; - use crate::ast::{ Arguments, Definition, Directive, Field, Fragment, FragmentSpread, InlineFragment, InputValue, Operation, OperationType, OwnedDocument, Selection, Type, VariableDefinition, @@ -19,9 +17,9 @@ use crate::{ }; #[doc(hidden)] -pub fn parse_document_source<'a, 'b, S>( +pub fn parse_document_source<'a, S>( s: &'a str, - schema: &'b SchemaType<'b, S>, + schema: &SchemaType, ) -> UnlocatedParseResult> where S: ScalarValue, @@ -31,9 +29,9 @@ where parse_document(&mut parser, schema) } -fn parse_document<'a, 'b, S>( +fn parse_document<'a, S>( parser: &mut Parser<'a>, - schema: &'b SchemaType<'b, S>, + schema: &SchemaType, ) -> UnlocatedParseResult> where S: ScalarValue, @@ -49,9 +47,9 @@ where } } -fn parse_definition<'a, 'b, S>( +fn parse_definition<'a, S>( parser: &mut Parser<'a>, - schema: &'b SchemaType<'b, S>, + schema: &SchemaType, ) -> UnlocatedParseResult> where S: ScalarValue, @@ -70,9 +68,9 @@ where } } -fn parse_operation_definition<'a, 'b, S>( +fn parse_operation_definition<'a, S>( parser: &mut Parser<'a>, - schema: &'b SchemaType<'b, S>, + schema: &SchemaType, ) -> ParseResult> where S: ScalarValue, @@ -125,9 +123,9 @@ where } } -fn parse_fragment_definition<'a, 'b, S>( +fn parse_fragment_definition<'a, S>( parser: &mut Parser<'a>, - schema: &'b SchemaType<'b, S>, + schema: &SchemaType, ) -> ParseResult> where S: ScalarValue, @@ -167,10 +165,10 @@ where )) } -fn parse_optional_selection_set<'a, 'b, S>( +fn parse_optional_selection_set<'a, S>( parser: &mut Parser<'a>, - schema: &'b SchemaType<'b, S>, - fields: Option<&[&MetaField<'b, S>]>, + schema: &SchemaType, + fields: Option<&[&MetaField]>, ) -> OptionParseResult>> where S: ScalarValue, @@ -182,10 +180,10 @@ where } } -fn parse_selection_set<'a, 'b, S>( +fn parse_selection_set<'a, S>( parser: &mut Parser<'a>, - schema: &'b SchemaType<'b, S>, - fields: Option<&[&MetaField<'b, S>]>, + schema: &SchemaType, + fields: Option<&[&MetaField]>, ) -> ParseResult>> where S: ScalarValue, @@ -197,10 +195,10 @@ where ) } -fn parse_selection<'a, 'b, S>( +fn parse_selection<'a, S>( parser: &mut Parser<'a>, - schema: &'b SchemaType<'b, S>, - fields: Option<&[&MetaField<'b, S>]>, + schema: &SchemaType, + fields: Option<&[&MetaField]>, ) -> UnlocatedParseResult> where S: ScalarValue, @@ -211,10 +209,10 @@ where } } -fn parse_fragment<'a, 'b, S>( +fn parse_fragment<'a, S>( parser: &mut Parser<'a>, - schema: &'b SchemaType<'b, S>, - fields: Option<&[&MetaField<'b, S>]>, + schema: &SchemaType, + fields: Option<&[&MetaField]>, ) -> UnlocatedParseResult> where S: ScalarValue, @@ -290,10 +288,10 @@ where } } -fn parse_field<'a, 'b, S>( +fn parse_field<'a, S>( parser: &mut Parser<'a>, - schema: &'b SchemaType<'b, S>, - fields: Option<&[&MetaField<'b, S>]>, + schema: &SchemaType, + fields: Option<&[&MetaField]>, ) -> ParseResult> where S: ScalarValue, @@ -341,10 +339,10 @@ where )) } -fn parse_arguments<'a, 'b, S>( +fn parse_arguments<'a, S>( parser: &mut Parser<'a>, - schema: &'b SchemaType<'b, S>, - arguments: Option<&[Argument<'b, S>]>, + schema: &SchemaType, + arguments: Option<&[Argument]>, ) -> OptionParseResult> where S: ScalarValue, @@ -366,10 +364,10 @@ where } } -fn parse_argument<'a, 'b, S>( +fn parse_argument<'a, S>( parser: &mut Parser<'a>, - schema: &'b SchemaType<'b, S>, - arguments: Option<&[Argument<'b, S>]>, + schema: &SchemaType, + arguments: Option<&[Argument]>, ) -> ParseResult<(Spanning<&'a str>, Spanning>)> where S: ScalarValue, @@ -400,9 +398,9 @@ fn parse_operation_type(parser: &mut Parser<'_>) -> ParseResult { } } -fn parse_variable_definitions<'a, 'b, S>( +fn parse_variable_definitions<'a, S>( parser: &mut Parser<'a>, - schema: &'b SchemaType<'b, S>, + schema: &SchemaType, ) -> OptionParseResult> where S: ScalarValue, @@ -424,9 +422,9 @@ where } } -fn parse_variable_definition<'a, 'b, S>( +fn parse_variable_definition<'a, S>( parser: &mut Parser<'a>, - schema: &'b SchemaType<'b, S>, + schema: &SchemaType, ) -> ParseResult<(Spanning<&'a str>, VariableDefinition<'a, S>)> where S: ScalarValue, @@ -462,9 +460,9 @@ where )) } -fn parse_directives<'a, 'b, S>( +fn parse_directives<'a, S>( parser: &mut Parser<'a>, - schema: &'b SchemaType<'b, S>, + schema: &SchemaType, ) -> OptionParseResult>>> where S: ScalarValue, @@ -481,9 +479,9 @@ where } } -fn parse_directive<'a, 'b, S>( +fn parse_directive<'a, S>( parser: &mut Parser<'a>, - schema: &'b SchemaType<'b, S>, + schema: &SchemaType, ) -> ParseResult> where S: ScalarValue, @@ -509,7 +507,7 @@ where )) } -pub fn parse_type<'a>(parser: &mut Parser<'a>) -> ParseResult> { +pub fn parse_type<'a>(parser: &mut Parser<'a>) -> ParseResult> { let parsed_type = if let Some(Spanning { span: ref start_span, .. @@ -523,7 +521,7 @@ pub fn parse_type<'a>(parser: &mut Parser<'a>) -> ParseResult> { Type::List(Box::new(inner_type.item), None), ) } else { - parser.expect_name()?.map(|s| Type::Named(Cow::Borrowed(s))) + parser.expect_name()?.map(Type::Named) }; Ok(match *parser.peek() { @@ -535,7 +533,10 @@ pub fn parse_type<'a>(parser: &mut Parser<'a>) -> ParseResult> { }) } -fn wrap_non_null<'a>(parser: &mut Parser<'a>, inner: Spanning>) -> ParseResult> { +fn wrap_non_null<'a>( + parser: &mut Parser<'a>, + inner: Spanning>, +) -> ParseResult> { let end_pos = &parser.expect(&Token::ExclamationMark)?.span.end; let wrapped = match inner.item { diff --git a/juniper/src/parser/parser.rs b/juniper/src/parser/parser.rs index 41922b850..8485c4192 100644 --- a/juniper/src/parser/parser.rs +++ b/juniper/src/parser/parser.rs @@ -1,7 +1,5 @@ use std::{error::Error, fmt, result::Result}; -use smartstring::alias::String; - use crate::parser::{Lexer, LexerError, Spanning, Token}; /// Error while parsing a GraphQL query diff --git a/juniper/src/parser/tests/value.rs b/juniper/src/parser/tests/value.rs index cda48e0d7..fe0df670a 100644 --- a/juniper/src/parser/tests/value.rs +++ b/juniper/src/parser/tests/value.rs @@ -1,6 +1,6 @@ use crate::{ ast::{FromInputValue, InputValue, Type}, - graphql_input_value, + graphql_input_value, literal, parser::{value::parse_value_literal, Lexer, Parser, SourcePosition, Spanning}, schema::{ meta::{Argument, EnumMeta, EnumValue, InputObjectMeta, MetaType, ScalarMeta}, @@ -115,7 +115,7 @@ fn input_value_literals() { graphql_input_value!("test"), ), ); - let values = &[EnumValue::new("enum_value")]; + let values = &[EnumValue::new(literal!("enum_value"))]; let e: EnumMeta = EnumMeta::new::("TestEnum".into(), values); assert_eq!( @@ -173,8 +173,8 @@ fn input_value_literals() { ), ); let fields = [ - Argument::new("key", Type::NonNullNamed("Int".into())), - Argument::new("other", Type::NonNullNamed("Bar".into())), + Argument::new(literal!("key"), Type::NonNullNamed("Int".into())), + Argument::new(literal!("other"), Type::NonNullNamed("Bar".into())), ]; let meta = &MetaType::InputObject(InputObjectMeta::new::("foo".into(), &fields)); assert_eq!( diff --git a/juniper/src/parser/value.rs b/juniper/src/parser/value.rs index 53a8103fe..3090f0984 100644 --- a/juniper/src/parser/value.rs +++ b/juniper/src/parser/value.rs @@ -11,11 +11,11 @@ use crate::{ use super::utils::Span; -pub fn parse_value_literal<'b, S>( +pub fn parse_value_literal( parser: &mut Parser<'_>, is_const: bool, - schema: &'b SchemaType<'b, S>, - tpe: Option<&MetaType<'b, S>>, + schema: &SchemaType, + tpe: Option<&MetaType>, ) -> ParseResult> where S: ScalarValue, @@ -117,11 +117,11 @@ where } } -fn parse_list_literal<'b, S>( +fn parse_list_literal( parser: &mut Parser<'_>, is_const: bool, - schema: &'b SchemaType<'b, S>, - tpe: Option<&MetaType<'b, S>>, + schema: &SchemaType, + tpe: Option<&MetaType>, ) -> ParseResult> where S: ScalarValue, @@ -135,11 +135,11 @@ where .map(InputValue::parsed_list)) } -fn parse_object_literal<'b, S>( +fn parse_object_literal( parser: &mut Parser<'_>, is_const: bool, - schema: &'b SchemaType<'b, S>, - object_tpe: Option<&InputObjectMeta<'b, S>>, + schema: &SchemaType, + object_tpe: Option<&InputObjectMeta>, ) -> ParseResult> where S: ScalarValue, @@ -153,11 +153,11 @@ where .map(|items| InputValue::parsed_object(items.into_iter().map(|s| s.item).collect()))) } -fn parse_object_field<'b, S>( +fn parse_object_field( parser: &mut Parser<'_>, is_const: bool, - schema: &'b SchemaType<'b, S>, - object_meta: Option<&InputObjectMeta<'b, S>>, + schema: &SchemaType, + object_meta: Option<&InputObjectMeta>, ) -> ParseResult<(Spanning, Spanning>)> where S: ScalarValue, @@ -197,10 +197,10 @@ where )) } -fn parse_scalar_literal_by_infered_type<'b, S>( +fn parse_scalar_literal_by_infered_type( token: ScalarToken<'_>, span: Span, - schema: &'b SchemaType<'b, S>, + schema: &SchemaType, ) -> ParseResult> where S: ScalarValue, diff --git a/juniper/src/schema/meta.rs b/juniper/src/schema/meta.rs index 04f5eda96..f67f7b8c5 100644 --- a/juniper/src/schema/meta.rs +++ b/juniper/src/schema/meta.rs @@ -1,10 +1,8 @@ //! Types used to describe a `GraphQL` schema +use arcstr::ArcStr; use juniper::IntoFieldError; -use std::{ - borrow::{Cow, ToOwned}, - fmt, -}; +use std::{borrow::ToOwned, fmt}; use crate::{ ast::{FromInputValue, InputValue, Type}, @@ -21,7 +19,7 @@ pub enum DeprecationStatus { /// The field/variant is not deprecated. Current, /// The field/variant is deprecated, with an optional reason - Deprecated(Option), + Deprecated(Option), } impl DeprecationStatus { @@ -43,13 +41,13 @@ impl DeprecationStatus { } /// Scalar type metadata -pub struct ScalarMeta<'a, S> { +pub struct ScalarMeta { #[doc(hidden)] - pub name: Cow<'a, str>, + pub name: ArcStr, #[doc(hidden)] - pub description: Option, + pub description: Option, #[doc(hidden)] - pub specified_by_url: Option>, + pub specified_by_url: Option, pub(crate) try_parse_fn: InputValueParseFn, pub(crate) parse_fn: ScalarTokenParseFn, } @@ -62,9 +60,9 @@ pub type ScalarTokenParseFn = for<'b> fn(ScalarToken<'b>) -> Result { +pub struct ListMeta { #[doc(hidden)] - pub of_type: Type<'a>, + pub of_type: Type, #[doc(hidden)] pub expected_size: Option, @@ -72,30 +70,30 @@ pub struct ListMeta<'a> { /// Nullable type metadata #[derive(Debug)] -pub struct NullableMeta<'a> { +pub struct NullableMeta { #[doc(hidden)] - pub of_type: Type<'a>, + pub of_type: Type, } /// Object type metadata #[derive(Debug)] -pub struct ObjectMeta<'a, S> { +pub struct ObjectMeta { #[doc(hidden)] - pub name: Cow<'a, str>, + pub name: ArcStr, #[doc(hidden)] - pub description: Option, + pub description: Option, #[doc(hidden)] - pub fields: Vec>, + pub fields: Vec>, #[doc(hidden)] - pub interface_names: Vec, + pub interface_names: Vec, } /// Enum type metadata -pub struct EnumMeta<'a, S> { +pub struct EnumMeta { #[doc(hidden)] - pub name: Cow<'a, str>, + pub name: ArcStr, #[doc(hidden)] - pub description: Option, + pub description: Option, #[doc(hidden)] pub values: Vec, pub(crate) try_parse_fn: InputValueParseFn, @@ -103,36 +101,36 @@ pub struct EnumMeta<'a, S> { /// Interface type metadata #[derive(Debug)] -pub struct InterfaceMeta<'a, S> { +pub struct InterfaceMeta { #[doc(hidden)] - pub name: Cow<'a, str>, + pub name: ArcStr, #[doc(hidden)] - pub description: Option, + pub description: Option, #[doc(hidden)] - pub fields: Vec>, + pub fields: Vec>, #[doc(hidden)] - pub interface_names: Vec, + pub interface_names: Vec, } /// Union type metadata #[derive(Debug)] -pub struct UnionMeta<'a> { +pub struct UnionMeta { #[doc(hidden)] - pub name: Cow<'a, str>, + pub name: ArcStr, #[doc(hidden)] - pub description: Option, + pub description: Option, #[doc(hidden)] - pub of_type_names: Vec, + pub of_type_names: Vec, } /// Input object metadata -pub struct InputObjectMeta<'a, S> { +pub struct InputObjectMeta { #[doc(hidden)] - pub name: Cow<'a, str>, + pub name: ArcStr, #[doc(hidden)] - pub description: Option, + pub description: Option, #[doc(hidden)] - pub input_fields: Vec>, + pub input_fields: Vec>, pub(crate) try_parse_fn: InputValueParseFn, } @@ -141,50 +139,50 @@ pub struct InputObjectMeta<'a, S> { /// After a type's `meta` method has been called but before it has returned, a placeholder type /// is inserted into a registry to indicate existence. #[derive(Debug)] -pub struct PlaceholderMeta<'a> { +pub struct PlaceholderMeta { #[doc(hidden)] - pub of_type: Type<'a>, + pub of_type: Type, } /// Generic type metadata #[derive(Debug)] -pub enum MetaType<'a, S = DefaultScalarValue> { +pub enum MetaType { #[doc(hidden)] - Scalar(ScalarMeta<'a, S>), + Scalar(ScalarMeta), #[doc(hidden)] - List(ListMeta<'a>), + List(ListMeta), #[doc(hidden)] - Nullable(NullableMeta<'a>), + Nullable(NullableMeta), #[doc(hidden)] - Object(ObjectMeta<'a, S>), + Object(ObjectMeta), #[doc(hidden)] - Enum(EnumMeta<'a, S>), + Enum(EnumMeta), #[doc(hidden)] - Interface(InterfaceMeta<'a, S>), + Interface(InterfaceMeta), #[doc(hidden)] - Union(UnionMeta<'a>), + Union(UnionMeta), #[doc(hidden)] - InputObject(InputObjectMeta<'a, S>), + InputObject(InputObjectMeta), #[doc(hidden)] - Placeholder(PlaceholderMeta<'a>), + Placeholder(PlaceholderMeta), } /// Metadata for a field #[derive(Debug, Clone)] -pub struct Field<'a, S> { +pub struct Field { #[doc(hidden)] - pub name: smartstring::alias::String, + pub name: ArcStr, #[doc(hidden)] - pub description: Option, + pub description: Option, #[doc(hidden)] - pub arguments: Option>>, + pub arguments: Option>>, #[doc(hidden)] - pub field_type: Type<'a>, + pub field_type: Type, #[doc(hidden)] pub deprecation_status: DeprecationStatus, } -impl<'a, S> Field<'a, S> { +impl Field { /// Returns true if the type is built-in to GraphQL. pub fn is_builtin(&self) -> bool { // "used exclusively by GraphQL’s introspection system" @@ -194,18 +192,18 @@ impl<'a, S> Field<'a, S> { /// Metadata for an argument to a field #[derive(Debug, Clone)] -pub struct Argument<'a, S> { +pub struct Argument { #[doc(hidden)] - pub name: String, + pub name: ArcStr, #[doc(hidden)] - pub description: Option, + pub description: Option, #[doc(hidden)] - pub arg_type: Type<'a>, + pub arg_type: Type, #[doc(hidden)] pub default_value: Option>, } -impl<'a, S> Argument<'a, S> { +impl Argument { /// Returns true if the type is built-in to GraphQL. pub fn is_builtin(&self) -> bool { // "used exclusively by GraphQL’s introspection system" @@ -219,17 +217,17 @@ pub struct EnumValue { /// The name of the enum value /// /// This is the string literal representation of the enum in responses. - pub name: String, + pub name: ArcStr, /// The optional description of the enum value. /// /// Note: this is not the description of the enum itself; it's the /// description of this enum _value_. - pub description: Option, + pub description: Option, /// Whether the field is deprecated or not, with an optional reason. pub deprecation_status: DeprecationStatus, } -impl<'a, S> MetaType<'a, S> { +impl MetaType { /// Access the name of the type, if applicable /// /// Lists, non-null wrappers, and placeholders don't have names. @@ -248,14 +246,14 @@ impl<'a, S> MetaType<'a, S> { /// Access the description of the type, if applicable /// /// Lists, nullable wrappers, and placeholders don't have names. - pub fn description(&self) -> Option<&str> { + pub fn description(&self) -> Option<&ArcStr> { match self { MetaType::Scalar(ScalarMeta { description, .. }) | MetaType::Object(ObjectMeta { description, .. }) | MetaType::Enum(EnumMeta { description, .. }) | MetaType::Interface(InterfaceMeta { description, .. }) | MetaType::Union(UnionMeta { description, .. }) - | MetaType::InputObject(InputObjectMeta { description, .. }) => description.as_deref(), + | MetaType::InputObject(InputObjectMeta { description, .. }) => description.as_ref(), _ => None, } } @@ -265,11 +263,11 @@ impl<'a, S> MetaType<'a, S> { /// Only custom GraphQL scalars can have a [specification URL][0]. /// /// [0]: https://spec.graphql.org/October2021#sec--specifiedBy - pub fn specified_by_url(&self) -> Option<&str> { + pub fn specified_by_url(&self) -> Option<&ArcStr> { match self { Self::Scalar(ScalarMeta { specified_by_url, .. - }) => specified_by_url.as_deref(), + }) => specified_by_url.as_ref(), _ => None, } } @@ -319,7 +317,7 @@ impl<'a, S> MetaType<'a, S> { } /// Construct a `Type` literal instance based on the metadata - pub fn as_type(&self) -> Type<'a> { + pub fn as_type(&self) -> Type { match *self { MetaType::Scalar(ScalarMeta { ref name, .. }) | MetaType::Object(ObjectMeta { ref name, .. }) @@ -415,7 +413,7 @@ impl<'a, S> MetaType<'a, S> { } } - pub(crate) fn fields<'b>(&self, schema: &'b SchemaType) -> Option>> { + pub(crate) fn fields<'b>(&self, schema: &'b SchemaType) -> Option>> { schema .lookup_type(&self.as_type()) .and_then(|tpe| match *tpe { @@ -434,9 +432,9 @@ impl<'a, S> MetaType<'a, S> { } } -impl<'a, S> ScalarMeta<'a, S> { +impl ScalarMeta { /// Builds a new [`ScalarMeta`] type with the specified `name`. - pub fn new(name: Cow<'a, str>) -> Self + pub fn new(name: ArcStr) -> Self where T: FromInputValue + ParseScalarValue, T::Error: IntoFieldError, @@ -454,8 +452,8 @@ impl<'a, S> ScalarMeta<'a, S> { /// /// Overwrites any previously set description. #[must_use] - pub fn description(mut self, description: &str) -> Self { - self.description = Some(description.into()); + pub fn description(mut self, description: ArcStr) -> Self { + self.description = Some(description); self } @@ -465,23 +463,23 @@ impl<'a, S> ScalarMeta<'a, S> { /// /// [0]: https://spec.graphql.org/October2021#sec--specifiedBy #[must_use] - pub fn specified_by_url(mut self, url: impl Into>) -> Self { - self.specified_by_url = Some(url.into()); + pub fn specified_by_url(mut self, url: ArcStr) -> Self { + self.specified_by_url = Some(url); self } /// Wraps this [`ScalarMeta`] type into a generic [`MetaType`]. - pub fn into_meta(self) -> MetaType<'a, S> { + pub fn into_meta(self) -> MetaType { MetaType::Scalar(self) } } -impl<'a> ListMeta<'a> { +impl ListMeta { /// Build a new [`ListMeta`] type by wrapping the specified [`Type`]. /// /// Specifying `expected_size` will be used to ensure that values of this /// type will always match it. - pub fn new(of_type: Type<'a>, expected_size: Option) -> Self { + pub fn new(of_type: Type, expected_size: Option) -> Self { Self { of_type, expected_size, @@ -489,26 +487,26 @@ impl<'a> ListMeta<'a> { } /// Wraps this [`ListMeta`] type into a generic [`MetaType`]. - pub fn into_meta(self) -> MetaType<'a, S> { + pub fn into_meta(self) -> MetaType { MetaType::List(self) } } -impl<'a> NullableMeta<'a> { +impl NullableMeta { /// Build a new [`NullableMeta`] type by wrapping the specified [`Type`]. - pub fn new(of_type: Type<'a>) -> Self { + pub fn new(of_type: Type) -> Self { Self { of_type } } /// Wraps this [`NullableMeta`] type into a generic [`MetaType`]. - pub fn into_meta(self) -> MetaType<'a, S> { + pub fn into_meta(self) -> MetaType { MetaType::Nullable(self) } } -impl<'a, S> ObjectMeta<'a, S> { +impl ObjectMeta { /// Build a new [`ObjectMeta`] type with the specified `name` and `fields`. - pub fn new(name: Cow<'a, str>, fields: &[Field<'a, S>]) -> Self + pub fn new(name: ArcStr, fields: &[Field]) -> Self where S: Clone, { @@ -524,8 +522,8 @@ impl<'a, S> ObjectMeta<'a, S> { /// /// Overwrites any previously set description. #[must_use] - pub fn description(mut self, description: &str) -> Self { - self.description = Some(description.into()); + pub fn description(mut self, description: ArcStr) -> Self { + self.description = Some(description); self } @@ -533,7 +531,7 @@ impl<'a, S> ObjectMeta<'a, S> { /// /// Overwrites any previously set list of interfaces. #[must_use] - pub fn interfaces(mut self, interfaces: &[Type<'a>]) -> Self { + pub fn interfaces(mut self, interfaces: &[Type]) -> Self { self.interface_names = interfaces .iter() .map(|t| t.innermost_name().into()) @@ -542,15 +540,15 @@ impl<'a, S> ObjectMeta<'a, S> { } /// Wraps this [`ObjectMeta`] type into a generic [`MetaType`]. - pub fn into_meta(self) -> MetaType<'a, S> { + pub fn into_meta(self) -> MetaType { MetaType::Object(self) } } -impl<'a, S> EnumMeta<'a, S> { +impl EnumMeta { /// Build a new [`EnumMeta`] type with the specified `name` and possible /// `values`. - pub fn new(name: Cow<'a, str>, values: &[EnumValue]) -> Self + pub fn new(name: ArcStr, values: &[EnumValue]) -> Self where T: FromInputValue, T::Error: IntoFieldError, @@ -567,21 +565,21 @@ impl<'a, S> EnumMeta<'a, S> { /// /// Overwrites any previously set description. #[must_use] - pub fn description(mut self, description: &str) -> Self { - self.description = Some(description.into()); + pub fn description(mut self, description: ArcStr) -> Self { + self.description = Some(description); self } /// Wraps this [`EnumMeta`] type into a generic [`MetaType`]. - pub fn into_meta(self) -> MetaType<'a, S> { + pub fn into_meta(self) -> MetaType { MetaType::Enum(self) } } -impl<'a, S> InterfaceMeta<'a, S> { +impl InterfaceMeta { /// Builds a new [`InterfaceMeta`] type with the specified `name` and /// `fields`. - pub fn new(name: Cow<'a, str>, fields: &[Field<'a, S>]) -> Self + pub fn new(name: ArcStr, fields: &[Field]) -> Self where S: Clone, { @@ -597,8 +595,8 @@ impl<'a, S> InterfaceMeta<'a, S> { /// /// Overwrites any previously set description. #[must_use] - pub fn description(mut self, description: &str) -> Self { - self.description = Some(description.into()); + pub fn description(mut self, description: ArcStr) -> Self { + self.description = Some(description); self } @@ -606,7 +604,7 @@ impl<'a, S> InterfaceMeta<'a, S> { /// /// Overwrites any previously set list of interfaces. #[must_use] - pub fn interfaces(mut self, interfaces: &[Type<'a>]) -> Self { + pub fn interfaces(mut self, interfaces: &[Type]) -> Self { self.interface_names = interfaces .iter() .map(|t| t.innermost_name().into()) @@ -615,15 +613,15 @@ impl<'a, S> InterfaceMeta<'a, S> { } /// Wraps this [`InterfaceMeta`] type into a generic [`MetaType`]. - pub fn into_meta(self) -> MetaType<'a, S> { + pub fn into_meta(self) -> MetaType { MetaType::Interface(self) } } -impl<'a> UnionMeta<'a> { +impl UnionMeta { /// Build a new [`UnionMeta`] type with the specified `name` and possible /// [`Type`]s. - pub fn new(name: Cow<'a, str>, of_types: &[Type]) -> Self { + pub fn new(name: ArcStr, of_types: &[Type]) -> Self { Self { name, description: None, @@ -635,21 +633,21 @@ impl<'a> UnionMeta<'a> { /// /// Overwrites any previously set description. #[must_use] - pub fn description(mut self, description: &str) -> Self { - self.description = Some(description.into()); + pub fn description(mut self, description: ArcStr) -> Self { + self.description = Some(description); self } /// Wraps this [`UnionMeta`] type into a generic [`MetaType`]. - pub fn into_meta(self) -> MetaType<'a, S> { + pub fn into_meta(self) -> MetaType { MetaType::Union(self) } } -impl<'a, S> InputObjectMeta<'a, S> { +impl InputObjectMeta { /// Builds a new [`InputObjectMeta`] type with the specified `name` and /// `input_fields`. - pub fn new(name: Cow<'a, str>, input_fields: &[Argument<'a, S>]) -> Self + pub fn new(name: ArcStr, input_fields: &[Argument]) -> Self where T: FromInputValue, T::Error: IntoFieldError, @@ -667,24 +665,24 @@ impl<'a, S> InputObjectMeta<'a, S> { /// /// Overwrites any previously set description. #[must_use] - pub fn description(mut self, description: &str) -> Self { - self.description = Some(description.into()); + pub fn description(mut self, description: ArcStr) -> Self { + self.description = Some(description); self } /// Wraps this [`InputObjectMeta`] type into a generic [`MetaType`]. - pub fn into_meta(self) -> MetaType<'a, S> { + pub fn into_meta(self) -> MetaType { MetaType::InputObject(self) } } -impl<'a, S> Field<'a, S> { +impl Field { /// Set the `description` of this [`Field`]. /// /// Overwrites any previously set description. #[must_use] - pub fn description(mut self, description: &str) -> Self { - self.description = Some(description.into()); + pub fn description(mut self, description: ArcStr) -> Self { + self.description = Some(description); self } @@ -692,7 +690,7 @@ impl<'a, S> Field<'a, S> { /// /// Arguments are unordered and can't contain duplicates by name. #[must_use] - pub fn argument(mut self, argument: Argument<'a, S>) -> Self { + pub fn argument(mut self, argument: Argument) -> Self { match self.arguments { None => { self.arguments = Some(vec![argument]); @@ -708,17 +706,17 @@ impl<'a, S> Field<'a, S> { /// /// Overwrites any previously set deprecation reason. #[must_use] - pub fn deprecated(mut self, reason: Option<&str>) -> Self { + pub fn deprecated(mut self, reason: Option) -> Self { self.deprecation_status = DeprecationStatus::Deprecated(reason.map(Into::into)); self } } -impl<'a, S> Argument<'a, S> { +impl Argument { /// Builds a new [`Argument`] of the given [`Type`] with the given `name`. - pub fn new(name: &str, arg_type: Type<'a>) -> Self { + pub fn new(name: ArcStr, arg_type: Type) -> Self { Self { - name: name.into(), + name, description: None, arg_type, default_value: None, @@ -729,8 +727,8 @@ impl<'a, S> Argument<'a, S> { /// /// Overwrites any previously set description. #[must_use] - pub fn description(mut self, description: &str) -> Self { - self.description = Some(description.into()); + pub fn description(mut self, description: ArcStr) -> Self { + self.description = Some(description); self } @@ -746,9 +744,9 @@ impl<'a, S> Argument<'a, S> { impl EnumValue { /// Constructs a new [`EnumValue`] with the provided `name`. - pub fn new(name: &str) -> Self { + pub fn new(name: ArcStr) -> Self { Self { - name: name.into(), + name, description: None, deprecation_status: DeprecationStatus::Current, } @@ -758,8 +756,8 @@ impl EnumValue { /// /// Overwrites any previously set description. #[must_use] - pub fn description(mut self, description: &str) -> Self { - self.description = Some(description.into()); + pub fn description(mut self, description: ArcStr) -> Self { + self.description = Some(description); self } @@ -767,13 +765,13 @@ impl EnumValue { /// /// Overwrites any previously set deprecation reason. #[must_use] - pub fn deprecated(mut self, reason: Option<&str>) -> Self { - self.deprecation_status = DeprecationStatus::Deprecated(reason.map(Into::into)); + pub fn deprecated(mut self, reason: Option) -> Self { + self.deprecation_status = DeprecationStatus::Deprecated(reason); self } } -impl<'a, S: fmt::Debug> fmt::Debug for ScalarMeta<'a, S> { +impl fmt::Debug for ScalarMeta { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("ScalarMeta") .field("name", &self.name) @@ -782,7 +780,7 @@ impl<'a, S: fmt::Debug> fmt::Debug for ScalarMeta<'a, S> { } } -impl<'a, S: fmt::Debug> fmt::Debug for EnumMeta<'a, S> { +impl fmt::Debug for EnumMeta { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("EnumMeta") .field("name", &self.name) @@ -792,7 +790,7 @@ impl<'a, S: fmt::Debug> fmt::Debug for EnumMeta<'a, S> { } } -impl<'a, S: fmt::Debug> fmt::Debug for InputObjectMeta<'a, S> { +impl fmt::Debug for InputObjectMeta { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("InputObjectMeta") .field("name", &self.name) diff --git a/juniper/src/schema/model.rs b/juniper/src/schema/model.rs index 61b119678..37b14fb60 100644 --- a/juniper/src/schema/model.rs +++ b/juniper/src/schema/model.rs @@ -1,5 +1,6 @@ -use std::{borrow::Cow, fmt}; +use std::fmt; +use arcstr::ArcStr; use fnv::FnvHashMap; #[cfg(feature = "schema-language")] use graphql_parser::schema::Document; @@ -7,6 +8,7 @@ use graphql_parser::schema::Document; use crate::{ ast::Type, executor::{Context, Registry}, + literal, schema::meta::{Argument, InterfaceMeta, MetaType, ObjectMeta, PlaceholderMeta, UnionMeta}, types::{base::GraphQLType, name::Name}, value::{DefaultScalarValue, ScalarValue}, @@ -19,7 +21,6 @@ use crate::{ /// and provides the predefined metadata fields. #[derive(Debug)] pub struct RootNode< - 'a, QueryT: GraphQLType, MutationT: GraphQLType, SubscriptionT: GraphQLType, @@ -40,37 +41,37 @@ pub struct RootNode< #[doc(hidden)] pub subscription_info: SubscriptionT::TypeInfo, #[doc(hidden)] - pub schema: SchemaType<'a, S>, + pub schema: SchemaType, #[doc(hidden)] pub introspection_disabled: bool, } /// Metadata for a schema #[derive(Debug)] -pub struct SchemaType<'a, S> { - pub(crate) description: Option>, - pub(crate) types: FnvHashMap>, +pub struct SchemaType { + pub(crate) description: Option, + pub(crate) types: FnvHashMap>, pub(crate) query_type_name: String, pub(crate) mutation_type_name: Option, pub(crate) subscription_type_name: Option, - directives: FnvHashMap>, + directives: FnvHashMap>, } -impl<'a, S> Context for SchemaType<'a, S> {} +impl Context for SchemaType {} #[derive(Clone)] pub enum TypeType<'a, S: 'a> { - Concrete(&'a MetaType<'a, S>), + Concrete(&'a MetaType), NonNull(Box>), List(Box>, Option), } #[derive(Debug)] -pub struct DirectiveType<'a, S> { +pub struct DirectiveType { pub name: String, pub description: Option, pub locations: Vec, - pub arguments: Vec>, + pub arguments: Vec>, pub is_repeatable: bool, } @@ -96,8 +97,53 @@ pub enum DirectiveLocation { EnumValue, } -impl<'a, QueryT, MutationT, SubscriptionT> - RootNode<'a, QueryT, MutationT, SubscriptionT, DefaultScalarValue> +/// Allows seeing [Type] with different name/string representations +/// as the same type without allocating. +/// +/// TODO: Ideally this type should not exist, but the reason it currently does +/// is that [Type] is fully recursive, but recursive type references cannot really exist in GraphQL. +/// (only one level of list-wrapping is allowed). +/// If [Type] got properly "flattened" it would be easy to cheaply project a [Type] as a [Type<&str>]. +#[derive(Clone, Copy, Debug)] +pub enum DynType<'a> { + Named(&'a str), + List(&'a dyn AsDynType, Option), + NonNullNamed(&'a str), + NonNullList(&'a dyn AsDynType, Option), +} + +/// Trait for converting a [Type] into [DynType] +pub trait AsDynType: fmt::Debug { + /// Project [self] as a [DynType]. + /// + /// this function should not allocate memory. + fn as_dyn_type(&self) -> DynType<'_>; +} + +impl AsDynType for Type { + fn as_dyn_type(&self) -> DynType<'_> { + match self { + Self::Named(n) => DynType::Named(n.as_str()), + Self::List(t, s) => DynType::List(t.as_ref(), *s), + Self::NonNullNamed(n) => DynType::NonNullNamed(n.as_str()), + Self::NonNullList(t, s) => DynType::NonNullList(t.as_ref(), *s), + } + } +} + +impl<'a> AsDynType for Type<&'a str> { + fn as_dyn_type(&self) -> DynType<'_> { + match self { + Self::Named(n) => DynType::Named(n), + Self::List(t, s) => DynType::List(t.as_ref(), *s), + Self::NonNullNamed(n) => DynType::NonNullNamed(n), + Self::NonNullList(t, s) => DynType::NonNullList(t.as_ref(), *s), + } + } +} + +impl + RootNode where QueryT: GraphQLType, MutationT: GraphQLType, @@ -110,9 +156,9 @@ where } } -impl<'a, QueryT, MutationT, SubscriptionT, S> RootNode<'a, QueryT, MutationT, SubscriptionT, S> +impl RootNode where - S: ScalarValue + 'a, + S: ScalarValue, QueryT: GraphQLType, MutationT: GraphQLType, SubscriptionT: GraphQLType, @@ -128,12 +174,12 @@ where } } -impl<'a, S, QueryT, MutationT, SubscriptionT> RootNode<'a, QueryT, MutationT, SubscriptionT, S> +impl RootNode where QueryT: GraphQLType, MutationT: GraphQLType, SubscriptionT: GraphQLType, - S: ScalarValue + 'a, + S: ScalarValue, { /// Construct a new root node from query and mutation nodes, /// while also providing type info objects for the query and @@ -184,7 +230,7 @@ where /// } /// } /// - /// type Schema = RootNode<'static, Query, EmptyMutation<()>, EmptySubscription<()>>; + /// type Schema = RootNode, EmptySubscription<()>>; /// /// let schema = Schema::new(Query, EmptyMutation::new(), EmptySubscription::new()) /// .disable_introspection(); @@ -247,7 +293,7 @@ where /// The order of the generated definitions in the returned [`Document`] is NOT stable and may change without any /// real schema changes. #[must_use] - pub fn as_document(&'a self) -> Document<'a, &'a str> { + pub fn as_document(&self) -> Document<&str> { use crate::schema::translate::{ graphql_parser::GraphQLParserTranslator, SchemaTranslator as _, }; @@ -256,7 +302,7 @@ where } } -impl<'a, S> SchemaType<'a, S> { +impl SchemaType { /// Create a new schema. pub fn new( query_info: &QueryT::TypeInfo, @@ -264,7 +310,7 @@ impl<'a, S> SchemaType<'a, S> { subscription_info: &SubscriptionT::TypeInfo, ) -> Self where - S: ScalarValue + 'a, + S: ScalarValue, QueryT: GraphQLType, MutationT: GraphQLType, SubscriptionT: GraphQLType, @@ -272,18 +318,18 @@ impl<'a, S> SchemaType<'a, S> { let mut directives = FnvHashMap::default(); let mut registry = Registry::new(FnvHashMap::default()); - let query_type_name = registry + let query_type_name: Box = registry .get_type::(query_info) .innermost_name() - .to_owned(); - let mutation_type_name = registry + .into(); + let mutation_type_name: Box = registry .get_type::(mutation_info) .innermost_name() - .to_owned(); - let subscription_type_name = registry + .into(); + let subscription_type_name: Box = registry .get_type::(subscription_info) .innermost_name() - .to_owned(); + .into(); registry.get_type::>(&()); @@ -299,13 +345,13 @@ impl<'a, S> SchemaType<'a, S> { ); let mut meta_fields = vec![ - registry.field::>("__schema", &()), + registry.field::>(literal!("__schema"), &()), registry - .field::>("__type", &()) - .argument(registry.arg::("name", &())), + .field::>(literal!("__type"), &()) + .argument(registry.arg::(literal!("name"), &())), ]; - if let Some(root_type) = registry.types.get_mut(&query_type_name) { + if let Some(root_type) = registry.types.get_mut(query_type_name.as_ref()) { if let MetaType::Object(ObjectMeta { ref mut fields, .. }) = *root_type { fields.append(&mut meta_fields); } else { @@ -323,14 +369,14 @@ impl<'a, S> SchemaType<'a, S> { SchemaType { description: None, types: registry.types, - query_type_name, - mutation_type_name: if &mutation_type_name != "_EmptyMutation" { - Some(mutation_type_name) + query_type_name: query_type_name.into(), + mutation_type_name: if mutation_type_name.as_ref() != "_EmptyMutation" { + Some(mutation_type_name.into()) } else { None }, - subscription_type_name: if &subscription_type_name != "_EmptySubscription" { - Some(subscription_type_name) + subscription_type_name: if subscription_type_name.as_ref() != "_EmptySubscription" { + Some(subscription_type_name.into()) } else { None }, @@ -339,12 +385,12 @@ impl<'a, S> SchemaType<'a, S> { } /// Add a description. - pub fn set_description(&mut self, description: impl Into>) { - self.description = Some(description.into()); + pub fn set_description(&mut self, description: ArcStr) { + self.description = Some(description); } /// Add a directive like `skip` or `include`. - pub fn add_directive(&mut self, directive: DirectiveType<'a, S>) { + pub fn add_directive(&mut self, directive: DirectiveType) { self.directives.insert(directive.name.clone(), directive); } @@ -358,10 +404,10 @@ impl<'a, S> SchemaType<'a, S> { self.types.get(name) } - pub(crate) fn lookup_type(&self, tpe: &Type) -> Option<&MetaType> { + pub(crate) fn lookup_type>(&self, tpe: &Type) -> Option<&MetaType> { match *tpe { Type::NonNullNamed(ref name) | Type::Named(ref name) => { - self.concrete_type_by_name(name) + self.concrete_type_by_name(name.as_ref()) } Type::List(ref inner, _) | Type::NonNullList(ref inner, _) => self.lookup_type(inner), } @@ -371,7 +417,7 @@ impl<'a, S> SchemaType<'a, S> { pub fn query_type(&self) -> TypeType { TypeType::Concrete( self.types - .get(&self.query_type_name) + .get(self.query_type_name.as_str()) .expect("Query type does not exist in schema"), ) } @@ -379,7 +425,7 @@ impl<'a, S> SchemaType<'a, S> { /// Get the concrete query type from the schema. pub fn concrete_query_type(&self) -> &MetaType { self.types - .get(&self.query_type_name) + .get(self.query_type_name.as_str()) .expect("Query type does not exist in schema") } @@ -432,17 +478,20 @@ impl<'a, S> SchemaType<'a, S> { } /// Make a type. - pub fn make_type(&self, t: &Type) -> TypeType { - match *t { - Type::NonNullNamed(ref n) => TypeType::NonNull(Box::new( - self.type_by_name(n).expect("Type not found in schema"), + pub fn make_type(&self, t: DynType) -> TypeType { + match t { + DynType::NonNullNamed(n) => TypeType::NonNull(Box::new( + self.type_by_name(n.as_ref()) + .expect("Type not found in schema"), )), - Type::NonNullList(ref inner, expected_size) => TypeType::NonNull(Box::new( - TypeType::List(Box::new(self.make_type(inner)), expected_size), + DynType::NonNullList(inner, expected_size) => TypeType::NonNull(Box::new( + TypeType::List(Box::new(self.make_type(inner.as_dyn_type())), expected_size), )), - Type::Named(ref n) => self.type_by_name(n).expect("Type not found in schema"), - Type::List(ref inner, expected_size) => { - TypeType::List(Box::new(self.make_type(inner)), expected_size) + DynType::Named(n) => self + .type_by_name(n.as_ref()) + .expect("Type not found in schema"), + DynType::List(inner, expected_size) => { + TypeType::List(Box::new(self.make_type(inner.as_dyn_type())), expected_size) } } } @@ -512,10 +561,10 @@ impl<'a, S> SchemaType<'a, S> { } /// If the type is a subtype of another type. - pub fn is_subtype<'b>(&self, sub_type: &Type<'b>, super_type: &Type<'b>) -> bool { - use crate::ast::Type::*; + pub fn is_subtype<'b>(&self, sub_type: &DynType<'b>, super_type: &DynType<'b>) -> bool { + use DynType::*; - if super_type == sub_type { + if super_type.equals(sub_type) { return true; } @@ -523,12 +572,12 @@ impl<'a, S> SchemaType<'a, S> { (&NonNullNamed(ref super_name), &NonNullNamed(ref sub_name)) | (&Named(ref super_name), &Named(ref sub_name)) | (&Named(ref super_name), &NonNullNamed(ref sub_name)) => { - self.is_named_subtype(sub_name, super_name) + self.is_named_subtype(sub_name.as_ref(), super_name.as_ref()) } - (&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) + (&NonNullList(super_inner, _), &NonNullList(sub_inner, _)) + | (&List(super_inner, _), &List(sub_inner, _)) + | (&List(super_inner, _), &NonNullList(sub_inner, _)) => { + self.is_subtype(&sub_inner.as_dyn_type(), &super_inner.as_dyn_type()) } _ => false, } @@ -581,14 +630,14 @@ impl<'a, S> TypeType<'a, S> { } } -impl<'a, S> DirectiveType<'a, S> +impl DirectiveType where - S: ScalarValue + 'a, + S: ScalarValue, { pub fn new( name: &str, locations: &[DirectiveLocation], - arguments: &[Argument<'a, S>], + arguments: &[Argument], is_repeatable: bool, ) -> Self { Self { @@ -600,7 +649,7 @@ where } } - fn new_skip(registry: &mut Registry<'a, S>) -> DirectiveType<'a, S> + fn new_skip(registry: &mut Registry) -> DirectiveType where S: ScalarValue, { @@ -611,12 +660,12 @@ where DirectiveLocation::FragmentSpread, DirectiveLocation::InlineFragment, ], - &[registry.arg::("if", &())], + &[registry.arg::(literal!("if"), &())], false, ) } - fn new_include(registry: &mut Registry<'a, S>) -> DirectiveType<'a, S> + fn new_include(registry: &mut Registry) -> DirectiveType where S: ScalarValue, { @@ -627,12 +676,12 @@ where DirectiveLocation::FragmentSpread, DirectiveLocation::InlineFragment, ], - &[registry.arg::("if", &())], + &[registry.arg::(literal!("if"), &())], false, ) } - fn new_deprecated(registry: &mut Registry<'a, S>) -> DirectiveType<'a, S> + fn new_deprecated(registry: &mut Registry) -> DirectiveType where S: ScalarValue, { @@ -642,24 +691,24 @@ where DirectiveLocation::FieldDefinition, DirectiveLocation::EnumValue, ], - &[registry.arg::("reason", &())], + &[registry.arg::(literal!("reason"), &())], false, ) } - fn new_specified_by(registry: &mut Registry<'a, S>) -> DirectiveType<'a, S> + fn new_specified_by(registry: &mut Registry) -> DirectiveType where S: ScalarValue, { Self::new( "specifiedBy", &[DirectiveLocation::Scalar], - &[registry.arg::("url", &())], + &[registry.arg::(literal!("url"), &())], false, ) } - pub fn description(mut self, description: &str) -> DirectiveType<'a, S> { + pub fn description(mut self, description: &str) -> DirectiveType { self.description = Some(description.into()); self } @@ -693,6 +742,40 @@ impl<'a, S> fmt::Display for TypeType<'a, S> { } } +impl<'a> DynType<'a> { + pub fn equals(&self, other: &DynType) -> bool { + match (self, other) { + (DynType::Named(n0), DynType::Named(n1)) => n0 == n1, + (DynType::List(t0, s0), DynType::List(t1, s1)) => { + t0.as_dyn_type().equals(&t1.as_dyn_type()) && s0 == s1 + } + (DynType::NonNullNamed(n0), DynType::NonNullNamed(n1)) => n0 == n1, + (DynType::NonNullList(t0, s0), DynType::NonNullList(t1, s1)) => { + t0.as_dyn_type().equals(&t1.as_dyn_type()) && s0 == s1 + } + _ => false, + } + } + + pub fn innermost_name(&self) -> &'a str { + match self { + Self::Named(n) | Self::NonNullNamed(n) => n, + Self::List(l, _) | Self::NonNullList(l, _) => l.as_dyn_type().innermost_name(), + } + } +} + +impl<'a> fmt::Display for DynType<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Named(n) => write!(f, "{n}"), + Self::NonNullNamed(n) => write!(f, "{n}!"), + Self::List(t, _) => write!(f, "[{}]", t.as_dyn_type()), + Self::NonNullList(t, _) => write!(f, "[{}]!", t.as_dyn_type()), + } + } +} + /// Sorts the provided [`TypeType`]s in the "type-then-name" manner. fn sort_concrete_types(types: &mut [TypeType]) { types.sort_by(|a, b| { diff --git a/juniper/src/schema/schema.rs b/juniper/src/schema/schema.rs index 9ec47e33f..f7573ead7 100644 --- a/juniper/src/schema/schema.rs +++ b/juniper/src/schema/schema.rs @@ -1,3 +1,5 @@ +use arcstr::ArcStr; + use crate::{ ast::Selection, executor::{ExecutionResult, Executor, Registry}, @@ -17,28 +19,27 @@ use crate::schema::{ model::{DirectiveLocation, DirectiveType, RootNode, SchemaType, TypeType}, }; -impl<'a, S, QueryT, MutationT, SubscriptionT> GraphQLType - for RootNode<'a, QueryT, MutationT, SubscriptionT, S> +use super::model::AsDynType; + +impl GraphQLType + for RootNode where S: ScalarValue, QueryT: GraphQLType, MutationT: GraphQLType, SubscriptionT: GraphQLType, { - fn name(info: &Self::TypeInfo) -> Option<&str> { + fn name(info: &Self::TypeInfo) -> Option { QueryT::name(info) } - fn meta<'r>(info: &Self::TypeInfo, registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(info: &Self::TypeInfo, registry: &mut Registry) -> MetaType { QueryT::meta(info, registry) } } -impl<'a, S, QueryT, MutationT, SubscriptionT> GraphQLValue - for RootNode<'a, QueryT, MutationT, SubscriptionT, S> +impl GraphQLValue + for RootNode where S: ScalarValue, QueryT: GraphQLType, @@ -48,7 +49,7 @@ where type Context = QueryT::Context; type TypeInfo = QueryT::TypeInfo; - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { QueryT::name(info) } @@ -99,7 +100,7 @@ where } impl<'a, S, QueryT, MutationT, SubscriptionT> GraphQLValueAsync - for RootNode<'a, QueryT, MutationT, SubscriptionT, S> + for RootNode where QueryT: GraphQLTypeAsync, QueryT::TypeInfo: Sync, @@ -132,11 +133,11 @@ where #[graphql_object( name = "__Schema" - context = SchemaType<'a, S>, + context = SchemaType, scalar = S, internal, )] -impl<'a, S: ScalarValue + 'a> SchemaType<'a, S> { +impl SchemaType { fn description(&self) -> Option<&str> { self.description.as_deref() } @@ -177,7 +178,7 @@ impl<'a, S: ScalarValue + 'a> SchemaType<'a, S> { #[graphql_object( name = "__Type" - context = SchemaType<'a, S>, + context = SchemaType, scalar = S, internal, )] @@ -189,14 +190,14 @@ impl<'a, S: ScalarValue + 'a> TypeType<'a, S> { } } - fn description(&self) -> Option<&str> { + fn description(&self) -> Option<&ArcStr> { match self { TypeType::Concrete(t) => t.description(), _ => None, } } - fn specified_by_url(&self) -> Option<&str> { + fn specified_by_url(&self) -> Option<&ArcStr> { match self { Self::Concrete(t) => t.specified_by_url(), Self::NonNull(_) | Self::List(..) => None, @@ -248,7 +249,7 @@ impl<'a, S: ScalarValue + 'a> TypeType<'a, S> { } } - fn interfaces<'s>(&self, context: &'s SchemaType<'a, S>) -> Option>> { + fn interfaces<'s>(&self, context: &'s SchemaType) -> Option>> { match self { TypeType::Concrete( &MetaType::Object(ObjectMeta { @@ -269,7 +270,7 @@ impl<'a, S: ScalarValue + 'a> TypeType<'a, S> { } } - fn possible_types<'s>(&self, context: &'s SchemaType<'a, S>) -> Option>> { + fn possible_types<'s>(&self, context: &'s SchemaType) -> Option>> { match self { TypeType::Concrete(&MetaType::Union(UnionMeta { ref of_type_names, .. @@ -335,13 +336,13 @@ impl<'a, S: ScalarValue + 'a> TypeType<'a, S> { #[graphql_object( name = "__Field", - context = SchemaType<'a, S>, + context = SchemaType, scalar = S, internal, )] -impl<'a, S: ScalarValue + 'a> Field<'a, S> { - fn name(&self) -> String { - self.name.clone().into() +impl Field { + fn name(&self) -> &ArcStr { + &self.name } #[graphql(name = "description")] @@ -356,8 +357,8 @@ impl<'a, S: ScalarValue + 'a> Field<'a, S> { } #[graphql(name = "type")] - fn type_<'s>(&self, context: &'s SchemaType<'a, S>) -> TypeType<'s, S> { - context.make_type(&self.field_type) + fn type_<'s>(&self, context: &'s SchemaType) -> TypeType<'s, S> { + context.make_type(self.field_type.as_dyn_type()) } fn is_deprecated(&self) -> bool { @@ -371,11 +372,11 @@ impl<'a, S: ScalarValue + 'a> Field<'a, S> { #[graphql_object( name = "__InputValue", - context = SchemaType<'a, S>, + context = SchemaType, scalar = S, internal, )] -impl<'a, S: ScalarValue + 'a> Argument<'a, S> { +impl Argument { fn name(&self) -> &str { &self.name } @@ -386,8 +387,8 @@ impl<'a, S: ScalarValue + 'a> Argument<'a, S> { } #[graphql(name = "type")] - fn type_<'s>(&self, context: &'s SchemaType<'a, S>) -> TypeType<'s, S> { - context.make_type(&self.arg_type) + fn type_<'s>(&self, context: &'s SchemaType) -> TypeType<'s, S> { + context.make_type(self.arg_type.as_dyn_type()) } #[graphql(name = "defaultValue")] @@ -418,11 +419,11 @@ impl EnumValue { #[graphql_object( name = "__Directive", - context = SchemaType<'a, S>, + context = SchemaType, scalar = S, internal, )] -impl<'a, S: ScalarValue + 'a> DirectiveType<'a, S> { +impl DirectiveType { fn name(&self) -> &str { &self.name } diff --git a/juniper/src/schema/translate/graphql_parser.rs b/juniper/src/schema/translate/graphql_parser.rs index 0fac42caa..87f41cd53 100644 --- a/juniper/src/schema/translate/graphql_parser.rs +++ b/juniper/src/schema/translate/graphql_parser.rs @@ -25,12 +25,12 @@ use crate::{ pub struct GraphQLParserTranslator; -impl<'a, S: 'a, T> From<&'a SchemaType<'a, S>> for Document<'a, T> +impl<'a, S: 'a, T> From<&'a SchemaType> for Document<'a, T> where S: ScalarValue, T: Text<'a> + Default, { - fn from(input: &'a SchemaType<'a, S>) -> Document<'a, T> { + fn from(input: &'a SchemaType) -> Document<'a, T> { GraphQLParserTranslator::translate_schema(input) } } @@ -83,7 +83,7 @@ impl GraphQLParserTranslator { { ExternalInputValue { position: Pos::default(), - description: input.description.as_ref().map(From::from), + description: input.description.as_deref().map(From::from), name: From::from(input.name.as_str()), value_type: GraphQLParserTranslator::translate_type(&input.arg_type), default_value: input @@ -134,7 +134,7 @@ impl GraphQLParserTranslator { } } - fn translate_type<'a, T>(input: &'a Type<'a>) -> ExternalType<'a, T> + fn translate_type<'a, T, N: AsRef>(input: &'a Type) -> ExternalType<'a, T> where T: Text<'a>, { @@ -160,7 +160,7 @@ impl GraphQLParserTranslator { match input { MetaType::Scalar(x) => ExternalTypeDefinition::Scalar(ExternalScalarType { position: Pos::default(), - description: x.description.as_ref().map(From::from), + description: x.description.as_ref().map(|s| s.to_string()), name: From::from(x.name.as_ref()), directives: vec![], }), @@ -288,7 +288,12 @@ where name: "deprecated".into(), arguments: reason .as_ref() - .map(|rsn| vec![(From::from("reason"), ExternalValue::String(rsn.into()))]) + .map(|rsn| { + vec![( + From::from("reason"), + ExternalValue::String(rsn.as_str().into()), + )] + }) .unwrap_or_default(), }), } diff --git a/juniper/src/tests/subscriptions.rs b/juniper/src/tests/subscriptions.rs index a4171651d..51a8114ad 100644 --- a/juniper/src/tests/subscriptions.rs +++ b/juniper/src/tests/subscriptions.rs @@ -30,8 +30,7 @@ impl MyQuery { } } -type Schema = - RootNode<'static, MyQuery, EmptyMutation, MySubscription, DefaultScalarValue>; +type Schema = RootNode, MySubscription, DefaultScalarValue>; fn run(f: impl std::future::Future) -> O { let rt = tokio::runtime::Runtime::new().unwrap(); diff --git a/juniper/src/tests/type_info_tests.rs b/juniper/src/tests/type_info_tests.rs index 6b43a7efc..163803b50 100644 --- a/juniper/src/tests/type_info_tests.rs +++ b/juniper/src/tests/type_info_tests.rs @@ -1,3 +1,4 @@ +use arcstr::ArcStr; use indexmap::IndexMap; use crate::{ @@ -12,8 +13,8 @@ use crate::{ }; pub struct NodeTypeInfo { - name: String, - attribute_names: Vec, + name: ArcStr, + attribute_names: Vec, } pub struct Node { @@ -24,18 +25,15 @@ impl GraphQLType for Node where S: ScalarValue, { - fn name(info: &Self::TypeInfo) -> Option<&str> { - Some(&info.name) + fn name(info: &Self::TypeInfo) -> Option { + Some(info.name.clone()) } - fn meta<'r>(info: &Self::TypeInfo, registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(info: &Self::TypeInfo, registry: &mut Registry) -> MetaType { let fields = info .attribute_names .iter() - .map(|name| registry.field::(name, &())) + .map(|name| registry.field::(name.clone(), &())) .collect::>(); registry @@ -51,7 +49,7 @@ where type Context = (); type TypeInfo = NodeTypeInfo; - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option { >::name(info) } diff --git a/juniper/src/types/async_await.rs b/juniper/src/types/async_await.rs index d86ed01be..1fb94c9c5 100644 --- a/juniper/src/types/async_await.rs +++ b/juniper/src/types/async_await.rs @@ -307,7 +307,7 @@ where if executor .schema() .is_named_subtype(&concrete_type_name, fragment.type_condition.item) - || Some(fragment.type_condition.item) == type_name + || Some(fragment.type_condition.item) == type_name.as_deref() { let sub_result = instance .resolve_into_type_async( diff --git a/juniper/src/types/base.rs b/juniper/src/types/base.rs index 8392d24a0..144bd46a2 100644 --- a/juniper/src/types/base.rs +++ b/juniper/src/types/base.rs @@ -1,3 +1,4 @@ +use arcstr::ArcStr; use indexmap::IndexMap; use crate::{ @@ -187,7 +188,7 @@ where /// any calculation and _always_ return the same value. /// /// Usually, it should just call a [`GraphQLType::name`] inside. - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str>; + fn type_name(&self, info: &Self::TypeInfo) -> Option; /// Resolves the value of a single field on this [`GraphQLValue`]. /// @@ -310,7 +311,7 @@ where /// ``` /// # use std::collections::HashMap; /// use juniper::{ -/// meta::MetaType, Arguments, Context, DefaultScalarValue, Executor, ExecutionResult, +/// literal, meta::MetaType, ArcStr, Arguments, Context, DefaultScalarValue, Executor, ExecutionResult, /// FieldResult, GraphQLType, GraphQLValue, Registry, /// }; /// @@ -322,21 +323,19 @@ where /// struct User { id: String, name: String, friend_ids: Vec } /// /// impl GraphQLType for User { -/// fn name(_: &()) -> Option<&'static str> { -/// Some("User") +/// fn name(_: &()) -> Option { +/// Some(literal!("User")) /// } /// -/// fn meta<'r>(_: &(), registry: &mut Registry<'r>) -> MetaType<'r> -/// where DefaultScalarValue: 'r, -/// { +/// fn meta(_: &(), registry: &mut Registry) -> MetaType { /// // First, we need to define all fields and their types on this type. /// // /// // If we need arguments, want to implement interfaces, or want to add documentation /// // strings, we can do it here. /// let fields = &[ -/// registry.field::<&String>("id", &()), -/// registry.field::<&String>("name", &()), -/// registry.field::>("friends", &()), +/// registry.field::<&String>(literal!("id"), &()), +/// registry.field::<&String>(literal!("name"), &()), +/// registry.field::>(literal!("friends"), &()), /// ]; /// registry.build_object_type::(&(), fields).into_meta() /// } @@ -346,7 +345,7 @@ where /// type Context = Database; /// type TypeInfo = (); /// -/// fn type_name(&self, _: &()) -> Option<&'static str> { +/// fn type_name(&self, _: &()) -> Option { /// ::name(&()) /// } /// @@ -398,12 +397,10 @@ where /// /// This function will be called multiple times during schema construction. It must _not_ /// perform any calculation and _always_ return the same value. - fn name(info: &Self::TypeInfo) -> Option<&str>; + fn name(info: &Self::TypeInfo) -> Option; /// Returns [`MetaType`] representing this [`GraphQLType`]. - fn meta<'r>(info: &Self::TypeInfo, registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r; + fn meta(info: &Self::TypeInfo, registry: &mut Registry) -> MetaType; } /// Resolver logic for queries'/mutations' selection set. @@ -524,7 +521,7 @@ where if executor .schema() .is_named_subtype(&concrete_type_name, fragment.type_condition.item) - || Some(fragment.type_condition.item) == type_name + || Some(fragment.type_condition.item) == type_name.as_deref() { let sub_result = instance.resolve_into_type( info, diff --git a/juniper/src/types/containers.rs b/juniper/src/types/containers.rs index 108f0e021..c6bea24f6 100644 --- a/juniper/src/types/containers.rs +++ b/juniper/src/types/containers.rs @@ -3,6 +3,8 @@ use std::{ ptr, }; +use arcstr::ArcStr; + use crate::{ ast::{FromInputValue, InputValue, Selection, ToInputValue}, executor::{ExecutionResult, Executor, FieldError, IntoFieldError, Registry}, @@ -19,14 +21,11 @@ where T: GraphQLType, S: ScalarValue, { - fn name(_: &Self::TypeInfo) -> Option<&'static str> { + fn name(_: &Self::TypeInfo) -> Option { None } - fn meta<'r>(info: &Self::TypeInfo, registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(info: &Self::TypeInfo, registry: &mut Registry) -> MetaType { registry.build_nullable_type::(info).into_meta() } } @@ -39,7 +38,7 @@ where type Context = T::Context; type TypeInfo = T::TypeInfo; - fn type_name(&self, _: &Self::TypeInfo) -> Option<&'static str> { + fn type_name(&self, _: &Self::TypeInfo) -> Option { None } @@ -105,14 +104,11 @@ where T: GraphQLType, S: ScalarValue, { - fn name(_: &Self::TypeInfo) -> Option<&'static str> { + fn name(_: &Self::TypeInfo) -> Option { None } - fn meta<'r>(info: &Self::TypeInfo, registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(info: &Self::TypeInfo, registry: &mut Registry) -> MetaType { registry.build_list_type::(info, None).into_meta() } } @@ -125,7 +121,7 @@ where type Context = T::Context; type TypeInfo = T::TypeInfo; - fn type_name(&self, _: &Self::TypeInfo) -> Option<&'static str> { + fn type_name(&self, _: &Self::TypeInfo) -> Option { None } @@ -225,14 +221,11 @@ where S: ScalarValue, T: GraphQLType, { - fn name(_: &Self::TypeInfo) -> Option<&'static str> { + fn name(_: &Self::TypeInfo) -> Option { None } - fn meta<'r>(info: &Self::TypeInfo, registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(info: &Self::TypeInfo, registry: &mut Registry) -> MetaType { registry.build_list_type::(info, None).into_meta() } } @@ -245,7 +238,7 @@ where type Context = T::Context; type TypeInfo = T::TypeInfo; - fn type_name(&self, _: &Self::TypeInfo) -> Option<&'static str> { + fn type_name(&self, _: &Self::TypeInfo) -> Option { None } @@ -292,14 +285,11 @@ where S: ScalarValue, T: GraphQLType, { - fn name(_: &Self::TypeInfo) -> Option<&'static str> { + fn name(_: &Self::TypeInfo) -> Option { None } - fn meta<'r>(info: &Self::TypeInfo, registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(info: &Self::TypeInfo, registry: &mut Registry) -> MetaType { registry.build_list_type::(info, Some(N)).into_meta() } } @@ -312,7 +302,7 @@ where type Context = T::Context; type TypeInfo = T::TypeInfo; - fn type_name(&self, _: &Self::TypeInfo) -> Option<&'static str> { + fn type_name(&self, _: &Self::TypeInfo) -> Option { None } diff --git a/juniper/src/types/marker.rs b/juniper/src/types/marker.rs index c4cc18f55..7caf226cb 100644 --- a/juniper/src/types/marker.rs +++ b/juniper/src/types/marker.rs @@ -7,6 +7,8 @@ use std::sync::Arc; +use arcstr::ArcStr; + use crate::{GraphQLType, ScalarValue}; /// Maker trait for [GraphQL objects][1]. @@ -272,6 +274,7 @@ where } impl IsOutputType for str where S: ScalarValue {} +impl IsOutputType for ArcStr where S: ScalarValue {} /// Marker trait for types which can be used as input types. /// diff --git a/juniper/src/types/name.rs b/juniper/src/types/name.rs index 899137ad7..152605e20 100644 --- a/juniper/src/types/name.rs +++ b/juniper/src/types/name.rs @@ -2,13 +2,24 @@ use std::{ borrow::Borrow, error::Error, fmt::{Display, Formatter, Result as FmtResult}, - str::FromStr, }; +use arcstr::ArcStr; + #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct Name(String); +pub struct Name(ArcStr); impl Name { + pub fn new(input: ArcStr) -> Result { + if Self::is_valid(&input) { + Ok(Name(input)) + } else { + Err(NameParseError(format!( + "Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but \"{input}\" does not", + ))) + } + } + pub fn is_valid(input: &str) -> bool { for (i, c) in input.chars().enumerate() { let is_valid = c.is_ascii_alphabetic() || c == '_' || (i > 0 && c.is_ascii_digit()); @@ -35,21 +46,8 @@ impl Error for NameParseError { } } -impl FromStr for Name { - type Err = NameParseError; - fn from_str(s: &str) -> Result { - if Name::is_valid(s) { - Ok(Name(s.into())) - } else { - Err(NameParseError(format!( - "Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but \"{s}\" does not", - ))) - } - } -} - -impl Borrow for Name { - fn borrow(&self) -> &String { +impl Borrow for Name { + fn borrow(&self) -> &ArcStr { &self.0 } } diff --git a/juniper/src/types/nullable.rs b/juniper/src/types/nullable.rs index 20f16708b..3c4b47895 100644 --- a/juniper/src/types/nullable.rs +++ b/juniper/src/types/nullable.rs @@ -1,3 +1,5 @@ +use arcstr::ArcStr; + use crate::{ ast::{FromInputValue, InputValue, Selection, ToInputValue}, executor::{ExecutionResult, Executor, Registry}, @@ -224,14 +226,11 @@ where T: GraphQLType, S: ScalarValue, { - fn name(_: &Self::TypeInfo) -> Option<&'static str> { + fn name(_: &Self::TypeInfo) -> Option { None } - fn meta<'r>(info: &Self::TypeInfo, registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(info: &Self::TypeInfo, registry: &mut Registry) -> MetaType { registry.build_nullable_type::(info).into_meta() } } @@ -244,7 +243,7 @@ where type Context = T::Context; type TypeInfo = T::TypeInfo; - fn type_name(&self, _: &Self::TypeInfo) -> Option<&'static str> { + fn type_name(&self, _: &Self::TypeInfo) -> Option { None } diff --git a/juniper/src/types/pointers.rs b/juniper/src/types/pointers.rs index 17e706799..386ae50d2 100644 --- a/juniper/src/types/pointers.rs +++ b/juniper/src/types/pointers.rs @@ -1,5 +1,7 @@ use std::{fmt, sync::Arc}; +use arcstr::ArcStr; + use crate::{ ast::{FromInputValue, InputValue, Selection, ToInputValue}, executor::{ExecutionResult, Executor, Registry}, @@ -17,14 +19,11 @@ where T: GraphQLType + ?Sized, S: ScalarValue, { - fn name(info: &Self::TypeInfo) -> Option<&str> { + fn name(info: &Self::TypeInfo) -> Option { T::name(info) } - fn meta<'r>(info: &Self::TypeInfo, registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(info: &Self::TypeInfo, registry: &mut Registry) -> MetaType { T::meta(info, registry) } } @@ -37,7 +36,7 @@ where type Context = T::Context; type TypeInfo = T::TypeInfo; - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { (**self).type_name(info) } @@ -115,14 +114,11 @@ where T: GraphQLType + ?Sized, S: ScalarValue, { - fn name(info: &Self::TypeInfo) -> Option<&str> { + fn name(info: &Self::TypeInfo) -> Option { T::name(info) } - fn meta<'r>(info: &Self::TypeInfo, registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(info: &Self::TypeInfo, registry: &mut Registry) -> MetaType { T::meta(info, registry) } } @@ -135,7 +131,7 @@ where type Context = T::Context; type TypeInfo = T::TypeInfo; - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { (**self).type_name(info) } @@ -211,14 +207,11 @@ where S: ScalarValue, T: GraphQLType + ?Sized, { - fn name(info: &Self::TypeInfo) -> Option<&str> { + fn name(info: &Self::TypeInfo) -> Option { T::name(info) } - fn meta<'r>(info: &Self::TypeInfo, registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(info: &Self::TypeInfo, registry: &mut Registry) -> MetaType { T::meta(info, registry) } } @@ -231,7 +224,7 @@ where type Context = T::Context; type TypeInfo = T::TypeInfo; - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { (**self).type_name(info) } diff --git a/juniper/src/types/scalars.rs b/juniper/src/types/scalars.rs index c1002ec27..032aa0036 100644 --- a/juniper/src/types/scalars.rs +++ b/juniper/src/types/scalars.rs @@ -2,6 +2,7 @@ use std::{ char, convert::From, fmt, marker::PhantomData, ops::Deref, rc::Rc, thread::JoinHandle, u32, }; +use arcstr::{literal, ArcStr}; use serde::{Deserialize, Serialize}; use crate::{ @@ -200,18 +201,27 @@ impl reflect::BaseSubTypes for str { const NAMES: reflect::Types = &[>::NAME]; } +impl reflect::WrappedType for ArcStr { + const VALUE: reflect::WrappedValue = 1; +} + +impl reflect::BaseType for ArcStr { + const NAME: reflect::Type = "String"; +} + +impl reflect::BaseSubTypes for ArcStr { + const NAMES: reflect::Types = &[>::NAME]; +} + impl GraphQLType for str where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("String") + fn name(_: &()) -> Option { + Some(literal!("String")) } - fn meta<'r>(_: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(_: &(), registry: &mut Registry) -> MetaType { registry.build_scalar_type::(&()).into_meta() } } @@ -223,7 +233,7 @@ where type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { >::name(info) } @@ -252,6 +262,55 @@ where } } +impl GraphQLType for ArcStr +where + S: ScalarValue, +{ + fn name(_: &()) -> Option { + Some(literal!("String")) + } + + fn meta(_: &(), registry: &mut Registry) -> MetaType { + registry.build_scalar_type::(&()).into_meta() + } +} + +impl GraphQLValue for ArcStr +where + S: ScalarValue, +{ + type Context = (); + type TypeInfo = (); + + fn type_name(&self, info: &Self::TypeInfo) -> Option { + >::name(info) + } + + fn resolve( + &self, + _: &(), + _: Option<&[Selection]>, + _: &Executor, + ) -> ExecutionResult { + Ok(Value::scalar(String::from(self.as_str()))) + } +} + +impl GraphQLValueAsync for ArcStr +where + S: ScalarValue + Send + Sync, +{ + fn resolve_async<'a>( + &'a self, + info: &'a Self::TypeInfo, + selection_set: Option<&'a [Selection]>, + executor: &'a Executor, + ) -> crate::BoxFuture<'a, crate::ExecutionResult> { + use futures::future; + Box::pin(future::ready(self.resolve(info, selection_set, executor))) + } +} + impl<'a, S> ToInputValue for &'a str where S: ScalarValue, @@ -361,14 +420,11 @@ impl GraphQLType for EmptyMutation where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("_EmptyMutation") + fn name(_: &()) -> Option { + Some(literal!("_EmptyMutation")) } - fn meta<'r>(_: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(_: &(), registry: &mut Registry) -> MetaType { registry.build_object_type::(&(), &[]).into_meta() } } @@ -380,7 +436,7 @@ where type Context = T; type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { >::name(info) } } @@ -422,14 +478,11 @@ impl GraphQLType for EmptySubscription where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("_EmptySubscription") + fn name(_: &()) -> Option { + Some(literal!("_EmptySubscription")) } - fn meta<'r>(_: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(_: &(), registry: &mut Registry) -> MetaType { registry.build_object_type::(&(), &[]).into_meta() } } @@ -441,7 +494,7 @@ where type Context = T; type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { >::name(info) } } diff --git a/juniper/src/types/subscriptions.rs b/juniper/src/types/subscriptions.rs index 3e8211b8a..93a587a0c 100644 --- a/juniper/src/types/subscriptions.rs +++ b/juniper/src/types/subscriptions.rs @@ -188,7 +188,7 @@ where 'res: 'f, { Box::pin(async move { - if self.type_name(info) == Some(type_name) { + if self.type_name(info).as_deref() == Some(type_name) { self.resolve_into_stream(info, executor).await } else { panic!("resolve_into_type_stream must be implemented"); diff --git a/juniper/src/types/utilities.rs b/juniper/src/types/utilities.rs index a4f5c45b4..201e23199 100644 --- a/juniper/src/types/utilities.rs +++ b/juniper/src/types/utilities.rs @@ -4,7 +4,7 @@ use crate::{ ast::InputValue, schema::{ meta::{Argument, EnumMeta, InputObjectMeta, MetaType}, - model::{SchemaType, TypeType}, + model::{AsDynType, SchemaType, TypeType}, }, value::ScalarValue, }; @@ -73,7 +73,7 @@ where let field_type = object_fields .iter() .filter(|f| f.name == field_key) - .map(|f| schema.make_type(&f.arg_type)) + .map(|f| schema.make_type(f.arg_type.as_dyn_type())) .next(); if let Some(field_arg_type) = field_type { @@ -155,12 +155,12 @@ where .iter() .filter_map(|f| { (f.arg_type.is_non_null() && f.default_value.is_none()) - .then_some(&f.name) + .then_some(f.name.as_str()) }) .collect::>(); let error_message = obj.iter().find_map(|(key, value)| { - remaining_required_fields.remove(&key.item); + remaining_required_fields.remove(key.item.as_str()); validate_object_field( schema, arg_type, @@ -179,7 +179,7 @@ where } else { let missing_fields = remaining_required_fields .into_iter() - .map(|s| format!("\"{}\"", &**s)) + .map(|s| format!("\"{}\"", s)) .collect::>() .join(", "); Some(error::missing_fields(arg_type, missing_fields)) diff --git a/juniper/src/validation/context.rs b/juniper/src/validation/context.rs index f46af2f30..bb10ce2b6 100644 --- a/juniper/src/validation/context.rs +++ b/juniper/src/validation/context.rs @@ -3,7 +3,10 @@ use std::{ fmt::{self, Debug}, }; -use crate::ast::{Definition, Document, Type}; +use crate::{ + ast::{Definition, Document}, + schema::model::DynType, +}; use crate::schema::{meta::MetaType, model::SchemaType}; @@ -18,13 +21,13 @@ pub struct RuleError { #[doc(hidden)] pub struct ValidatorContext<'a, S: Debug + 'a> { - pub schema: &'a SchemaType<'a, S>, + pub schema: &'a SchemaType, errors: Vec, - type_stack: Vec>>, - type_literal_stack: Vec>>, - input_type_stack: Vec>>, - input_type_literal_stack: Vec>>, - parent_type_stack: Vec>>, + type_stack: Vec>>, + type_literal_stack: Vec>>, + input_type_stack: Vec>>, + input_type_literal_stack: Vec>>, + parent_type_stack: Vec>>, fragment_names: HashSet<&'a str>, } @@ -109,7 +112,7 @@ impl<'a, S: Debug> ValidatorContext<'a, S> { } #[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>, f: F) -> R where F: FnOnce(&mut ValidatorContext<'a, S>) -> R, { @@ -120,7 +123,7 @@ impl<'a, S: Debug> ValidatorContext<'a, S> { self.type_stack.push(None); } - self.type_literal_stack.push(t.cloned()); + self.type_literal_stack.push(t); let res = f(self); @@ -144,7 +147,7 @@ impl<'a, S: Debug> ValidatorContext<'a, S> { } #[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>, f: F) -> R where F: FnOnce(&mut ValidatorContext<'a, S>) -> R, { @@ -155,7 +158,7 @@ impl<'a, S: Debug> ValidatorContext<'a, S> { self.input_type_stack.push(None); } - self.input_type_literal_stack.push(t.cloned()); + self.input_type_literal_stack.push(t); let res = f(self); @@ -166,27 +169,27 @@ impl<'a, S: Debug> ValidatorContext<'a, S> { } #[doc(hidden)] - pub fn current_type(&self) -> Option<&'a MetaType<'a, S>> { + pub fn current_type(&self) -> Option<&'a MetaType> { *self.type_stack.last().unwrap_or(&None) } #[doc(hidden)] - pub fn current_type_literal(&self) -> Option<&Type<'a>> { + pub fn current_type_literal(&self) -> Option> { match self.type_literal_stack.last() { - Some(Some(t)) => Some(t), + Some(Some(t)) => Some(*t), _ => None, } } #[doc(hidden)] - pub fn parent_type(&self) -> Option<&'a MetaType<'a, S>> { + pub fn parent_type(&self) -> Option<&'a MetaType> { *self.parent_type_stack.last().unwrap_or(&None) } #[doc(hidden)] - pub fn current_input_type_literal(&self) -> Option<&Type<'a>> { + pub fn current_input_type_literal(&self) -> Option> { match self.input_type_literal_stack.last() { - Some(Some(t)) => Some(t), + Some(Some(t)) => Some(*t), _ => None, } } diff --git a/juniper/src/validation/input_value.rs b/juniper/src/validation/input_value.rs index 1c906bbbe..51cc62cb5 100644 --- a/juniper/src/validation/input_value.rs +++ b/juniper/src/validation/input_value.rs @@ -6,7 +6,7 @@ use crate::{ parser::{SourcePosition, Spanning}, schema::{ meta::{EnumMeta, InputObjectMeta, MetaType, ScalarMeta}, - model::{SchemaType, TypeType}, + model::{AsDynType, SchemaType, TypeType}, }, validation::RuleError, value::ScalarValue, @@ -50,7 +50,7 @@ fn validate_var_defs( let raw_type_name = def.var_type.item.innermost_name(); match schema.concrete_type_by_name(raw_type_name) { Some(t) if t.is_input() => { - let ct = schema.make_type(&def.var_type.item); + let ct = schema.make_type(def.var_type.item.as_dyn_type()); if def.var_type.item.is_non_null() && is_absent_or_null(values.get(name.item)) { errors.push(RuleError::new( @@ -305,7 +305,7 @@ where var_name, var_pos, value, - &schema.make_type(&input_field.arg_type), + &schema.make_type(input_field.arg_type.as_dyn_type()), schema, Path::ObjectField(&input_field.name, path), )); diff --git a/juniper/src/validation/rules/arguments_of_correct_type.rs b/juniper/src/validation/rules/arguments_of_correct_type.rs index 4524cf8d6..0840f6017 100644 --- a/juniper/src/validation/rules/arguments_of_correct_type.rs +++ b/juniper/src/validation/rules/arguments_of_correct_type.rs @@ -3,14 +3,14 @@ use std::fmt; use crate::{ ast::{Directive, Field, InputValue}, parser::Spanning, - schema::meta::Argument, + schema::{meta::Argument, model::AsDynType}, types::utilities::validate_literal_value, validation::{ValidatorContext, Visitor}, value::ScalarValue, }; pub struct ArgumentsOfCorrectType<'a, S: fmt::Debug + 'a> { - current_args: Option<&'a Vec>>, + current_args: Option<&'a Vec>>, } pub fn factory<'a, S: fmt::Debug>() -> ArgumentsOfCorrectType<'a, S> { @@ -56,7 +56,7 @@ where .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); + let meta_type = ctx.schema.make_type(argument_meta.arg_type.as_dyn_type()); if let Some(err) = validate_literal_value(ctx.schema, &meta_type, &arg_value.item) { ctx.report_error(&error_message(arg_name.item, err), &[arg_value.span.start]); 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 bc3458972..ff66e589c 100644 --- a/juniper/src/validation/rules/default_values_of_correct_type.rs +++ b/juniper/src/validation/rules/default_values_of_correct_type.rs @@ -3,6 +3,7 @@ use std::fmt; use crate::{ ast::VariableDefinition, parser::Spanning, + schema::model::AsDynType, types::utilities::validate_literal_value, validation::{ValidatorContext, Visitor}, value::ScalarValue, @@ -34,7 +35,7 @@ where &[span.start], ) } else { - let meta_type = ctx.schema.make_type(&var_def.var_type.item); + let meta_type = ctx.schema.make_type(var_def.var_type.item.as_dyn_type()); if let Some(err) = validate_literal_value(ctx.schema, &meta_type, var_value) { ctx.report_error( diff --git a/juniper/src/validation/rules/known_argument_names.rs b/juniper/src/validation/rules/known_argument_names.rs index c8e11820f..171898e3d 100644 --- a/juniper/src/validation/rules/known_argument_names.rs +++ b/juniper/src/validation/rules/known_argument_names.rs @@ -14,7 +14,7 @@ enum ArgumentPosition<'a> { } pub struct KnownArgumentNames<'a, S: Debug + 'a> { - current_args: Option<(ArgumentPosition<'a>, &'a Vec>)>, + current_args: Option<(ArgumentPosition<'a>, &'a Vec>)>, } pub fn factory<'a, S: Debug>() -> KnownArgumentNames<'a, S> { 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 a41610d3f..3fbc78742 100644 --- a/juniper/src/validation/rules/overlapping_fields_can_be_merged.rs +++ b/juniper/src/validation/rules/overlapping_fields_can_be_merged.rs @@ -18,7 +18,7 @@ struct ConflictReason(String, ConflictReasonMessage); struct AstAndDef<'a, S: Debug + 'a>( Option<&'a str>, &'a Spanning>, - Option<&'a FieldType<'a, S>>, + Option<&'a FieldType>, ); type AstAndDefCollection<'a, S> = OrderedMap<&'a str, Vec>>; @@ -554,7 +554,11 @@ impl<'a, S: Debug> OverlappingFieldsCanBeMerged<'a, S> { )) } - fn is_type_conflict(ctx: &ValidatorContext<'a, S>, t1: &Type, t2: &Type) -> bool { + fn is_type_conflict + PartialEq>( + ctx: &ValidatorContext<'a, S>, + t1: &Type, + t2: &Type, + ) -> bool { match (t1, t2) { (&Type::List(ref inner1, expected_size1), &Type::List(ref inner2, expected_size2)) | ( @@ -568,8 +572,8 @@ impl<'a, S: Debug> OverlappingFieldsCanBeMerged<'a, S> { } (&Type::NonNullNamed(ref n1), &Type::NonNullNamed(ref n2)) | (&Type::Named(ref n1), &Type::Named(ref n2)) => { - let ct1 = ctx.schema.concrete_type_by_name(n1); - let ct2 = ctx.schema.concrete_type_by_name(n2); + let ct1 = ctx.schema.concrete_type_by_name(n1.as_ref()); + let ct2 = ctx.schema.concrete_type_by_name(n2.as_ref()); if ct1.map(MetaType::is_leaf).unwrap_or(false) || ct2.map(MetaType::is_leaf).unwrap_or(false) @@ -761,10 +765,13 @@ fn format_reason(reason: &ConflictReasonMessage) -> String { #[cfg(test)] mod tests { + use arcstr::ArcStr; + use super::{error_message, factory, ConflictReason, ConflictReasonMessage::*}; use crate::{ executor::Registry, + literal, schema::meta::MetaType, types::{ base::{GraphQLType, GraphQLValue}, @@ -1400,18 +1407,15 @@ mod tests { where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("SomeBox") + fn name(_: &()) -> Option { + Some(literal!("SomeBox")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let fields = &[ - registry.field::>("deepBox", i), - registry.field::>("unrelatedField", i), - registry.field::>("otherField", i), + registry.field::>(literal!("deepBox"), i), + registry.field::>(literal!("unrelatedField"), i), + registry.field::>(literal!("otherField"), i), ]; registry.build_interface_type::(i, fields).into_meta() @@ -1425,7 +1429,7 @@ mod tests { type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -1434,21 +1438,18 @@ mod tests { where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("StringBox") + fn name(_: &()) -> Option { + Some(literal!("StringBox")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let fields = &[ - registry.field::>("scalar", i), - registry.field::>("deepBox", i), - registry.field::>("unrelatedField", i), - registry.field::>>>("listStringBox", i), - registry.field::>("stringBox", i), - registry.field::>("intBox", i), + registry.field::>(literal!("scalar"), i), + registry.field::>(literal!("deepBox"), i), + registry.field::>(literal!("unrelatedField"), i), + registry.field::>>>(literal!("listStringBox"), i), + registry.field::>(literal!("stringBox"), i), + registry.field::>(literal!("intBox"), i), ]; registry @@ -1465,7 +1466,7 @@ mod tests { type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -1474,21 +1475,18 @@ mod tests { where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("IntBox") + fn name(_: &()) -> Option { + Some(literal!("IntBox")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let fields = &[ - registry.field::>("scalar", i), - registry.field::>("deepBox", i), - registry.field::>("unrelatedField", i), - registry.field::>>>("listStringBox", i), - registry.field::>("stringBox", i), - registry.field::>("intBox", i), + registry.field::>(literal!("scalar"), i), + registry.field::>(literal!("deepBox"), i), + registry.field::>(literal!("unrelatedField"), i), + registry.field::>>>(literal!("listStringBox"), i), + registry.field::>(literal!("stringBox"), i), + registry.field::>(literal!("intBox"), i), ]; registry @@ -1505,7 +1503,7 @@ mod tests { type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -1514,15 +1512,12 @@ mod tests { where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("NonNullStringBox1") + fn name(_: &()) -> Option { + Some(literal!("NonNullStringBox1")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { - let fields = &[registry.field::("scalar", i)]; + fn meta(i: &(), registry: &mut Registry) -> MetaType { + let fields = &[registry.field::(literal!("scalar"), i)]; registry.build_interface_type::(i, fields).into_meta() } @@ -1535,7 +1530,7 @@ mod tests { type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -1544,18 +1539,15 @@ mod tests { where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("NonNullStringBox1Impl") + fn name(_: &()) -> Option { + Some(literal!("NonNullStringBox1Impl")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let fields = &[ - registry.field::("scalar", i), - registry.field::>("deepBox", i), - registry.field::>("unrelatedField", i), + registry.field::(literal!("scalar"), i), + registry.field::>(literal!("deepBox"), i), + registry.field::>(literal!("unrelatedField"), i), ]; registry @@ -1575,7 +1567,7 @@ mod tests { type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -1584,15 +1576,12 @@ mod tests { where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("NonNullStringBox2") + fn name(_: &()) -> Option { + Some(literal!("NonNullStringBox2")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { - let fields = &[registry.field::("scalar", i)]; + fn meta(i: &(), registry: &mut Registry) -> MetaType { + let fields = &[registry.field::(literal!("scalar"), i)]; registry.build_interface_type::(i, fields).into_meta() } @@ -1605,7 +1594,7 @@ mod tests { type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -1614,18 +1603,15 @@ mod tests { where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("NonNullStringBox2Impl") + fn name(_: &()) -> Option { + Some(literal!("NonNullStringBox2Impl")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let fields = &[ - registry.field::("scalar", i), - registry.field::>("deepBox", i), - registry.field::>("unrelatedField", i), + registry.field::(literal!("scalar"), i), + registry.field::>(literal!("deepBox"), i), + registry.field::>(literal!("unrelatedField"), i), ]; registry @@ -1645,7 +1631,7 @@ mod tests { type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -1654,17 +1640,14 @@ mod tests { where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("Node") + fn name(_: &()) -> Option { + Some(literal!("Node")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let fields = &[ - registry.field::>("id", i), - registry.field::>("name", i), + registry.field::>(literal!("id"), i), + registry.field::>(literal!("name"), i), ]; registry.build_object_type::(i, fields).into_meta() @@ -1678,7 +1661,7 @@ mod tests { type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -1687,15 +1670,12 @@ mod tests { where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("Edge") + fn name(_: &()) -> Option { + Some(literal!("Edge")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { - let fields = &[registry.field::>("node", i)]; + fn meta(i: &(), registry: &mut Registry) -> MetaType { + let fields = &[registry.field::>(literal!("node"), i)]; registry.build_object_type::(i, fields).into_meta() } @@ -1708,7 +1688,7 @@ mod tests { type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -1717,15 +1697,12 @@ mod tests { where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("Connection") + fn name(_: &()) -> Option { + Some(literal!("Connection")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { - let fields = &[registry.field::>>>("edges", i)]; + fn meta(i: &(), registry: &mut Registry) -> MetaType { + let fields = &[registry.field::>>>(literal!("edges"), i)]; registry.build_object_type::(i, fields).into_meta() } @@ -1738,7 +1715,7 @@ mod tests { type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -1747,22 +1724,19 @@ mod tests { where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("QueryRoot") + fn name(_: &()) -> Option { + Some(literal!("QueryRoot")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { registry.get_type::(i); registry.get_type::(i); registry.get_type::(i); registry.get_type::(i); let fields = &[ - registry.field::>("someBox", i), - registry.field::>("connection", i), + registry.field::>(literal!("someBox"), i), + registry.field::>(literal!("connection"), i), ]; registry.build_object_type::(i, fields).into_meta() } @@ -1775,7 +1749,7 @@ mod tests { type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } diff --git a/juniper/src/validation/rules/possible_fragment_spreads.rs b/juniper/src/validation/rules/possible_fragment_spreads.rs index 856b33ec0..a24774f5f 100644 --- a/juniper/src/validation/rules/possible_fragment_spreads.rs +++ b/juniper/src/validation/rules/possible_fragment_spreads.rs @@ -11,7 +11,7 @@ use crate::{ use std::collections::HashMap; pub struct PossibleFragmentSpreads<'a, S: Debug + 'a> { - fragment_types: HashMap<&'a str, &'a MetaType<'a, S>>, + fragment_types: HashMap<&'a str, &'a MetaType>, } pub fn factory<'a, S: Debug>() -> PossibleFragmentSpreads<'a, S> { diff --git a/juniper/src/validation/rules/variables_in_allowed_position.rs b/juniper/src/validation/rules/variables_in_allowed_position.rs index 1ec9b5665..90c828c93 100644 --- a/juniper/src/validation/rules/variables_in_allowed_position.rs +++ b/juniper/src/validation/rules/variables_in_allowed_position.rs @@ -1,5 +1,4 @@ use std::{ - borrow::Cow, collections::{HashMap, HashSet}, fmt, }; @@ -7,6 +6,7 @@ use std::{ use crate::{ ast::{Document, Fragment, FragmentSpread, Operation, Type, VariableDefinition}, parser::Spanning, + schema::model::{AsDynType, DynType}, validation::{ValidatorContext, Visitor}, value::ScalarValue, Span, @@ -29,7 +29,7 @@ pub fn factory<'a, S: fmt::Debug>() -> VariableInAllowedPosition<'a, S> { pub struct VariableInAllowedPosition<'a, S: fmt::Debug + 'a> { spreads: HashMap, HashSet<&'a str>>, - variable_usages: HashMap, Vec<(SpannedInput<'a, String>, Type<'a>)>>, + variable_usages: HashMap, Vec<(SpannedInput<'a, String>, DynType<'a>)>>, #[allow(clippy::type_complexity)] variable_defs: HashMap, Vec<&'a (Spanning<&'a str>, VariableDefinition<'a, S>)>>, current_scope: Option>, @@ -88,11 +88,14 @@ impl<'a, S: fmt::Debug> VariableInAllowedPosition<'a, S> { (&Some(_), Type::List(inner, expected_size)) => { Type::NonNullList(inner.clone(), *expected_size) } - (&Some(_), Type::Named(inner)) => Type::NonNullNamed(Cow::Borrowed(inner)), + (&Some(_), Type::Named(inner)) => Type::NonNullNamed(*inner), (_, t) => t.clone(), }; - if !ctx.schema.is_subtype(&expected_type, var_type) { + if !ctx + .schema + .is_subtype(&expected_type.as_dyn_type(), var_type) + { ctx.report_error( &error_message(var_name.item, expected_type, var_type), &[var_def_name.span.start, var_name.span.start], @@ -169,7 +172,7 @@ where self.variable_usages .entry(scope.clone()) .or_default() - .push((var_name, input_type.clone())); + .push((var_name, input_type)); } } } diff --git a/juniper/src/validation/test_harness.rs b/juniper/src/validation/test_harness.rs index 1dd28ac66..672239845 100644 --- a/juniper/src/validation/test_harness.rs +++ b/juniper/src/validation/test_harness.rs @@ -1,3 +1,4 @@ +use arcstr::{literal, ArcStr}; use std::mem; use crate::{ @@ -76,17 +77,14 @@ impl GraphQLType for Being where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("Being") + fn name(_: &()) -> Option { + Some(literal!("Being")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let fields = &[registry - .field::>("name", i) - .argument(registry.arg::>("surname", i))]; + .field::>(literal!("name"), i) + .argument(registry.arg::>(literal!("surname"), i))]; registry.build_interface_type::(i, fields).into_meta() } @@ -99,7 +97,7 @@ where type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -108,17 +106,14 @@ impl GraphQLType for Pet where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("Pet") + fn name(_: &()) -> Option { + Some(literal!("Pet")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let fields = &[registry - .field::>("name", i) - .argument(registry.arg::>("surname", i))]; + .field::>(literal!("name"), i) + .argument(registry.arg::>(literal!("surname"), i))]; registry.build_interface_type::(i, fields).into_meta() } @@ -131,7 +126,7 @@ where type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -140,17 +135,14 @@ impl GraphQLType for Canine where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("Canine") + fn name(_: &()) -> Option { + Some(literal!("Canine")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let fields = &[registry - .field::>("name", i) - .argument(registry.arg::>("surname", i))]; + .field::>(literal!("name"), i) + .argument(registry.arg::>(literal!("surname"), i))]; registry.build_interface_type::(i, fields).into_meta() } @@ -163,7 +155,7 @@ where type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -172,17 +164,14 @@ impl GraphQLType for Unpopulated where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("Unpopulated") + fn name(_: &()) -> Option { + Some(literal!("Unpopulated")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let fields = &[registry - .field::>("name", i) - .argument(registry.arg::>("surname", i))]; + .field::>(literal!("name"), i) + .argument(registry.arg::>(literal!("surname"), i))]; registry .build_interface_type::(i, fields) @@ -198,7 +187,7 @@ where type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -207,21 +196,18 @@ impl GraphQLType for DogCommand where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("DogCommand") + fn name(_: &()) -> Option { + Some(literal!("DogCommand")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { registry .build_enum_type::( i, &[ - EnumValue::new("SIT"), - EnumValue::new("HEEL"), - EnumValue::new("DOWN"), + EnumValue::new(literal!("SIT")), + EnumValue::new(literal!("HEEL")), + EnumValue::new(literal!("DOWN")), ], ) .into_meta() @@ -235,7 +221,7 @@ where type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -260,31 +246,28 @@ impl GraphQLType for Dog where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("Dog") + fn name(_: &()) -> Option { + Some(literal!("Dog")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let fields = &[ registry - .field::>("name", i) - .argument(registry.arg::>("surname", i)), - registry.field::>("nickname", i), - registry.field::>("barkVolume", i), - registry.field::>("barks", i), + .field::>(literal!("name"), i) + .argument(registry.arg::>(literal!("surname"), i)), + registry.field::>(literal!("nickname"), i), + registry.field::>(literal!("barkVolume"), i), + registry.field::>(literal!("barks"), i), registry - .field::>("doesKnowCommand", i) - .argument(registry.arg::>("dogCommand", i)), + .field::>(literal!("doesKnowCommand"), i) + .argument(registry.arg::>(literal!("dogCommand"), i)), registry - .field::>("isHousetrained", i) - .argument(registry.arg_with_default("atOtherHomes", &true, i)), + .field::>(literal!("isHousetrained"), i) + .argument(registry.arg_with_default(literal!("atOtherHomes"), &true, i)), registry - .field::>("isAtLocation", i) - .argument(registry.arg::>("x", i)) - .argument(registry.arg::>("y", i)), + .field::>(literal!("isAtLocation"), i) + .argument(registry.arg::>(literal!("x"), i)) + .argument(registry.arg::>(literal!("y"), i)), ]; registry @@ -305,7 +288,7 @@ where type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -314,22 +297,19 @@ impl GraphQLType for FurColor where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("FurColor") + fn name(_: &()) -> Option { + Some(literal!("FurColor")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { registry .build_enum_type::( i, &[ - EnumValue::new("BROWN"), - EnumValue::new("BLACK"), - EnumValue::new("TAN"), - EnumValue::new("SPOTTED"), + EnumValue::new(literal!("BROWN")), + EnumValue::new(literal!("BLACK")), + EnumValue::new(literal!("TAN")), + EnumValue::new(literal!("SPOTTED")), ], ) .into_meta() @@ -343,7 +323,7 @@ where type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -369,22 +349,19 @@ impl GraphQLType for Cat where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("Cat") + fn name(_: &()) -> Option { + Some(literal!("Cat")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let fields = &[ registry - .field::>("name", i) - .argument(registry.arg::>("surname", i)), - registry.field::>("nickname", i), - registry.field::>("meows", i), - registry.field::>("meowVolume", i), - registry.field::>("furColor", i), + .field::>(literal!("name"), i) + .argument(registry.arg::>(literal!("surname"), i)), + registry.field::>(literal!("nickname"), i), + registry.field::>(literal!("meows"), i), + registry.field::>(literal!("meowVolume"), i), + registry.field::>(literal!("furColor"), i), ]; registry @@ -401,7 +378,7 @@ where type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -410,14 +387,11 @@ impl GraphQLType for CatOrDog where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("CatOrDog") + fn name(_: &()) -> Option { + Some(literal!("CatOrDog")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let types = &[registry.get_type::(i), registry.get_type::(i)]; registry.build_union_type::(i, types).into_meta() @@ -431,7 +405,7 @@ where type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -440,15 +414,12 @@ impl GraphQLType for Intelligent where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("Intelligent") + fn name(_: &()) -> Option { + Some(literal!("Intelligent")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { - let fields = &[registry.field::>("iq", i)]; + fn meta(i: &(), registry: &mut Registry) -> MetaType { + let fields = &[registry.field::>(literal!("iq"), i)]; registry.build_interface_type::(i, fields).into_meta() } @@ -461,7 +432,7 @@ where type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -470,21 +441,18 @@ impl GraphQLType for Human where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("Human") + fn name(_: &()) -> Option { + Some(literal!("Human")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let fields = &[ registry - .field::>("name", i) - .argument(registry.arg::>("surname", i)), - registry.field::>>>("pets", i), - registry.field::>>("relatives", i), - registry.field::>("iq", i), + .field::>(literal!("name"), i) + .argument(registry.arg::>(literal!("surname"), i)), + registry.field::>>>(literal!("pets"), i), + registry.field::>>(literal!("relatives"), i), + registry.field::>(literal!("iq"), i), ]; registry .build_object_type::(i, fields) @@ -503,7 +471,7 @@ where type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -512,20 +480,17 @@ impl GraphQLType for Alien where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("Alien") + fn name(_: &()) -> Option { + Some(literal!("Alien")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let fields = &[ registry - .field::>("name", i) - .argument(registry.arg::>("surname", i)), - registry.field::>("iq", i), - registry.field::>("numEyes", i), + .field::>(literal!("name"), i) + .argument(registry.arg::>(literal!("surname"), i)), + registry.field::>(literal!("iq"), i), + registry.field::>(literal!("numEyes"), i), ]; registry @@ -545,7 +510,7 @@ where type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -554,14 +519,11 @@ impl GraphQLType for DogOrHuman where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("DogOrHuman") + fn name(_: &()) -> Option { + Some(literal!("DogOrHuman")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let types = &[registry.get_type::(i), registry.get_type::(i)]; registry.build_union_type::(i, types).into_meta() @@ -575,7 +537,7 @@ where type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -584,14 +546,11 @@ impl GraphQLType for HumanOrAlien where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("HumanOrAlien") + fn name(_: &()) -> Option { + Some(literal!("HumanOrAlien")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let types = &[registry.get_type::(i), registry.get_type::(i)]; registry.build_union_type::(i, types).into_meta() @@ -605,7 +564,7 @@ where type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -614,20 +573,17 @@ impl GraphQLType for ComplexInput where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("ComplexInput") + fn name(_: &()) -> Option { + Some(literal!("ComplexInput")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let fields = &[ - registry.arg::("requiredField", i), - registry.arg::>("intField", i), - registry.arg::>("stringField", i), - registry.arg::>("booleanField", i), - registry.arg::>>>("stringListField", i), + registry.arg::(literal!("requiredField"), i), + registry.arg::>(literal!("intField"), i), + registry.arg::>(literal!("stringField"), i), + registry.arg::>(literal!("booleanField"), i), + registry.arg::>>>(literal!("stringListField"), i), ]; registry @@ -643,7 +599,7 @@ where type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -691,59 +647,58 @@ impl GraphQLType for ComplicatedArgs where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("ComplicatedArgs") + fn name(_: &()) -> Option { + Some(literal!("ComplicatedArgs")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let fields = &[ registry - .field::>("intArgField", i) - .argument(registry.arg::>("intArg", i)), + .field::>(literal!("intArgField"), i) + .argument(registry.arg::>(literal!("intArg"), i)), registry - .field::>("nonNullIntArgField", i) - .argument(registry.arg::("nonNullIntArg", i)), + .field::>(literal!("nonNullIntArgField"), i) + .argument(registry.arg::(literal!("nonNullIntArg"), i)), registry - .field::>("stringArgField", i) - .argument(registry.arg::>("stringArg", i)), + .field::>(literal!("stringArgField"), i) + .argument(registry.arg::>(literal!("stringArg"), i)), registry - .field::>("booleanArgField", i) - .argument(registry.arg::>("booleanArg", i)), + .field::>(literal!("booleanArgField"), i) + .argument(registry.arg::>(literal!("booleanArg"), i)), registry - .field::>("enumArgField", i) - .argument(registry.arg::>("enumArg", i)), + .field::>(literal!("enumArgField"), i) + .argument(registry.arg::>(literal!("enumArg"), i)), registry - .field::>("floatArgField", i) - .argument(registry.arg::>("floatArg", i)), + .field::>(literal!("floatArgField"), i) + .argument(registry.arg::>(literal!("floatArg"), i)), registry - .field::>("idArgField", i) - .argument(registry.arg::>("idArg", i)), + .field::>(literal!("idArgField"), i) + .argument(registry.arg::>(literal!("idArg"), i)), registry - .field::>("stringListArgField", i) - .argument(registry.arg::>>>("stringListArg", i)), + .field::>(literal!("stringListArgField"), i) + .argument( + registry.arg::>>>(literal!("stringListArg"), i), + ), registry - .field::>("nonNullStringListArgField", i) - .argument(registry.arg::>("nonNullStringListArg", i)), + .field::>(literal!("nonNullStringListArgField"), i) + .argument(registry.arg::>(literal!("nonNullStringListArg"), i)), registry - .field::>("complexArgField", i) - .argument(registry.arg::>("complexArg", i)), + .field::>(literal!("complexArgField"), i) + .argument(registry.arg::>(literal!("complexArg"), i)), registry - .field::>("multipleReqs", i) - .argument(registry.arg::("req1", i)) - .argument(registry.arg::("req2", i)), + .field::>(literal!("multipleReqs"), i) + .argument(registry.arg::(literal!("req1"), i)) + .argument(registry.arg::(literal!("req2"), i)), registry - .field::>("multipleOpts", i) - .argument(registry.arg_with_default("opt1", &0i32, i)) - .argument(registry.arg_with_default("opt2", &0i32, i)), + .field::>(literal!("multipleOpts"), i) + .argument(registry.arg_with_default(literal!("opt1"), &0i32, i)) + .argument(registry.arg_with_default(literal!("opt2"), &0i32, i)), registry - .field::>("multipleOptAndReq", i) - .argument(registry.arg::("req1", i)) - .argument(registry.arg::("req2", i)) - .argument(registry.arg_with_default("opt1", &0i32, i)) - .argument(registry.arg_with_default("opt2", &0i32, i)), + .field::>(literal!("multipleOptAndReq"), i) + .argument(registry.arg::(literal!("req1"), i)) + .argument(registry.arg::(literal!("req2"), i)) + .argument(registry.arg_with_default(literal!("opt1"), &0i32, i)) + .argument(registry.arg_with_default(literal!("opt2"), &0i32, i)), ]; registry.build_object_type::(i, fields).into_meta() @@ -757,7 +712,7 @@ where type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -766,26 +721,23 @@ impl GraphQLType for QueryRoot where S: ScalarValue, { - fn name(_: &()) -> Option<&'static str> { - Some("QueryRoot") + fn name(_: &()) -> Option { + Some(literal!("QueryRoot")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let fields = &[ registry - .field::>("human", i) - .argument(registry.arg::>("id", i)), - registry.field::>("alien", i), - registry.field::>("dog", i), - registry.field::>("cat", i), - registry.field::>("pet", i), - registry.field::>("catOrDog", i), - registry.field::>("dorOrHuman", i), - registry.field::>("humanOrAlien", i), - registry.field::>("complicatedArgs", i), + .field::>(literal!("human"), i) + .argument(registry.arg::>(literal!("id"), i)), + registry.field::>(literal!("alien"), i), + registry.field::>(literal!("dog"), i), + registry.field::>(literal!("cat"), i), + registry.field::>(literal!("pet"), i), + registry.field::>(literal!("catOrDog"), i), + registry.field::>(literal!("dorOrHuman"), i), + registry.field::>(literal!("humanOrAlien"), i), + registry.field::>(literal!("complicatedArgs"), i), ]; registry.build_object_type::(i, fields).into_meta() @@ -799,7 +751,7 @@ where type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -808,19 +760,16 @@ impl GraphQLType for MutationRoot where S: ScalarValue, { - fn name(_: &()) -> Option<&str> { - Some("MutationRoot") + fn name(_: &()) -> Option { + Some(literal!("MutationRoot")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let _ = registry.get_type::(i); - let fields = [registry.field::("testInput", i).argument( + let fields = [registry.field::(literal!("testInput"), i).argument( registry.arg_with_default::( - "input", + literal!("input"), &TestInput { id: 423, name: String::from("foo"), @@ -840,7 +789,7 @@ where type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } @@ -849,14 +798,11 @@ impl GraphQLType for SubscriptionRoot where S: ScalarValue, { - fn name(_: &()) -> Option<&str> { - Some("SubscriptionRoot") + fn name(_: &()) -> Option { + Some(literal!("SubscriptionRoot")) } - fn meta<'r>(i: &(), registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - { + fn meta(i: &(), registry: &mut Registry) -> MetaType { let fields = []; registry.build_object_type::(i, &fields).into_meta() @@ -870,7 +816,7 @@ where type Context = (); type TypeInfo = (); - fn type_name<'i>(&self, info: &'i Self::TypeInfo) -> Option<&'i str> { + fn type_name(&self, info: &Self::TypeInfo) -> Option { ::name(info) } } diff --git a/juniper/src/validation/visitor.rs b/juniper/src/validation/visitor.rs index 17d20ad12..382c48ea2 100644 --- a/juniper/src/validation/visitor.rs +++ b/juniper/src/validation/visitor.rs @@ -1,12 +1,13 @@ -use std::borrow::Cow; - use crate::{ ast::{ Arguments, Definition, Directive, Document, Field, Fragment, FragmentSpread, - InlineFragment, InputValue, Operation, OperationType, Selection, Type, VariableDefinitions, + InlineFragment, InputValue, Operation, OperationType, Selection, VariableDefinitions, }, parser::Spanning, - schema::meta::Argument, + schema::{ + meta::Argument, + model::{AsDynType, DynType}, + }, validation::{multi_visitor::MultiVisitorCons, ValidatorContext, Visitor}, value::ScalarValue, }; @@ -39,7 +40,7 @@ where .. }, .. - }) => Some(Type::NonNullNamed(Cow::Borrowed(name))), + }) => Some(DynType::NonNullNamed(name)), Definition::Operation(Spanning { item: Operation { @@ -47,9 +48,9 @@ where .. }, .. - }) => Some(Type::NonNullNamed(Cow::Borrowed( + }) => Some(DynType::NonNullNamed( ctx.schema.concrete_query_type().name().unwrap(), - ))), + )), Definition::Operation(Spanning { item: Operation { @@ -60,7 +61,7 @@ where }) => ctx .schema .concrete_mutation_type() - .map(|t| Type::NonNullNamed(Cow::Borrowed(t.name().unwrap()))), + .map(|t| DynType::NonNullNamed(t.name().unwrap())), Definition::Operation(Spanning { item: Operation { @@ -71,10 +72,10 @@ where }) => ctx .schema .concrete_subscription_type() - .map(|t| Type::NonNullNamed(Cow::Borrowed(t.name().unwrap()))), + .map(|t| DynType::NonNullNamed(t.name().unwrap())), }; - ctx.with_pushed_type(def_type.as_ref(), |ctx| { + ctx.with_pushed_type(def_type, |ctx| { enter_definition(v, ctx, def); visit_definition(v, ctx, def); exit_definition(v, ctx, def); @@ -132,9 +133,9 @@ fn visit_variable_definitions<'a, S, V>( { if let Some(ref defs) = *defs { for def in defs.item.iter() { - let var_type = def.1.var_type.item.clone(); + let var_type = &def.1.var_type.item; - ctx.with_pushed_input_type(Some(&var_type), |ctx| { + ctx.with_pushed_input_type(Some(var_type.as_dyn_type()), |ctx| { v.enter_variable_definition(ctx, def); if let Some(ref default_value) = def.1.default_value { @@ -185,7 +186,7 @@ fn visit_directives<'a, S, V>( fn visit_arguments<'a, S, V>( v: &mut V, ctx: &mut ValidatorContext<'a, S>, - meta_args: Option<&Vec>>, + meta_args: Option<&'a Vec>>, arguments: &'a Option>>, ) where S: ScalarValue, @@ -195,7 +196,8 @@ fn visit_arguments<'a, S, V>( for argument in arguments.item.iter() { let arg_type = meta_args .and_then(|args| args.iter().find(|a| a.name == argument.0.item)) - .map(|a| &a.arg_type); + .map(|a| &a.arg_type) + .map(|t| t.as_dyn_type()); ctx.with_pushed_input_type(arg_type, |ctx| { v.enter_argument(ctx, argument); @@ -254,7 +256,7 @@ fn visit_field<'a, S, V>( .parent_type() .and_then(|t| t.field_by_name(field.item.name.item)); - let field_type = meta_field.map(|f| &f.field_type); + let field_type = meta_field.map(|f| f.field_type.as_dyn_type()); let field_args = meta_field.and_then(|f| f.arguments.as_ref()); ctx.with_pushed_type(field_type, |ctx| { @@ -307,10 +309,7 @@ fn visit_inline_fragment<'a, S, V>( item: type_name, .. }) = fragment.item.type_condition { - ctx.with_pushed_type( - Some(&Type::NonNullNamed(Cow::Borrowed(type_name))), - visit_fn, - ); + ctx.with_pushed_type(Some(DynType::NonNullNamed(type_name)), visit_fn); } else { visit_fn(ctx); } @@ -331,14 +330,15 @@ fn visit_input_value<'a, S, V>( for (key, value) in fields { let inner_type = ctx .current_input_type_literal() - .and_then(|t| match *t { - Type::NonNullNamed(ref name) | Type::Named(ref name) => { + .and_then(|t| match t { + DynType::NonNullNamed(name) | DynType::Named(name) => { ctx.schema.concrete_type_by_name(name) } _ => None, }) .and_then(|ct| ct.input_field_by_name(&key.item)) - .map(|f| &f.arg_type); + .map(|f| &f.arg_type) + .map(|t| t.as_dyn_type()); ctx.with_pushed_input_type(inner_type, |ctx| { v.enter_object_field(ctx, (key.as_ref(), value.as_ref())); @@ -348,14 +348,14 @@ fn visit_input_value<'a, S, V>( } } 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()) + let inner_type = ctx.current_input_type_literal().and_then(|t| match t { + DynType::List(inner, _) | DynType::NonNullList(inner, _) => { + Some(inner.as_dyn_type()) } _ => None, }); - ctx.with_pushed_input_type(inner_type.as_ref(), |ctx| { + ctx.with_pushed_input_type(inner_type, |ctx| { for value in ls { visit_input_value(v, ctx, value); } diff --git a/juniper_actix/examples/subscription.rs b/juniper_actix/examples/subscription.rs index 17f72d40f..7dd764fd0 100644 --- a/juniper_actix/examples/subscription.rs +++ b/juniper_actix/examples/subscription.rs @@ -18,7 +18,7 @@ use juniper::{ use juniper_actix::{graphiql_handler, graphql_handler, playground_handler, subscriptions}; use juniper_graphql_ws::ConnectionConfig; -type Schema = RootNode<'static, Query, EmptyMutation, Subscription>; +type Schema = RootNode, Subscription>; fn schema() -> Schema { Schema::new(Query, EmptyMutation::::new(), Subscription) diff --git a/juniper_actix/src/lib.rs b/juniper_actix/src/lib.rs index 4e8e63315..d7324fc38 100644 --- a/juniper_actix/src/lib.rs +++ b/juniper_actix/src/lib.rs @@ -42,7 +42,7 @@ where /// Actix Web GraphQL Handler for GET and POST requests pub async fn graphql_handler( - schema: &juniper::RootNode<'static, Query, Mutation, Subscription, S>, + schema: &juniper::RootNode, context: &CtxT, req: HttpRequest, payload: actix_web::web::Payload, @@ -65,7 +65,7 @@ where } /// Actix GraphQL Handler for GET requests pub async fn get_graphql_handler( - schema: &juniper::RootNode<'static, Query, Mutation, Subscription, S>, + schema: &juniper::RootNode, context: &CtxT, req: HttpRequest, ) -> Result @@ -94,7 +94,7 @@ where /// Actix GraphQL Handler for POST requests pub async fn post_graphql_handler( - schema: &juniper::RootNode<'static, Query, Mutation, Subscription, S>, + schema: &juniper::RootNode, context: &CtxT, req: HttpRequest, payload: actix_web::web::Payload, @@ -195,7 +195,7 @@ pub mod subscriptions { pub async fn ws_handler( req: HttpRequest, stream: web::Payload, - schema: Arc>, + schema: Arc>, init: I, ) -> Result where @@ -238,7 +238,7 @@ pub mod subscriptions { pub async fn graphql_ws_handler( req: HttpRequest, stream: web::Payload, - schema: Arc>, + schema: Arc>, init: I, ) -> Result where @@ -306,7 +306,7 @@ pub mod subscriptions { pub async fn graphql_transport_ws_handler( req: HttpRequest, stream: web::Payload, - schema: Arc>, + schema: Arc>, init: I, ) -> Result where @@ -461,8 +461,7 @@ mod tests { use super::*; - type Schema = - juniper::RootNode<'static, Query, EmptyMutation, EmptySubscription>; + type Schema = juniper::RootNode, EmptySubscription>; async fn take_response_body_string(resp: ServiceResponse) -> String { let mut body = resp.into_body(); @@ -856,7 +855,7 @@ mod subscription_tests { } } - type Schema = juniper::RootNode<'static, Query, EmptyMutation, Subscription>; + type Schema = juniper::RootNode, Subscription>; fn subscription( proto: &'static str, diff --git a/juniper_axum/examples/custom.rs b/juniper_axum/examples/custom.rs index ec3bd3c75..b961e4e4b 100644 --- a/juniper_axum/examples/custom.rs +++ b/juniper_axum/examples/custom.rs @@ -21,7 +21,7 @@ use juniper_axum::{ use juniper_graphql_ws::ConnectionConfig; use tokio::net::TcpListener; -type Schema = RootNode<'static, Query, EmptyMutation, Subscription>; +type Schema = RootNode, Subscription>; async fn homepage() -> Html<&'static str> { "

juniper_axum/custom example

\ diff --git a/juniper_axum/examples/simple.rs b/juniper_axum/examples/simple.rs index 0250714a7..f1aa9e09c 100644 --- a/juniper_axum/examples/simple.rs +++ b/juniper_axum/examples/simple.rs @@ -43,7 +43,7 @@ impl Subscription { } } -type Schema = RootNode<'static, Query, EmptyMutation, Subscription>; +type Schema = RootNode; async fn homepage() -> Html<&'static str> { "

juniper_axum/simple example

\ diff --git a/juniper_axum/src/extract.rs b/juniper_axum/src/extract.rs index fe087f672..50dedcead 100644 --- a/juniper_axum/src/extract.rs +++ b/juniper_axum/src/extract.rs @@ -44,7 +44,7 @@ use serde::Deserialize; /// } /// } /// -/// type Schema = RootNode<'static, Query, EmptyMutation, EmptySubscription>; +/// type Schema = RootNode, EmptySubscription>; /// /// let schema = Schema::new( /// Query, diff --git a/juniper_axum/src/lib.rs b/juniper_axum/src/lib.rs index 205669a67..633467102 100644 --- a/juniper_axum/src/lib.rs +++ b/juniper_axum/src/lib.rs @@ -52,7 +52,7 @@ pub use self::subscriptions::{graphql_transport_ws, graphql_ws, ws}; /// } /// } /// -/// type Schema = RootNode<'static, Query, EmptyMutation, EmptySubscription>; +/// type Schema = RootNode, EmptySubscription>; /// /// let schema = Schema::new( /// Query, diff --git a/juniper_axum/src/subscriptions.rs b/juniper_axum/src/subscriptions.rs index cc1ec7d70..4568e6406 100644 --- a/juniper_axum/src/subscriptions.rs +++ b/juniper_axum/src/subscriptions.rs @@ -47,7 +47,7 @@ use juniper_graphql_ws::{graphql_transport_ws, graphql_ws, Init, Schema}; /// use tokio::time::interval; /// use tokio_stream::wrappers::IntervalStream; /// -/// type Schema = RootNode<'static, Query, EmptyMutation, Subscription>; +/// type Schema = RootNode; /// /// #[derive(Clone, Copy, Debug)] /// pub struct Query; @@ -133,7 +133,7 @@ pub fn ws( /// use tokio::time::interval; /// use tokio_stream::wrappers::IntervalStream; /// -/// type Schema = RootNode<'static, Query, EmptyMutation, Subscription>; +/// type Schema = RootNode; /// /// #[derive(Clone, Copy, Debug)] /// pub struct Query; @@ -225,7 +225,7 @@ pub fn graphql_transport_ws( /// use tokio::time::interval; /// use tokio_stream::wrappers::IntervalStream; /// -/// type Schema = RootNode<'static, Query, EmptyMutation, Subscription>; +/// type Schema = RootNode; /// /// #[derive(Clone, Copy, Debug)] /// pub struct Query; @@ -317,7 +317,7 @@ pub fn graphql_ws( /// use tokio::time::interval; /// use tokio_stream::wrappers::IntervalStream; /// -/// type Schema = RootNode<'static, Query, EmptyMutation, Subscription>; +/// type Schema = RootNode; /// /// #[derive(Clone, Copy, Debug)] /// pub struct Query; @@ -419,7 +419,7 @@ where /// use tokio::time::interval; /// use tokio_stream::wrappers::IntervalStream; /// -/// type Schema = RootNode<'static, Query, EmptyMutation, Subscription>; +/// type Schema = RootNode; /// /// #[derive(Clone, Copy, Debug)] /// pub struct Query; @@ -550,7 +550,7 @@ where /// use tokio::time::interval; /// use tokio_stream::wrappers::IntervalStream; /// -/// type Schema = RootNode<'static, Query, EmptyMutation, Subscription>; +/// type Schema = RootNode; /// /// #[derive(Clone, Copy, Debug)] /// pub struct Query; diff --git a/juniper_axum/tests/http_test_suite.rs b/juniper_axum/tests/http_test_suite.rs index 0e13ca2dd..e3548042b 100644 --- a/juniper_axum/tests/http_test_suite.rs +++ b/juniper_axum/tests/http_test_suite.rs @@ -16,7 +16,7 @@ use juniper::{ use juniper_axum::{extract::JuniperRequest, response::JuniperResponse}; use tower_service::Service as _; -type Schema = RootNode<'static, Query, EmptyMutation, EmptySubscription>; +type Schema = RootNode, EmptySubscription>; struct TestApp(Router); diff --git a/juniper_axum/tests/ws_test_suite.rs b/juniper_axum/tests/ws_test_suite.rs index 01bc071e4..81f5c0b21 100644 --- a/juniper_axum/tests/ws_test_suite.rs +++ b/juniper_axum/tests/ws_test_suite.rs @@ -18,7 +18,7 @@ use tokio::{ }; use tokio_tungstenite::{connect_async, tungstenite::Message, MaybeTlsStream, WebSocketStream}; -type Schema = RootNode<'static, Query, EmptyMutation, Subscription>; +type Schema = RootNode, Subscription>; #[derive(Clone)] struct TestApp(Router); diff --git a/juniper_codegen/src/common/deprecation.rs b/juniper_codegen/src/common/deprecation.rs index f213659c4..30d192494 100644 --- a/juniper_codegen/src/common/deprecation.rs +++ b/juniper_codegen/src/common/deprecation.rs @@ -107,10 +107,10 @@ impl Directive { impl ToTokens for Directive { fn to_tokens(&self, into: &mut TokenStream) { - let reason = self - .reason - .as_ref() - .map_or_else(|| quote! { None }, |text| quote! { Some(#text) }); + let reason = self.reason.as_ref().map_or_else( + || quote! { None }, + |text| quote! { Some(::juniper::literal!(#text)) }, + ); quote! { .deprecated(::core::option::Option::#reason) } @@ -134,7 +134,8 @@ mod parse_from_deprecated_attr_test { .into_inner(); assert_eq!( quote! { #desc }.to_string(), - quote! { .deprecated(::core::option::Option::Some("foo")) }.to_string(), + quote! { .deprecated(::core::option::Option::Some(::juniper::literal!("foo"))) } + .to_string(), ); } diff --git a/juniper_codegen/src/common/description.rs b/juniper_codegen/src/common/description.rs index c3c5deaee..67d59292a 100644 --- a/juniper_codegen/src/common/description.rs +++ b/juniper_codegen/src/common/description.rs @@ -102,7 +102,7 @@ impl ToTokens for Description { let desc = &self.0; quote! { - .description(#desc) + .description(::juniper::literal!(#desc)) } .to_tokens(into); } @@ -123,7 +123,7 @@ mod parse_from_doc_attrs_test { .into_inner(); assert_eq!( quote! { #desc }.to_string(), - quote! { .description("foo") }.to_string(), + quote! { .description(::juniper::literal!("foo")) }.to_string(), ); } @@ -139,7 +139,7 @@ mod parse_from_doc_attrs_test { .into_inner(); assert_eq!( quote! { #desc }.to_string(), - quote! { .description("foo\n\nbar") }.to_string(), + quote! { .description(::juniper::literal!("foo\n\nbar")) }.to_string(), ); } diff --git a/juniper_codegen/src/common/field/arg.rs b/juniper_codegen/src/common/field/arg.rs index 19fc184cf..fdc036fab 100644 --- a/juniper_codegen/src/common/field/arg.rs +++ b/juniper_codegen/src/common/field/arg.rs @@ -303,10 +303,10 @@ impl OnMethod { let method = if let Some(val) = &arg.default { quote_spanned! { val.span() => - .arg_with_default::<#ty>(#name, &#val, info) + .arg_with_default::<#ty>(::juniper::literal!(#name), &#val, info) } } else { - quote! { .arg::<#ty>(#name, info) } + quote! { .arg::<#ty>(::juniper::literal!(#name), info) } }; Some(quote! { .argument(registry #method #description) }) diff --git a/juniper_codegen/src/common/field/mod.rs b/juniper_codegen/src/common/field/mod.rs index 092967f72..cdba63eef 100644 --- a/juniper_codegen/src/common/field/mod.rs +++ b/juniper_codegen/src/common/field/mod.rs @@ -299,7 +299,7 @@ impl Definition { .flat_map(|args| args.iter().filter_map(MethodArgument::method_meta_tokens)); quote! { - registry.field_convert::<#ty, _, Self::Context>(#name, info) + registry.field_convert::<#ty, _, Self::Context>(::juniper::literal!(#name), info) #( #args )* #description #deprecated diff --git a/juniper_codegen/src/graphql_enum/mod.rs b/juniper_codegen/src/graphql_enum/mod.rs index 048f6373e..0bbe64ba0 100644 --- a/juniper_codegen/src/graphql_enum/mod.rs +++ b/juniper_codegen/src/graphql_enum/mod.rs @@ -438,7 +438,7 @@ impl Definition { let v_deprecation = &v.deprecated; quote! { - ::juniper::meta::EnumValue::new(#v_name) + ::juniper::meta::EnumValue::new(::juniper::literal!(#v_name)) #v_description #v_deprecation } @@ -452,15 +452,14 @@ impl Definition { { fn name( _ : &Self::TypeInfo, - ) -> ::core::option::Option<&'static ::core::primitive::str> { - ::core::option::Option::Some(#name) + ) -> ::core::option::Option<::juniper::ArcStr> { + ::core::option::Option::Some(::juniper::literal!(#name)) } - fn meta<'r>( + fn meta( info: &Self::TypeInfo, - registry: &mut ::juniper::Registry<'r, #scalar> - ) -> ::juniper::meta::MetaType<'r, #scalar> - where #scalar: 'r, + registry: &mut ::juniper::Registry<#scalar> + ) -> ::juniper::meta::MetaType<#scalar> { let variants = [#( #variants_meta ),*]; @@ -516,7 +515,7 @@ impl Definition { fn type_name<'__i>( &self, info: &'__i Self::TypeInfo, - ) -> ::core::option::Option<&'__i ::core::primitive::str> { + ) -> ::core::option::Option<::juniper::ArcStr> { >::name(info) } diff --git a/juniper_codegen/src/graphql_input_object/mod.rs b/juniper_codegen/src/graphql_input_object/mod.rs index baa091a0b..a713e047d 100644 --- a/juniper_codegen/src/graphql_input_object/mod.rs +++ b/juniper_codegen/src/graphql_input_object/mod.rs @@ -463,9 +463,9 @@ impl Definition { (!f.ignored).then(|| { let arg = if let Some(default) = &f.default { - quote! { .arg_with_default::<#ty>(#name, &#default, info) } + quote! { .arg_with_default::<#ty>(::juniper::literal!(#name), &#default, info) } } else { - quote! { .arg::<#ty>(#name, info) } + quote! { .arg::<#ty>(::juniper::literal!(#name), info) } }; let description = &f.description; @@ -481,16 +481,14 @@ impl Definition { { fn name( _: &Self::TypeInfo, - ) -> ::core::option::Option<&'static ::core::primitive::str> { - ::core::option::Option::Some(#name) + ) -> ::core::option::Option<::juniper::ArcStr> { + ::core::option::Option::Some(::juniper::literal!(#name)) } - fn meta<'r>( + fn meta( info: &Self::TypeInfo, - registry: &mut ::juniper::Registry<'r, #scalar>, - ) -> ::juniper::meta::MetaType<'r, #scalar> - where - #scalar: 'r, + registry: &mut ::juniper::Registry<#scalar>, + ) -> ::juniper::meta::MetaType<#scalar> { let fields = [#( #fields ),*]; registry @@ -529,7 +527,7 @@ impl Definition { fn type_name<'__i>( &self, info: &'__i Self::TypeInfo, - ) -> ::core::option::Option<&'__i ::core::primitive::str> { + ) -> ::core::option::Option<::juniper::ArcStr> { >::name(info) } } diff --git a/juniper_codegen/src/graphql_interface/mod.rs b/juniper_codegen/src/graphql_interface/mod.rs index c618af84f..4a109975b 100644 --- a/juniper_codegen/src/graphql_interface/mod.rs +++ b/juniper_codegen/src/graphql_interface/mod.rs @@ -719,15 +719,14 @@ impl Definition { { fn name( _ : &Self::TypeInfo, - ) -> ::core::option::Option<&'static ::core::primitive::str> { - ::core::option::Option::Some(#name) + ) -> ::core::option::Option<::juniper::ArcStr> { + ::core::option::Option::Some(::juniper::literal!(#name)) } - fn meta<'r>( + fn meta( info: &Self::TypeInfo, - registry: &mut ::juniper::Registry<'r, #scalar> - ) -> ::juniper::meta::MetaType<'r, #scalar> - where #scalar: 'r, + registry: &mut ::juniper::Registry<#scalar> + ) -> ::juniper::meta::MetaType<#scalar> { // Ensure all implementer types are registered. #( let _ = registry.get_type::<#implemented_for>(info); )* @@ -791,7 +790,7 @@ impl Definition { fn type_name<'__i>( &self, info: &'__i Self::TypeInfo, - ) -> ::core::option::Option<&'__i ::core::primitive::str> { + ) -> ::core::option::Option<::juniper::ArcStr> { >::name(info) } diff --git a/juniper_codegen/src/graphql_object/mod.rs b/juniper_codegen/src/graphql_object/mod.rs index 96e18bb89..533a46063 100644 --- a/juniper_codegen/src/graphql_object/mod.rs +++ b/juniper_codegen/src/graphql_object/mod.rs @@ -459,15 +459,14 @@ impl Definition { { fn name( _ : &Self::TypeInfo, - ) -> ::core::option::Option<&'static ::core::primitive::str> { - ::core::option::Option::Some(#name) + ) -> ::core::option::Option<::juniper::ArcStr> { + ::core::option::Option::Some(::juniper::literal!(#name)) } - fn meta<'r>( + fn meta( info: &Self::TypeInfo, - registry: &mut ::juniper::Registry<'r, #scalar> - ) -> ::juniper::meta::MetaType<'r, #scalar> - where #scalar: 'r, + registry: &mut ::juniper::Registry<#scalar> + ) -> ::juniper::meta::MetaType<#scalar> { let fields = [ #( #fields_meta, )* @@ -788,7 +787,7 @@ impl Definition { fn type_name<'__i>( &self, info: &'__i Self::TypeInfo, - ) -> ::core::option::Option<&'__i ::core::primitive::str> { + ) -> ::core::option::Option<::juniper::ArcStr> { >::name(info) } diff --git a/juniper_codegen/src/graphql_scalar/mod.rs b/juniper_codegen/src/graphql_scalar/mod.rs index e296b05ae..6c3b47c55 100644 --- a/juniper_codegen/src/graphql_scalar/mod.rs +++ b/juniper_codegen/src/graphql_scalar/mod.rs @@ -363,7 +363,7 @@ impl Definition { let description = &self.description; let specified_by_url = self.specified_by_url.as_ref().map(|url| { let url_lit = url.as_str(); - quote! { .specified_by_url(#url_lit) } + quote! { .specified_by_url(::juniper::literal!(#url_lit)) } }); let (ty, generics) = self.impl_self_and_generics(false); @@ -376,16 +376,14 @@ impl Definition { { fn name( _: &Self::TypeInfo, - ) -> ::core::option::Option<&'static ::core::primitive::str> { - ::core::option::Option::Some(#name) + ) -> ::core::option::Option<::juniper::ArcStr> { + ::core::option::Option::Some(::juniper::literal!(#name)) } - fn meta<'r>( + fn meta( info: &Self::TypeInfo, - registry: &mut ::juniper::Registry<'r, #scalar>, - ) -> ::juniper::meta::MetaType<'r, #scalar> - where - #scalar: 'r, + registry: &mut ::juniper::Registry<#scalar>, + ) -> ::juniper::meta::MetaType<#scalar> { registry.build_scalar_type::(info) #description @@ -420,7 +418,7 @@ impl Definition { fn type_name<'i>( &self, info: &'i Self::TypeInfo, - ) -> ::core::option::Option<&'i ::core::primitive::str> { + ) -> ::core::option::Option<::juniper::ArcStr> { >::name(info) } diff --git a/juniper_codegen/src/graphql_subscription/mod.rs b/juniper_codegen/src/graphql_subscription/mod.rs index 47af4b30a..b81cdf5ef 100644 --- a/juniper_codegen/src/graphql_subscription/mod.rs +++ b/juniper_codegen/src/graphql_subscription/mod.rs @@ -52,7 +52,7 @@ impl Definition { fn type_name<'__i>( &self, info: &'__i Self::TypeInfo, - ) -> ::core::option::Option<&'__i ::core::primitive::str> { + ) -> ::core::option::Option<::juniper::ArcStr> { >::name(info) } diff --git a/juniper_codegen/src/graphql_union/mod.rs b/juniper_codegen/src/graphql_union/mod.rs index a89976234..ceee876ea 100644 --- a/juniper_codegen/src/graphql_union/mod.rs +++ b/juniper_codegen/src/graphql_union/mod.rs @@ -475,15 +475,14 @@ impl Definition { { fn name( _ : &Self::TypeInfo, - ) -> ::core::option::Option<&'static ::core::primitive::str> { - ::core::option::Option::Some(#name) + ) -> ::core::option::Option<::juniper::ArcStr> { + ::core::option::Option::Some(::juniper::literal!(#name)) } - fn meta<'r>( + fn meta( info: &Self::TypeInfo, - registry: &mut ::juniper::Registry<'r, #scalar> - ) -> ::juniper::meta::MetaType<'r, #scalar> - where #scalar: 'r, + registry: &mut ::juniper::Registry<#scalar> + ) -> ::juniper::meta::MetaType<#scalar> { let types = [ #( registry.get_type::<#variant_tys>(info), )* @@ -530,7 +529,7 @@ impl Definition { fn type_name<'__i>( &self, info: &'__i Self::TypeInfo, - ) -> ::core::option::Option<&'__i ::core::primitive::str> { + ) -> ::core::option::Option<::juniper::ArcStr> { >::name(info) } diff --git a/juniper_graphql_ws/src/graphql_transport_ws/mod.rs b/juniper_graphql_ws/src/graphql_transport_ws/mod.rs index c08cf0214..7a2b06c32 100644 --- a/juniper_graphql_ws/src/graphql_transport_ws/mod.rs +++ b/juniper_graphql_ws/src/graphql_transport_ws/mod.rs @@ -677,7 +677,7 @@ mod test { type ClientMessage = super::ClientMessage; type ServerMessage = super::ServerMessage; - fn new_test_schema() -> Arc, Subscription>> { + fn new_test_schema() -> Arc, Subscription>> { Arc::new(RootNode::new(Query, EmptyMutation::new(), Subscription)) } diff --git a/juniper_graphql_ws/src/graphql_ws/mod.rs b/juniper_graphql_ws/src/graphql_ws/mod.rs index 2c99a324e..ced29a3d4 100644 --- a/juniper_graphql_ws/src/graphql_ws/mod.rs +++ b/juniper_graphql_ws/src/graphql_ws/mod.rs @@ -613,7 +613,7 @@ mod test { type ClientMessage = super::ClientMessage; type ServerMessage = super::ServerMessage; - fn new_test_schema() -> Arc, Subscription>> { + fn new_test_schema() -> Arc, Subscription>> { Arc::new(RootNode::new(Query, EmptyMutation::new(), Subscription)) } diff --git a/juniper_graphql_ws/src/schema.rs b/juniper_graphql_ws/src/schema.rs index 43b7f94b4..20769faf5 100644 --- a/juniper_graphql_ws/src/schema.rs +++ b/juniper_graphql_ws/src/schema.rs @@ -41,7 +41,7 @@ pub trait Schema: Unpin + Clone + Send + Sync + 'static { /// Returns the root node for the schema. fn root_node( &self, - ) -> &RootNode<'static, Self::Query, Self::Mutation, Self::Subscription, Self::ScalarValue>; + ) -> &RootNode; } /// This exists as a work-around for this issue: https://github.com/rust-lang/rust/issues/64552 @@ -50,7 +50,7 @@ pub trait Schema: Unpin + Clone + Send + Sync + 'static { // TODO: Remove this once that issue is resolved. #[doc(hidden)] pub struct ArcSchema( - pub Arc>, + pub Arc>, ) where QueryT: GraphQLTypeAsync + Send + 'static, @@ -100,13 +100,13 @@ where type SubscriptionTypeInfo = SubscriptionT::TypeInfo; type Subscription = SubscriptionT; - fn root_node(&self) -> &RootNode<'static, QueryT, MutationT, SubscriptionT, S> { + fn root_node(&self) -> &RootNode { &self.0 } } impl Schema - for Arc> + for Arc> where QueryT: GraphQLTypeAsync + Send + 'static, QueryT::TypeInfo: Send + Sync, @@ -126,7 +126,7 @@ where type SubscriptionTypeInfo = SubscriptionT::TypeInfo; type Subscription = SubscriptionT; - fn root_node(&self) -> &RootNode<'static, QueryT, MutationT, SubscriptionT, S> { + fn root_node(&self) -> &RootNode { self } } diff --git a/juniper_hyper/src/lib.rs b/juniper_hyper/src/lib.rs index d39696301..31cf480b9 100644 --- a/juniper_hyper/src/lib.rs +++ b/juniper_hyper/src/lib.rs @@ -16,7 +16,7 @@ use serde_json::error::Error as SerdeError; use url::form_urlencoded; pub async fn graphql_sync( - root_node: Arc>, + root_node: Arc>, context: Arc, req: Request, ) -> Response @@ -37,7 +37,7 @@ where } pub async fn graphql( - root_node: Arc>, + root_node: Arc>, context: Arc, req: Request, ) -> Response @@ -150,7 +150,7 @@ fn render_error(err: GraphQLRequestError) -> Response { } async fn execute_request_sync( - root_node: Arc>, + root_node: Arc>, context: Arc, request: GraphQLBatchRequest, ) -> Response @@ -181,7 +181,7 @@ where } async fn execute_request( - root_node: Arc>, + root_node: Arc>, context: Arc, request: GraphQLBatchRequest, ) -> Response diff --git a/juniper_rocket/examples/simple.rs b/juniper_rocket/examples/simple.rs index f3a6d905a..1fd543ef2 100644 --- a/juniper_rocket/examples/simple.rs +++ b/juniper_rocket/examples/simple.rs @@ -4,7 +4,7 @@ use juniper::{ }; use rocket::{response::content::RawHtml, routes, State}; -type Schema = RootNode<'static, Query, EmptyMutation, EmptySubscription>; +type Schema = RootNode, EmptySubscription>; #[rocket::get("/")] async fn homepage() -> RawHtml<&'static str> { diff --git a/juniper_rocket/src/lib.rs b/juniper_rocket/src/lib.rs index 934047d17..267a66beb 100644 --- a/juniper_rocket/src/lib.rs +++ b/juniper_rocket/src/lib.rs @@ -31,7 +31,7 @@ use juniper::{ /// }; /// use rocket::{routes, State}; /// -/// type Schema = RootNode<'static, Query, EmptyMutation, EmptySubscription>; +/// type Schema = RootNode, EmptySubscription>; /// /// // GET request accepts query parameters like these: /// // ?query= @@ -166,7 +166,7 @@ where /// Asynchronously execute an incoming GraphQL query. pub async fn execute( &self, - root_node: &RootNode<'_, QueryT, MutationT, SubscriptionT, S>, + root_node: &RootNode, context: &CtxT, ) -> GraphQLResponse where @@ -212,7 +212,7 @@ impl GraphQLResponse { /// # use juniper::tests::fixtures::starwars::schema::{Database, Query}; /// # use juniper::{EmptyMutation, EmptySubscription, FieldError, RootNode, Value}; /// # - /// # type Schema = RootNode<'static, Query, EmptyMutation, EmptySubscription>; + /// # type Schema = RootNode, EmptySubscription>; /// # /// #[rocket::get("/graphql?")] /// fn get_graphql_handler( diff --git a/juniper_rocket/tests/http_test_suite.rs b/juniper_rocket/tests/http_test_suite.rs index 3e7ca823d..5398bb0c2 100644 --- a/juniper_rocket/tests/http_test_suite.rs +++ b/juniper_rocket/tests/http_test_suite.rs @@ -12,7 +12,7 @@ use rocket::{ post, routes, Build, Rocket, State, }; -type Schema = RootNode<'static, Query, EmptyMutation, EmptySubscription>; +type Schema = RootNode, EmptySubscription>; fn bootstrap_rocket() -> Rocket { Rocket::build().manage(Database::new()).manage(Schema::new( diff --git a/juniper_subscriptions/examples/basic.rs b/juniper_subscriptions/examples/basic.rs index df5236744..aa92f703c 100644 --- a/juniper_subscriptions/examples/basic.rs +++ b/juniper_subscriptions/examples/basic.rs @@ -42,7 +42,7 @@ impl Subscription { } } -type Schema = RootNode<'static, Query, EmptyMutation, Subscription>; +type Schema = RootNode, Subscription>; fn schema() -> Schema { Schema::new(Query, EmptyMutation::new(), Subscription) diff --git a/juniper_subscriptions/src/lib.rs b/juniper_subscriptions/src/lib.rs index 3d5d77bb3..1ff15aad8 100644 --- a/juniper_subscriptions/src/lib.rs +++ b/juniper_subscriptions/src/lib.rs @@ -17,7 +17,7 @@ use juniper::{ /// Simple [`SubscriptionCoordinator`] implementation: /// - contains the schema /// - handles subscription start -pub struct Coordinator<'a, QueryT, MutationT, SubscriptionT, CtxT, S> +pub struct Coordinator where QueryT: GraphQLTypeAsync + Send, QueryT::TypeInfo: Send + Sync, @@ -28,11 +28,11 @@ where CtxT: Sync, S: ScalarValue + Send + Sync, { - root_node: juniper::RootNode<'a, QueryT, MutationT, SubscriptionT, S>, + root_node: juniper::RootNode, } -impl<'a, QueryT, MutationT, SubscriptionT, CtxT, S> - Coordinator<'a, QueryT, MutationT, SubscriptionT, CtxT, S> +impl + Coordinator where QueryT: GraphQLTypeAsync + Send, QueryT::TypeInfo: Send + Sync, @@ -44,13 +44,13 @@ where S: ScalarValue + Send + Sync, { /// Builds new [`Coordinator`] with specified `root_node` - pub fn new(root_node: juniper::RootNode<'a, QueryT, MutationT, SubscriptionT, S>) -> Self { + pub fn new(root_node: juniper::RootNode) -> Self { Self { root_node } } } impl<'a, QueryT, MutationT, SubscriptionT, CtxT, S> SubscriptionCoordinator<'a, CtxT, S> - for Coordinator<'a, QueryT, MutationT, SubscriptionT, CtxT, S> + for Coordinator where QueryT: GraphQLTypeAsync + Send, QueryT::TypeInfo: Send + Sync, diff --git a/juniper_warp/examples/subscription.rs b/juniper_warp/examples/subscription.rs index 8ceb9049a..e4a18a336 100644 --- a/juniper_warp/examples/subscription.rs +++ b/juniper_warp/examples/subscription.rs @@ -132,7 +132,7 @@ impl Subscription { } } -type Schema = RootNode<'static, Query, EmptyMutation, Subscription>; +type Schema = RootNode, Subscription>; fn schema() -> Schema { Schema::new(Query, EmptyMutation::new(), Subscription) diff --git a/juniper_warp/src/lib.rs b/juniper_warp/src/lib.rs index f0f5bda0d..3c9d0d3e1 100644 --- a/juniper_warp/src/lib.rs +++ b/juniper_warp/src/lib.rs @@ -149,7 +149,7 @@ use self::response::JuniperResponse; /// /// [1]: https://github.com/seanmonstar/warp/issues/388#issuecomment-576453485 pub fn make_graphql_filter( - schema: impl Into>>, + schema: impl Into>>, context_extractor: impl Filter + Send + Sync + 'static, ) -> impl Filter + Clone + Send where @@ -192,7 +192,7 @@ where /// /// [1]: GraphQLBatchRequest::execute_sync pub fn make_graphql_filter_sync( - schema: impl Into>>, + schema: impl Into>>, context_extractor: impl Filter + Send + Sync + 'static, ) -> impl Filter + Clone + Send where @@ -232,7 +232,7 @@ where /// `context`. async fn graphql_handler( req: GraphQLBatchRequest, - schema: Arc>, + schema: Arc>, context: CtxT, ) -> reply::Response where @@ -254,7 +254,7 @@ where /// [1]: GraphQLBatchRequest::execute_sync async fn graphql_handler_sync( req: GraphQLBatchRequest, - schema: Arc>, + schema: Arc>, context: CtxT, ) -> reply::Response where @@ -472,12 +472,8 @@ mod tests { #[tokio::test] async fn post_json() { - type Schema = juniper::RootNode< - 'static, - Query, - EmptyMutation, - EmptySubscription, - >; + type Schema = + juniper::RootNode, EmptySubscription>; let schema = Schema::new(Query, EmptyMutation::new(), EmptySubscription::new()); @@ -522,12 +518,8 @@ mod tests { } } - type Schema = juniper::RootNode< - 'static, - Query, - EmptyMutation, - EmptySubscription, - >; + type Schema = + juniper::RootNode, EmptySubscription>; let schema = Schema::new(Query, EmptyMutation::new(), EmptySubscription::new()); @@ -570,12 +562,8 @@ mod tests { #[tokio::test] async fn batch_requests() { - type Schema = juniper::RootNode< - 'static, - Query, - EmptyMutation, - EmptySubscription, - >; + type Schema = + juniper::RootNode, EmptySubscription>; let schema = Schema::new(Query, EmptyMutation::new(), EmptySubscription::new()); diff --git a/juniper_warp/src/subscriptions.rs b/juniper_warp/src/subscriptions.rs index 6511c235f..ba914d264 100644 --- a/juniper_warp/src/subscriptions.rs +++ b/juniper_warp/src/subscriptions.rs @@ -177,7 +177,7 @@ impl From for Error { /// [new]: https://github.com/enisdenjo/graphql-ws/blob/v5.14.0/PROTOCOL.md /// [old]: https://github.com/apollographql/subscriptions-transport-ws/blob/v0.11.0/PROTOCOL.md pub fn make_ws_filter( - schema: impl Into>>, + schema: impl Into>>, init: I, ) -> BoxedFilter<(impl Reply,)> where @@ -239,7 +239,7 @@ where /// [old]: https://github.com/apollographql/subscriptions-transport-ws/blob/v0.11.0/PROTOCOL.md pub async fn serve_graphql_ws( websocket: warp::ws::WebSocket, - root_node: Arc>, + root_node: Arc>, init: I, ) -> Result<(), Error> where @@ -286,7 +286,7 @@ where /// [new]: https://github.com/enisdenjo/graphql-ws/blob/v5.14.0/PROTOCOL.md pub async fn serve_graphql_transport_ws( websocket: warp::ws::WebSocket, - root_node: Arc>, + root_node: Arc>, init: I, ) -> Result<(), Error> where diff --git a/tests/codegen/fail/input-object/derive_incompatible_field_type.stderr b/tests/codegen/fail/input-object/derive_incompatible_field_type.stderr index 21bf40147..beae95471 100644 --- a/tests/codegen/fail/input-object/derive_incompatible_field_type.stderr +++ b/tests/codegen/fail/input-object/derive_incompatible_field_type.stderr @@ -34,14 +34,14 @@ error[E0277]: the trait bound `ObjectA: FromInputValue<__S>` is not satisfied > > and $N others -note: required by a bound in `Registry::<'r, S>::arg` +note: required by a bound in `Registry::::arg` --> $WORKSPACE/juniper/src/executor/mod.rs | - | pub fn arg(&mut self, name: &str, info: &T::TypeInfo) -> Argument<'r, S> + | pub fn arg(&mut self, name: ArcStr, info: &T::TypeInfo) -> Argument | --- required by a bound in this associated function | where | T: GraphQLType + FromInputValue, - | ^^^^^^^^^^^^^^^^^ required by this bound in `Registry::<'r, S>::arg` + | ^^^^^^^^^^^^^^^^^ required by this bound in `Registry::::arg` error[E0277]: the trait bound `ObjectA: FromInputValue<__S>` is not satisfied --> fail/input-object/derive_incompatible_field_type.rs:8:10 diff --git a/tests/codegen/fail/interface/struct/attr_field_non_output_return_type.stderr b/tests/codegen/fail/interface/struct/attr_field_non_output_return_type.stderr index cd32c75c9..1e53e2f4c 100644 --- a/tests/codegen/fail/interface/struct/attr_field_non_output_return_type.stderr +++ b/tests/codegen/fail/interface/struct/attr_field_non_output_return_type.stderr @@ -8,9 +8,9 @@ error[E0277]: the trait bound `ObjB: IsOutputType<__S>` is not satisfied > > > + > > as IsOutputType> > > - > and $N others diff --git a/tests/codegen/fail/interface/struct/derive_field_non_output_return_type.stderr b/tests/codegen/fail/interface/struct/derive_field_non_output_return_type.stderr index d8b5b7333..d25198c1f 100644 --- a/tests/codegen/fail/interface/struct/derive_field_non_output_return_type.stderr +++ b/tests/codegen/fail/interface/struct/derive_field_non_output_return_type.stderr @@ -8,9 +8,9 @@ error[E0277]: the trait bound `ObjB: IsOutputType<__S>` is not satisfied > > > + > > as IsOutputType> > > - > and $N others diff --git a/tests/codegen/fail/interface/trait/argument_non_input_type.stderr b/tests/codegen/fail/interface/trait/argument_non_input_type.stderr index a6af9595d..bf804ee36 100644 --- a/tests/codegen/fail/interface/trait/argument_non_input_type.stderr +++ b/tests/codegen/fail/interface/trait/argument_non_input_type.stderr @@ -34,11 +34,11 @@ error[E0277]: the trait bound `ObjA: FromInputValue<__S>` is not satisfied > > and $N others -note: required by a bound in `Registry::<'r, S>::arg` +note: required by a bound in `Registry::::arg` --> $WORKSPACE/juniper/src/executor/mod.rs | - | pub fn arg(&mut self, name: &str, info: &T::TypeInfo) -> Argument<'r, S> + | pub fn arg(&mut self, name: ArcStr, info: &T::TypeInfo) -> Argument | --- required by a bound in this associated function | where | T: GraphQLType + FromInputValue, - | ^^^^^^^^^^^^^^^^^ required by this bound in `Registry::<'r, S>::arg` + | ^^^^^^^^^^^^^^^^^ required by this bound in `Registry::::arg` diff --git a/tests/codegen/fail/interface/trait/field_non_output_return_type.stderr b/tests/codegen/fail/interface/trait/field_non_output_return_type.stderr index ca0c5593d..ee216a5bd 100644 --- a/tests/codegen/fail/interface/trait/field_non_output_return_type.stderr +++ b/tests/codegen/fail/interface/trait/field_non_output_return_type.stderr @@ -8,9 +8,9 @@ error[E0277]: the trait bound `ObjB: IsOutputType<__S>` is not satisfied > > > + > > as IsOutputType> > > - > and $N others diff --git a/tests/codegen/fail/object/argument_non_input_type.stderr b/tests/codegen/fail/object/argument_non_input_type.stderr index 323928ff3..5b25ca80b 100644 --- a/tests/codegen/fail/object/argument_non_input_type.stderr +++ b/tests/codegen/fail/object/argument_non_input_type.stderr @@ -34,14 +34,14 @@ error[E0277]: the trait bound `ObjA: FromInputValue<__S>` is not satisfied > > and $N others -note: required by a bound in `Registry::<'r, S>::arg` +note: required by a bound in `Registry::::arg` --> $WORKSPACE/juniper/src/executor/mod.rs | - | pub fn arg(&mut self, name: &str, info: &T::TypeInfo) -> Argument<'r, S> + | pub fn arg(&mut self, name: ArcStr, info: &T::TypeInfo) -> Argument | --- required by a bound in this associated function | where | T: GraphQLType + FromInputValue, - | ^^^^^^^^^^^^^^^^^ required by this bound in `Registry::<'r, S>::arg` + | ^^^^^^^^^^^^^^^^^ required by this bound in `Registry::::arg` error[E0277]: the trait bound `ObjA: FromInputValue<__S>` is not satisfied --> fail/object/argument_non_input_type.rs:10:1 diff --git a/tests/codegen/fail/object/attr_field_non_output_return_type.stderr b/tests/codegen/fail/object/attr_field_non_output_return_type.stderr index 1c775851b..19974c7f9 100644 --- a/tests/codegen/fail/object/attr_field_non_output_return_type.stderr +++ b/tests/codegen/fail/object/attr_field_non_output_return_type.stderr @@ -9,8 +9,8 @@ error[E0277]: the trait bound `ObjB: IsOutputType<__S>` is not satisfied > > > + > as IsOutputType> > > - > and $N others diff --git a/tests/codegen/fail/object/derive_field_non_output_return_type.stderr b/tests/codegen/fail/object/derive_field_non_output_return_type.stderr index ad431c534..7602b75f9 100644 --- a/tests/codegen/fail/object/derive_field_non_output_return_type.stderr +++ b/tests/codegen/fail/object/derive_field_non_output_return_type.stderr @@ -8,9 +8,9 @@ error[E0277]: the trait bound `ObjB: IsOutputType<__S>` is not satisfied > > > + > > as IsOutputType> > > - > and $N others diff --git a/tests/codegen/fail/subscription/argument_non_input_type.stderr b/tests/codegen/fail/subscription/argument_non_input_type.stderr index 3022c6b4f..0a55faaf9 100644 --- a/tests/codegen/fail/subscription/argument_non_input_type.stderr +++ b/tests/codegen/fail/subscription/argument_non_input_type.stderr @@ -42,14 +42,14 @@ error[E0277]: the trait bound `ObjA: FromInputValue<__S>` is not satisfied > > and $N others -note: required by a bound in `Registry::<'r, S>::arg` +note: required by a bound in `Registry::::arg` --> $WORKSPACE/juniper/src/executor/mod.rs | - | pub fn arg(&mut self, name: &str, info: &T::TypeInfo) -> Argument<'r, S> + | pub fn arg(&mut self, name: ArcStr, info: &T::TypeInfo) -> Argument | --- required by a bound in this associated function | where | T: GraphQLType + FromInputValue, - | ^^^^^^^^^^^^^^^^^ required by this bound in `Registry::<'r, S>::arg` + | ^^^^^^^^^^^^^^^^^ required by this bound in `Registry::::arg` error[E0277]: the trait bound `ObjA: FromInputValue<__S>` is not satisfied --> fail/subscription/argument_non_input_type.rs:15:1 diff --git a/tests/codegen/fail/subscription/field_non_output_return_type.stderr b/tests/codegen/fail/subscription/field_non_output_return_type.stderr index 5a47e2c7f..8fa5bfff2 100644 --- a/tests/codegen/fail/subscription/field_non_output_return_type.stderr +++ b/tests/codegen/fail/subscription/field_non_output_return_type.stderr @@ -9,8 +9,8 @@ error[E0277]: the trait bound `ObjB: IsOutputType<__S>` is not satisfied > > > + > as IsOutputType> > > - > and $N others diff --git a/tests/codegen/fail/union/enum_non_object_variant.stderr b/tests/codegen/fail/union/enum_non_object_variant.stderr index c0356aa36..1bc95b3b1 100644 --- a/tests/codegen/fail/union/enum_non_object_variant.stderr +++ b/tests/codegen/fail/union/enum_non_object_variant.stderr @@ -6,11 +6,11 @@ error[E0277]: the trait bound `Test: GraphQLObject<__S>` is not satisfied | = help: the following other types implement trait `GraphQLObject`: as GraphQLObject> - as GraphQLObject> - as GraphQLObject> + as GraphQLObject> + as GraphQLObject> > - as GraphQLObject> + as GraphQLObject> as GraphQLObject> - as GraphQLObject> + as GraphQLObject> as GraphQLObject> <&T as GraphQLObject> diff --git a/tests/codegen/fail/union/struct_non_object_variant.stderr b/tests/codegen/fail/union/struct_non_object_variant.stderr index 934344c60..694553747 100644 --- a/tests/codegen/fail/union/struct_non_object_variant.stderr +++ b/tests/codegen/fail/union/struct_non_object_variant.stderr @@ -6,11 +6,11 @@ error[E0277]: the trait bound `Test: GraphQLObject<__S>` is not satisfied | = help: the following other types implement trait `GraphQLObject`: as GraphQLObject> - as GraphQLObject> - as GraphQLObject> + as GraphQLObject> + as GraphQLObject> > - as GraphQLObject> + as GraphQLObject> as GraphQLObject> - as GraphQLObject> + as GraphQLObject> as GraphQLObject> <&T as GraphQLObject> diff --git a/tests/codegen/fail/union/trait_non_object_variant.stderr b/tests/codegen/fail/union/trait_non_object_variant.stderr index 602147594..98ef08320 100644 --- a/tests/codegen/fail/union/trait_non_object_variant.stderr +++ b/tests/codegen/fail/union/trait_non_object_variant.stderr @@ -6,11 +6,11 @@ error[E0277]: the trait bound `Test: GraphQLObject<__S>` is not satisfied | = help: the following other types implement trait `GraphQLObject`: as GraphQLObject> - as GraphQLObject> - as GraphQLObject> + as GraphQLObject> + as GraphQLObject> > - as GraphQLObject> + as GraphQLObject> as GraphQLObject> - as GraphQLObject> + as GraphQLObject> as GraphQLObject> <&T as GraphQLObject> diff --git a/tests/integration/tests/codegen_subscription_attr.rs b/tests/integration/tests/codegen_subscription_attr.rs index e9ab167a2..f846dbfb1 100644 --- a/tests/integration/tests/codegen_subscription_attr.rs +++ b/tests/integration/tests/codegen_subscription_attr.rs @@ -30,25 +30,25 @@ impl Query { } } -fn schema<'q, C, Qry, Sub>( +fn schema( query_root: Qry, subscription_root: Sub, -) -> RootNode<'q, Qry, EmptyMutation, Sub> +) -> RootNode, Sub> where - Qry: GraphQLType + 'q, - Sub: GraphQLType + 'q, + Qry: GraphQLType, + Sub: GraphQLType, { RootNode::new(query_root, EmptyMutation::::new(), subscription_root) } -fn schema_with_scalar<'q, S, C, Qry, Sub>( +fn schema_with_scalar( query_root: Qry, subscription_root: Sub, -) -> RootNode<'q, Qry, EmptyMutation, Sub, S> +) -> RootNode, Sub, S> where - Qry: GraphQLType + 'q, - Sub: GraphQLType + 'q, - S: ScalarValue + 'q, + Qry: GraphQLType, + Sub: GraphQLType, + S: ScalarValue, { RootNode::new_with_scalar_value(query_root, EmptyMutation::::new(), subscription_root) } diff --git a/tests/integration/tests/common/mod.rs b/tests/integration/tests/common/mod.rs index aae6a04c0..1ce8b4417 100644 --- a/tests/integration/tests/common/mod.rs +++ b/tests/integration/tests/common/mod.rs @@ -11,11 +11,9 @@ pub mod util { GraphQLError, GraphQLType, RootNode, ScalarValue, Value, ValuesStream, }; - pub fn schema<'q, C, Q>( - query_root: Q, - ) -> RootNode<'q, Q, EmptyMutation, EmptySubscription> + pub fn schema(query_root: Q) -> RootNode, EmptySubscription> where - Q: GraphQLType + 'q, + Q: GraphQLType, { RootNode::new( query_root, @@ -24,12 +22,12 @@ pub mod util { ) } - pub fn schema_with_scalar<'q, S, C, Q>( + pub fn schema_with_scalar( query_root: Q, - ) -> RootNode<'q, Q, EmptyMutation, EmptySubscription, S> + ) -> RootNode, EmptySubscription, S> where - Q: GraphQLType + 'q, - S: ScalarValue + 'q, + Q: GraphQLType, + S: ScalarValue, { RootNode::new_with_scalar_value( query_root, diff --git a/tests/integration/tests/cve_2022_31173.rs b/tests/integration/tests/cve_2022_31173.rs index 332306a32..244145518 100644 --- a/tests/integration/tests/cve_2022_31173.rs +++ b/tests/integration/tests/cve_2022_31173.rs @@ -29,7 +29,7 @@ impl Query { } } -type Schema = juniper::RootNode<'static, Query, EmptyMutation, EmptySubscription>; +type Schema = juniper::RootNode; #[tokio::test] async fn test() { diff --git a/tests/integration/tests/explicit_null.rs b/tests/integration/tests/explicit_null.rs index 4c65f66c1..2aea8f5f4 100644 --- a/tests/integration/tests/explicit_null.rs +++ b/tests/integration/tests/explicit_null.rs @@ -25,7 +25,7 @@ impl Query { } } -type Schema = juniper::RootNode<'static, Query, EmptyMutation, EmptySubscription>; +type Schema = juniper::RootNode, EmptySubscription>; #[tokio::test] async fn explicit_null() { diff --git a/tests/integration/tests/issue_371.rs b/tests/integration/tests/issue_371.rs index 41f227e0b..bbad91541 100644 --- a/tests/integration/tests/issue_371.rs +++ b/tests/integration/tests/issue_371.rs @@ -57,7 +57,7 @@ impl Country { } } -type Schema = RootNode<'static, Query, EmptyMutation, EmptySubscription>; +type Schema = RootNode, EmptySubscription>; #[tokio::test] async fn users() { diff --git a/tests/integration/tests/issue_398.rs b/tests/integration/tests/issue_398.rs index 4fad2d125..ae08dbf14 100644 --- a/tests/integration/tests/issue_398.rs +++ b/tests/integration/tests/issue_398.rs @@ -50,7 +50,7 @@ impl Country { } } -type Schema = RootNode<'static, Query, EmptyMutation<()>, EmptySubscription<()>>; +type Schema = RootNode, EmptySubscription<()>>; #[tokio::test] async fn lookahead_from_fragment_with_nested_type() { diff --git a/tests/integration/tests/issue_407.rs b/tests/integration/tests/issue_407.rs index a8a4ef13c..266fd0399 100644 --- a/tests/integration/tests/issue_407.rs +++ b/tests/integration/tests/issue_407.rs @@ -42,7 +42,7 @@ impl Query { } } -type Schema = juniper::RootNode<'static, Query, EmptyMutation, EmptySubscription>; +type Schema = juniper::RootNode; #[tokio::test] async fn fragments_in_interface() { diff --git a/tests/integration/tests/issue_500.rs b/tests/integration/tests/issue_500.rs index d56c797bb..d80eb661a 100644 --- a/tests/integration/tests/issue_500.rs +++ b/tests/integration/tests/issue_500.rs @@ -63,7 +63,7 @@ impl Country { } } -type Schema = juniper::RootNode<'static, Query, EmptyMutation<()>, EmptySubscription<()>>; +type Schema = juniper::RootNode, EmptySubscription<()>>; #[tokio::test] async fn nested_fragments() { diff --git a/tests/integration/tests/issue_798.rs b/tests/integration/tests/issue_798.rs index 402524063..c96066742 100644 --- a/tests/integration/tests/issue_798.rs +++ b/tests/integration/tests/issue_798.rs @@ -53,7 +53,7 @@ impl Query { } } -type Schema = RootNode<'static, Query, EmptyMutation, EmptySubscription>; +type Schema = RootNode; #[tokio::test] async fn interface_inline_fragment_on_union() { diff --git a/tests/integration/tests/issue_914.rs b/tests/integration/tests/issue_914.rs index 4886f645b..2003cb469 100644 --- a/tests/integration/tests/issue_914.rs +++ b/tests/integration/tests/issue_914.rs @@ -34,7 +34,7 @@ impl Query { } } -type Schema = juniper::RootNode<'static, Query, EmptyMutation, EmptySubscription>; +type Schema = juniper::RootNode; #[tokio::test] async fn fragments_with_nested_objects_dont_override_previous_selections() { diff --git a/tests/integration/tests/issue_922.rs b/tests/integration/tests/issue_922.rs index b592f392e..23c058f3d 100644 --- a/tests/integration/tests/issue_922.rs +++ b/tests/integration/tests/issue_922.rs @@ -45,7 +45,7 @@ struct Droid { pub name: String, } -type Schema = juniper::RootNode<'static, Query, EmptyMutation, EmptySubscription>; +type Schema = juniper::RootNode; #[tokio::test] async fn object_fragment_on_interface() { diff --git a/tests/integration/tests/issue_925.rs b/tests/integration/tests/issue_925.rs index 4f8fa9c7c..bdd8f3ea6 100644 --- a/tests/integration/tests/issue_925.rs +++ b/tests/integration/tests/issue_925.rs @@ -46,7 +46,7 @@ impl Query { } } -type Schema = juniper::RootNode<'static, Query, EmptyMutation, SubscriptionsRoot>; +type Schema = juniper::RootNode; #[tokio::test] async fn error_extensions() { diff --git a/tests/integration/tests/issue_945.rs b/tests/integration/tests/issue_945.rs index 424583138..c30cf7479 100644 --- a/tests/integration/tests/issue_945.rs +++ b/tests/integration/tests/issue_945.rs @@ -40,7 +40,7 @@ struct Droid { pub sensor_color: String, } -type Schema = juniper::RootNode<'static, Query, EmptyMutation, EmptySubscription>; +type Schema = juniper::RootNode; #[tokio::test] async fn fragment_on_union() { diff --git a/tests/integration/tests/pre_parse.rs b/tests/integration/tests/pre_parse.rs index 7d1c239c7..b27cf4754 100644 --- a/tests/integration/tests/pre_parse.rs +++ b/tests/integration/tests/pre_parse.rs @@ -43,7 +43,7 @@ impl User { } } -type Schema = RootNode<'static, Query, EmptyMutation, Subscription>; +type Schema = RootNode, Subscription>; #[tokio::test] async fn query_document_can_be_pre_parsed() {