From 5332db0a4b573cea8e16a6e4b18b50ca1a8c14c2 Mon Sep 17 00:00:00 2001 From: Benno Tielen Date: Fri, 8 Jul 2022 20:21:23 +0200 Subject: [PATCH] Strip lifetime parameter from `ParseError` (#1081, #528) - replace `Token` with its string representation in `ParseError` - strip lifetime parameter from `GraphQLError`, `GraphQLResponse` and `GraphQLBatchResponse` Co-authored-by: Kai Ren --- book/src/types/scalars.md | 9 +- juniper/CHANGELOG.md | 1 + juniper/src/executor/mod.rs | 12 +-- juniper/src/http/mod.rs | 38 ++++---- juniper/src/integrations/serde.rs | 4 +- juniper/src/lib.rs | 54 ++++++----- juniper/src/parser/document.rs | 49 +++++----- juniper/src/parser/parser.rs | 92 ++++++++++++------- juniper/src/parser/tests/document.rs | 9 +- juniper/src/parser/value.rs | 34 +++---- juniper/src/schema/meta.rs | 2 +- juniper/src/types/scalars.rs | 24 ++--- juniper/src/value/scalar.rs | 4 +- juniper_codegen/src/graphql_scalar/mod.rs | 2 +- juniper_codegen/src/lib.rs | 6 +- juniper_graphql_ws/src/lib.rs | 11 +-- juniper_graphql_ws/src/server_message.rs | 10 +- juniper_subscriptions/src/lib.rs | 3 +- .../src/codegen/scalar_attr_derive_input.rs | 8 +- .../src/codegen/scalar_attr_type_alias.rs | 6 +- .../integration/src/codegen/scalar_derive.rs | 8 +- tests/integration/src/custom_scalar.rs | 6 +- tests/integration/src/lib.rs | 6 +- 23 files changed, 211 insertions(+), 187 deletions(-) diff --git a/book/src/types/scalars.md b/book/src/types/scalars.md index 8981eaac..052fe8dc 100644 --- a/book/src/types/scalars.md +++ b/book/src/types/scalars.md @@ -205,10 +205,7 @@ where .ok_or_else(|| format!("Expected `String` or `Int`, found: {}", v)) } -fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> -where - S: ScalarValue -{ +fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult { >::from_str(value) .or_else(|_| >::from_str(value)) } @@ -258,7 +255,7 @@ impl StringOrInt { .ok_or_else(|| format!("Expected `String` or `Int`, found: {}", v)) } - fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> + fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult where S: ScalarValue, { @@ -308,7 +305,7 @@ mod string_or_int { .ok_or_else(|| format!("Expected `String` or `Int`, found: {}", v)) } - pub(super) fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> + pub(super) fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult where S: ScalarValue, { diff --git a/juniper/CHANGELOG.md b/juniper/CHANGELOG.md index 7a5aa27a..0ddfa620 100644 --- a/juniper/CHANGELOG.md +++ b/juniper/CHANGELOG.md @@ -48,6 +48,7 @@ All user visible changes to `juniper` crate will be documented in this file. Thi - Reworked [`chrono` crate] integration GraphQL scalars according to [graphql-scalars.dev] specs: ([#1010]) - Disabled `chrono` [Cargo feature] by default. - Removed `scalar-naivetime` [Cargo feature]. +- Removed lifetime parameter from `ParseError`, `GraphlQLError`, `GraphQLBatchRequest` and `GraphQLRequest`. ([#528]) ### Added diff --git a/juniper/src/executor/mod.rs b/juniper/src/executor/mod.rs index 47d5fead..777d8062 100644 --- a/juniper/src/executor/mod.rs +++ b/juniper/src/executor/mod.rs @@ -814,13 +814,13 @@ impl ExecutionError { /// Create new `Executor` and start query/mutation execution. /// Returns `IsSubscription` error if subscription is passed. -pub fn execute_validated_query<'a, 'b, QueryT, MutationT, SubscriptionT, S>( +pub fn execute_validated_query<'b, QueryT, MutationT, SubscriptionT, S>( document: &'b Document, operation: &'b Spanning>, root_node: &RootNode, variables: &Variables, context: &QueryT::Context, -) -> Result<(Value, Vec>), GraphQLError<'a>> +) -> Result<(Value, Vec>), GraphQLError> where S: ScalarValue, QueryT: GraphQLType, @@ -914,7 +914,7 @@ pub async fn execute_validated_query_async<'a, 'b, QueryT, MutationT, Subscripti root_node: &RootNode<'a, QueryT, MutationT, SubscriptionT, S>, variables: &Variables, context: &QueryT::Context, -) -> Result<(Value, Vec>), GraphQLError<'a>> +) -> Result<(Value, Vec>), GraphQLError> where QueryT: GraphQLTypeAsync, QueryT::TypeInfo: Sync, @@ -1011,10 +1011,10 @@ where } #[doc(hidden)] -pub fn get_operation<'b, 'd, 'e, S>( +pub fn get_operation<'b, 'd, S>( document: &'b Document<'d, S>, operation_name: Option<&str>, -) -> Result<&'b Spanning>, GraphQLError<'e>> +) -> Result<&'b Spanning>, GraphQLError> where S: ScalarValue, { @@ -1058,7 +1058,7 @@ pub async fn resolve_validated_subscription< root_node: &'r RootNode<'r, QueryT, MutationT, SubscriptionT, S>, variables: &Variables, context: &'r QueryT::Context, -) -> Result<(Value>, Vec>), GraphQLError<'r>> +) -> Result<(Value>, Vec>), GraphQLError> where 'r: 'exec_ref, 'd: 'r, diff --git a/juniper/src/http/mod.rs b/juniper/src/http/mod.rs index 17420de3..fe3f2d65 100644 --- a/juniper/src/http/mod.rs +++ b/juniper/src/http/mod.rs @@ -86,11 +86,11 @@ where /// /// This is a simple wrapper around the `execute_sync` function exposed at the /// top level of this crate. - pub fn execute_sync<'a, QueryT, MutationT, SubscriptionT>( - &'a self, - root_node: &'a RootNode, + pub fn execute_sync( + &self, + root_node: &RootNode, context: &QueryT::Context, - ) -> GraphQLResponse<'a, S> + ) -> GraphQLResponse where S: ScalarValue, QueryT: GraphQLType, @@ -114,7 +114,7 @@ where &'a self, root_node: &'a RootNode<'a, QueryT, MutationT, SubscriptionT, S>, context: &'a QueryT::Context, - ) -> GraphQLResponse<'a, S> + ) -> GraphQLResponse where QueryT: GraphQLTypeAsync, QueryT::TypeInfo: Sync, @@ -140,7 +140,7 @@ pub async fn resolve_into_stream<'req, 'rn, 'ctx, 'a, QueryT, MutationT, Subscri req: &'req GraphQLRequest, root_node: &'rn RootNode<'a, QueryT, MutationT, SubscriptionT, S>, context: &'ctx QueryT::Context, -) -> Result<(Value>, Vec>), GraphQLError<'a>> +) -> Result<(Value>, Vec>), GraphQLError> where 'req: 'a, 'rn: 'a, @@ -166,16 +166,16 @@ where /// to JSON and send it over the wire. Use the `is_ok` method to determine /// whether to send a 200 or 400 HTTP status code. #[derive(Debug)] -pub struct GraphQLResponse<'a, S = DefaultScalarValue>( - Result<(Value, Vec>), GraphQLError<'a>>, +pub struct GraphQLResponse( + Result<(Value, Vec>), GraphQLError>, ); -impl<'a, S> GraphQLResponse<'a, S> +impl GraphQLResponse where S: ScalarValue, { /// Constructs new `GraphQLResponse` using the given result - pub fn from_result(r: Result<(Value, Vec>), GraphQLError<'a>>) -> Self { + pub fn from_result(r: Result<(Value, Vec>), GraphQLError>) -> Self { Self(r) } @@ -193,12 +193,11 @@ where } } -impl<'a, T> Serialize for GraphQLResponse<'a, T> +impl Serialize for GraphQLResponse where T: Serialize + ScalarValue, Value: Serialize, ExecutionError: Serialize, - GraphQLError<'a>: Serialize, { fn serialize(&self, serializer: S) -> Result where @@ -272,7 +271,7 @@ where &'a self, root_node: &'a RootNode, context: &QueryT::Context, - ) -> GraphQLBatchResponse<'a, S> + ) -> GraphQLBatchResponse where QueryT: GraphQLType, MutationT: GraphQLType, @@ -298,7 +297,7 @@ where &'a self, root_node: &'a RootNode<'a, QueryT, MutationT, SubscriptionT, S>, context: &'a QueryT::Context, - ) -> GraphQLBatchResponse<'a, S> + ) -> GraphQLBatchResponse where QueryT: GraphQLTypeAsync, QueryT::TypeInfo: Sync, @@ -340,20 +339,17 @@ where /// wheter to send a 200 or 400 HTTP status code. #[derive(Serialize)] #[serde(untagged)] -pub enum GraphQLBatchResponse<'a, S = DefaultScalarValue> +pub enum GraphQLBatchResponse where S: ScalarValue, { /// Result of a single operation in a GraphQL request. - Single(GraphQLResponse<'a, S>), + Single(GraphQLResponse), /// Result of a batch operation in a GraphQL request. - Batch(Vec>), + Batch(Vec>), } -impl<'a, S> GraphQLBatchResponse<'a, S> -where - S: ScalarValue, -{ +impl GraphQLBatchResponse { /// Returns if all the GraphQLResponse in this operation are ok, /// you can use it to determine wheter to send a 200 or 400 HTTP status code. pub fn is_ok(&self) -> bool { diff --git a/juniper/src/integrations/serde.rs b/juniper/src/integrations/serde.rs index 31a0b600..64b5018f 100644 --- a/juniper/src/integrations/serde.rs +++ b/juniper/src/integrations/serde.rs @@ -42,7 +42,7 @@ impl Serialize for ExecutionError { } } -impl<'a> Serialize for GraphQLError<'a> { +impl Serialize for GraphQLError { fn serialize(&self, ser: S) -> Result { #[derive(Serialize)] struct Helper { @@ -247,7 +247,7 @@ impl Serialize for SourcePosition { } } -impl<'a> Serialize for Spanning> { +impl Serialize for Spanning { fn serialize(&self, ser: S) -> Result { let mut map = ser.serialize_map(Some(2))?; diff --git a/juniper/src/lib.rs b/juniper/src/lib.rs index 0373175e..e113fcd9 100644 --- a/juniper/src/lib.rs +++ b/juniper/src/lib.rs @@ -95,8 +95,8 @@ pub use crate::{ /// An error that prevented query execution #[derive(Debug, PartialEq)] #[allow(missing_docs)] -pub enum GraphQLError<'a> { - ParseError(Spanning>), +pub enum GraphQLError { + ParseError(Spanning), ValidationError(Vec), NoOperationProvided, MultipleOperationsProvided, @@ -105,26 +105,38 @@ pub enum GraphQLError<'a> { NotSubscription, } -impl<'a> fmt::Display for GraphQLError<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +impl fmt::Display for GraphQLError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - GraphQLError::ParseError(error) => write!(f, "{}", error), - GraphQLError::ValidationError(errors) => { - for error in errors { - writeln!(f, "{}", error)?; + Self::ParseError(e) => write!(f, "{}", e), + Self::ValidationError(errs) => { + for e in errs { + writeln!(f, "{}", e)?; } Ok(()) } - GraphQLError::NoOperationProvided => write!(f, "No operation provided"), - GraphQLError::MultipleOperationsProvided => write!(f, "Multiple operations provided"), - GraphQLError::UnknownOperationName => write!(f, "Unknown operation name"), - GraphQLError::IsSubscription => write!(f, "Operation is a subscription"), - GraphQLError::NotSubscription => write!(f, "Operation is not a subscription"), + Self::NoOperationProvided => write!(f, "No operation provided"), + Self::MultipleOperationsProvided => write!(f, "Multiple operations provided"), + Self::UnknownOperationName => write!(f, "Unknown operation name"), + Self::IsSubscription => write!(f, "Operation is a subscription"), + Self::NotSubscription => write!(f, "Operation is not a subscription"), } } } -impl<'a> std::error::Error for GraphQLError<'a> {} +impl std::error::Error for GraphQLError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::ParseError(e) => Some(e), + Self::ValidationError(errs) => Some(errs.first()?), + Self::NoOperationProvided + | Self::MultipleOperationsProvided + | Self::UnknownOperationName + | Self::IsSubscription + | Self::NotSubscription => None, + } + } +} /// Execute a query synchronously in a provided schema pub fn execute_sync<'a, S, QueryT, MutationT, SubscriptionT>( @@ -133,7 +145,7 @@ pub fn execute_sync<'a, S, QueryT, MutationT, SubscriptionT>( root_node: &'a RootNode, variables: &Variables, context: &QueryT::Context, -) -> Result<(Value, Vec>), GraphQLError<'a>> +) -> Result<(Value, Vec>), GraphQLError> where S: ScalarValue, QueryT: GraphQLType, @@ -172,7 +184,7 @@ pub async fn execute<'a, S, QueryT, MutationT, SubscriptionT>( root_node: &'a RootNode<'a, QueryT, MutationT, SubscriptionT, S>, variables: &Variables, context: &QueryT::Context, -) -> Result<(Value, Vec>), GraphQLError<'a>> +) -> Result<(Value, Vec>), GraphQLError> where QueryT: GraphQLTypeAsync, QueryT::TypeInfo: Sync, @@ -216,7 +228,7 @@ pub async fn resolve_into_stream<'a, S, QueryT, MutationT, SubscriptionT>( root_node: &'a RootNode<'a, QueryT, MutationT, SubscriptionT, S>, variables: &Variables, context: &'a QueryT::Context, -) -> Result<(Value>, Vec>), GraphQLError<'a>> +) -> Result<(Value>, Vec>), GraphQLError> where QueryT: GraphQLTypeAsync, QueryT::TypeInfo: Sync, @@ -259,7 +271,7 @@ pub fn introspect<'a, S, QueryT, MutationT, SubscriptionT>( root_node: &'a RootNode, context: &QueryT::Context, format: IntrospectionFormat, -) -> Result<(Value, Vec>), GraphQLError<'a>> +) -> Result<(Value, Vec>), GraphQLError> where S: ScalarValue, QueryT: GraphQLType, @@ -278,8 +290,8 @@ where ) } -impl<'a> From>> for GraphQLError<'a> { - fn from(f: Spanning>) -> GraphQLError<'a> { - GraphQLError::ParseError(f) +impl From> for GraphQLError { + fn from(err: Spanning) -> Self { + Self::ParseError(err) } } diff --git a/juniper/src/parser/document.rs b/juniper/src/parser/document.rs index cd891883..cb2b308f 100644 --- a/juniper/src/parser/document.rs +++ b/juniper/src/parser/document.rs @@ -22,7 +22,7 @@ use crate::{ pub fn parse_document_source<'a, 'b, S>( s: &'a str, schema: &'b SchemaType<'b, S>, -) -> UnlocatedParseResult<'a, OwnedDocument<'a, S>> +) -> UnlocatedParseResult> where S: ScalarValue, { @@ -34,7 +34,7 @@ where fn parse_document<'a, 'b, S>( parser: &mut Parser<'a>, schema: &'b SchemaType<'b, S>, -) -> UnlocatedParseResult<'a, OwnedDocument<'a, S>> +) -> UnlocatedParseResult> where S: ScalarValue, { @@ -52,7 +52,7 @@ where fn parse_definition<'a, 'b, S>( parser: &mut Parser<'a>, schema: &'b SchemaType<'b, S>, -) -> UnlocatedParseResult<'a, Definition<'a, S>> +) -> UnlocatedParseResult> where S: ScalarValue, { @@ -66,14 +66,14 @@ where Token::Name("fragment") => Ok(Definition::Fragment(parse_fragment_definition( parser, schema, )?)), - _ => Err(parser.next_token()?.map(ParseError::UnexpectedToken)), + _ => Err(parser.next_token()?.map(ParseError::unexpected_token)), } } fn parse_operation_definition<'a, 'b, S>( parser: &mut Parser<'a>, schema: &'b SchemaType<'b, S>, -) -> ParseResult<'a, Operation<'a, S>> +) -> ParseResult> where S: ScalarValue, { @@ -129,7 +129,7 @@ where fn parse_fragment_definition<'a, 'b, S>( parser: &mut Parser<'a>, schema: &'b SchemaType<'b, S>, -) -> ParseResult<'a, Fragment<'a, S>> +) -> ParseResult> where S: ScalarValue, { @@ -139,7 +139,7 @@ where let name = match parser.expect_name() { Ok(n) => { if n.item == "on" { - return Err(n.map(|_| ParseError::UnexpectedToken(Token::Name("on")))); + return Err(n.map(|_| ParseError::UnexpectedToken("on".into()))); } else { n } @@ -174,7 +174,7 @@ fn parse_optional_selection_set<'a, 'b, S>( parser: &mut Parser<'a>, schema: &'b SchemaType<'b, S>, fields: Option<&[&MetaField<'b, S>]>, -) -> OptionParseResult<'a, Vec>> +) -> OptionParseResult>> where S: ScalarValue, { @@ -189,7 +189,7 @@ fn parse_selection_set<'a, 'b, S>( parser: &mut Parser<'a>, schema: &'b SchemaType<'b, S>, fields: Option<&[&MetaField<'b, S>]>, -) -> ParseResult<'a, Vec>> +) -> ParseResult>> where S: ScalarValue, { @@ -204,7 +204,7 @@ fn parse_selection<'a, 'b, S>( parser: &mut Parser<'a>, schema: &'b SchemaType<'b, S>, fields: Option<&[&MetaField<'b, S>]>, -) -> UnlocatedParseResult<'a, Selection<'a, S>> +) -> UnlocatedParseResult> where S: ScalarValue, { @@ -218,7 +218,7 @@ fn parse_fragment<'a, 'b, S>( parser: &mut Parser<'a>, schema: &'b SchemaType<'b, S>, fields: Option<&[&MetaField<'b, S>]>, -) -> UnlocatedParseResult<'a, Selection<'a, S>> +) -> UnlocatedParseResult> where S: ScalarValue, { @@ -292,7 +292,7 @@ where }, ))) } - _ => Err(parser.next_token()?.map(ParseError::UnexpectedToken)), + _ => Err(parser.next_token()?.map(ParseError::unexpected_token)), } } @@ -300,7 +300,7 @@ fn parse_field<'a, 'b, S>( parser: &mut Parser<'a>, schema: &'b SchemaType<'b, S>, fields: Option<&[&MetaField<'b, S>]>, -) -> ParseResult<'a, Field<'a, S>> +) -> ParseResult> where S: ScalarValue, { @@ -351,7 +351,7 @@ fn parse_arguments<'a, 'b, S>( parser: &mut Parser<'a>, schema: &'b SchemaType<'b, S>, arguments: Option<&[Argument<'b, S>]>, -) -> OptionParseResult<'a, Arguments<'a, S>> +) -> OptionParseResult> where S: ScalarValue, { @@ -376,7 +376,7 @@ fn parse_argument<'a, 'b, S>( parser: &mut Parser<'a>, schema: &'b SchemaType<'b, S>, arguments: Option<&[Argument<'b, S>]>, -) -> ParseResult<'a, (Spanning<&'a str>, Spanning>)> +) -> ParseResult<(Spanning<&'a str>, Spanning>)> where S: ScalarValue, { @@ -395,21 +395,21 @@ where )) } -fn parse_operation_type<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, OperationType> { +fn parse_operation_type(parser: &mut Parser<'_>) -> ParseResult { match parser.peek().item { Token::Name("query") => Ok(parser.next_token()?.map(|_| OperationType::Query)), Token::Name("mutation") => Ok(parser.next_token()?.map(|_| OperationType::Mutation)), Token::Name("subscription") => { Ok(parser.next_token()?.map(|_| OperationType::Subscription)) } - _ => Err(parser.next_token()?.map(ParseError::UnexpectedToken)), + _ => Err(parser.next_token()?.map(ParseError::unexpected_token)), } } fn parse_variable_definitions<'a, 'b, S>( parser: &mut Parser<'a>, schema: &'b SchemaType<'b, S>, -) -> OptionParseResult<'a, VariableDefinitions<'a, S>> +) -> OptionParseResult> where S: ScalarValue, { @@ -433,7 +433,7 @@ where fn parse_variable_definition<'a, 'b, S>( parser: &mut Parser<'a>, schema: &'b SchemaType<'b, S>, -) -> ParseResult<'a, (Spanning<&'a str>, VariableDefinition<'a, S>)> +) -> ParseResult<(Spanning<&'a str>, VariableDefinition<'a, S>)> where S: ScalarValue, { @@ -473,7 +473,7 @@ where fn parse_directives<'a, 'b, S>( parser: &mut Parser<'a>, schema: &'b SchemaType<'b, S>, -) -> OptionParseResult<'a, Vec>>> +) -> OptionParseResult>>> where S: ScalarValue, { @@ -492,7 +492,7 @@ where fn parse_directive<'a, 'b, S>( parser: &mut Parser<'a>, schema: &'b SchemaType<'b, S>, -) -> ParseResult<'a, Directive<'a, S>> +) -> ParseResult> where S: ScalarValue, { @@ -516,7 +516,7 @@ where )) } -pub fn parse_type<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Type<'a>> { +pub fn parse_type<'a>(parser: &mut Parser<'a>) -> ParseResult> { let parsed_type = if let Some(Spanning { start: start_pos, .. }) = parser.skip(&Token::BracketOpen)? @@ -541,10 +541,7 @@ pub fn parse_type<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Type<'a>> { }) } -fn wrap_non_null<'a>( - parser: &mut Parser<'a>, - inner: Spanning>, -) -> ParseResult<'a, Type<'a>> { +fn wrap_non_null<'a>(parser: &mut Parser<'a>, inner: Spanning>) -> ParseResult> { let Spanning { end: end_pos, .. } = parser.expect(&Token::ExclamationMark)?; let wrapped = match inner.item { diff --git a/juniper/src/parser/parser.rs b/juniper/src/parser/parser.rs index 4a066453..6ee6e758 100644 --- a/juniper/src/parser/parser.rs +++ b/juniper/src/parser/parser.rs @@ -1,12 +1,16 @@ -use std::{fmt, result::Result}; +use std::{error::Error, fmt, result::Result}; + +use smartstring::alias::String; use crate::parser::{Lexer, LexerError, Spanning, Token}; /// Error while parsing a GraphQL query #[derive(Debug, PartialEq)] -pub enum ParseError<'a> { +pub enum ParseError { /// An unexpected token occurred in the source - UnexpectedToken(Token<'a>), + // TODO: Previously was `Token<'a>`. + // Revisit on `graphql-parser` integration. + UnexpectedToken(String), /// The input source abruptly ended UnexpectedEndOfFile, @@ -18,14 +22,51 @@ pub enum ParseError<'a> { ExpectedScalarError(&'static str), } -#[doc(hidden)] -pub type ParseResult<'a, T> = Result, Spanning>>; +impl fmt::Display for ParseError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::UnexpectedToken(token) => write!(f, "Unexpected \"{}\"", token), + Self::UnexpectedEndOfFile => write!(f, "Unexpected end of input"), + Self::LexerError(e) => e.fmt(f), + Self::ExpectedScalarError(e) => e.fmt(f), + } + } +} + +impl Error for ParseError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + match self { + Self::LexerError(e) => Some(e), + Self::ExpectedScalarError(_) | Self::UnexpectedToken(_) | Self::UnexpectedEndOfFile => { + None + } + } + } +} + +impl ParseError { + /// Creates a [`ParseError::UnexpectedToken`] out of the provided [`Token`]. + #[must_use] + pub fn unexpected_token(token: Token<'_>) -> Self { + use std::fmt::Write as _; + + let mut s = String::new(); + // PANIC: Unwrapping is OK here, as it may panic only on allocation + // error. + write!(s, "{}", token).unwrap(); + + Self::UnexpectedToken(s) + } +} #[doc(hidden)] -pub type UnlocatedParseResult<'a, T> = Result>>; +pub type ParseResult = Result, Spanning>; #[doc(hidden)] -pub type OptionParseResult<'a, T> = Result>, Spanning>>; +pub type UnlocatedParseResult = Result>; + +#[doc(hidden)] +pub type OptionParseResult = Result>, Spanning>; #[doc(hidden)] #[derive(Debug)] @@ -54,7 +95,7 @@ impl<'a> Parser<'a> { } #[doc(hidden)] - pub fn next_token(&mut self) -> ParseResult<'a, Token<'a>> { + pub fn next_token(&mut self) -> ParseResult> { if self.tokens.len() == 1 { Err(Spanning::start_end( &self.peek().start, @@ -67,9 +108,9 @@ impl<'a> Parser<'a> { } #[doc(hidden)] - pub fn expect(&mut self, expected: &Token) -> ParseResult<'a, Token<'a>> { + pub fn expect(&mut self, expected: &Token) -> ParseResult> { if &self.peek().item != expected { - Err(self.next_token()?.map(ParseError::UnexpectedToken)) + Err(self.next_token()?.map(ParseError::unexpected_token)) } else { self.next_token() } @@ -79,7 +120,7 @@ impl<'a> Parser<'a> { pub fn skip( &mut self, expected: &Token, - ) -> Result>>, Spanning>> { + ) -> Result>>, Spanning> { if &self.peek().item == expected { Ok(Some(self.next_token()?)) } else if self.peek().item == Token::EndOfFile { @@ -98,10 +139,10 @@ impl<'a> Parser<'a> { opening: &Token, parser: F, closing: &Token, - ) -> ParseResult<'a, Vec>> + ) -> ParseResult>> where T: fmt::Debug, - F: Fn(&mut Parser<'a>) -> ParseResult<'a, T>, + F: Fn(&mut Parser<'a>) -> ParseResult, { let Spanning { start: start_pos, .. @@ -123,10 +164,10 @@ impl<'a> Parser<'a> { opening: &Token, parser: F, closing: &Token, - ) -> ParseResult<'a, Vec>> + ) -> ParseResult>> where T: fmt::Debug, - F: Fn(&mut Parser<'a>) -> ParseResult<'a, T>, + F: Fn(&mut Parser<'a>) -> ParseResult, { let Spanning { start: start_pos, .. @@ -148,10 +189,10 @@ impl<'a> Parser<'a> { opening: &Token, parser: F, closing: &Token, - ) -> ParseResult<'a, Vec> + ) -> ParseResult> where T: fmt::Debug, - F: Fn(&mut Parser<'a>) -> UnlocatedParseResult<'a, T>, + F: Fn(&mut Parser<'a>) -> UnlocatedParseResult, { let Spanning { start: start_pos, .. @@ -168,7 +209,7 @@ impl<'a> Parser<'a> { } #[doc(hidden)] - pub fn expect_name(&mut self) -> ParseResult<'a, &'a str> { + pub fn expect_name(&mut self) -> ParseResult<&'a str> { match *self.peek() { Spanning { item: Token::Name(_), @@ -188,20 +229,7 @@ impl<'a> Parser<'a> { &self.peek().end, ParseError::UnexpectedEndOfFile, )), - _ => Err(self.next_token()?.map(ParseError::UnexpectedToken)), + _ => Err(self.next_token()?.map(ParseError::unexpected_token)), } } } - -impl<'a> fmt::Display for ParseError<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - ParseError::UnexpectedToken(ref token) => write!(f, "Unexpected \"{}\"", token), - ParseError::UnexpectedEndOfFile => write!(f, "Unexpected end of input"), - ParseError::LexerError(ref err) => err.fmt(f), - ParseError::ExpectedScalarError(err) => err.fmt(f), - } - } -} - -impl<'a> std::error::Error for ParseError<'a> {} diff --git a/juniper/src/parser/tests/document.rs b/juniper/src/parser/tests/document.rs index bb28074b..55ae6230 100644 --- a/juniper/src/parser/tests/document.rs +++ b/juniper/src/parser/tests/document.rs @@ -19,10 +19,7 @@ where .expect(&format!("Parse error on input {:#?}", s)) } -fn parse_document_error<'a, S>(s: &'a str) -> Spanning> -where - S: ScalarValue, -{ +fn parse_document_error(s: &str) -> Spanning { match parse_document_source::( s, &SchemaType::new::(&(), &(), &()), @@ -136,7 +133,7 @@ fn errors() { Spanning::start_end( &SourcePosition::new(36, 1, 19), &SourcePosition::new(40, 1, 23), - ParseError::UnexpectedToken(Token::Name("Type")) + ParseError::UnexpectedToken("Type".into()) ) ); @@ -145,7 +142,7 @@ fn errors() { Spanning::start_end( &SourcePosition::new(8, 0, 8), &SourcePosition::new(9, 0, 9), - ParseError::UnexpectedToken(Token::CurlyClose) + ParseError::unexpected_token(Token::CurlyClose) ) ); } diff --git a/juniper/src/parser/value.rs b/juniper/src/parser/value.rs index 3ff6d5ef..f94f65c2 100644 --- a/juniper/src/parser/value.rs +++ b/juniper/src/parser/value.rs @@ -9,12 +9,12 @@ use crate::{ value::ScalarValue, }; -pub fn parse_value_literal<'a, 'b, S>( - parser: &mut Parser<'a>, +pub fn parse_value_literal<'b, S>( + parser: &mut Parser<'_>, is_const: bool, schema: &'b SchemaType<'b, S>, tpe: Option<&MetaType<'b, S>>, -) -> ParseResult<'a, InputValue> +) -> ParseResult> where S: ScalarValue, { @@ -113,16 +113,16 @@ where }, _, ) => Ok(parser.next_token()?.map(|_| InputValue::enum_value(name))), - _ => Err(parser.next_token()?.map(ParseError::UnexpectedToken)), + _ => Err(parser.next_token()?.map(ParseError::unexpected_token)), } } -fn parse_list_literal<'a, 'b, S>( - parser: &mut Parser<'a>, +fn parse_list_literal<'b, S>( + parser: &mut Parser<'_>, is_const: bool, schema: &'b SchemaType<'b, S>, tpe: Option<&MetaType<'b, S>>, -) -> ParseResult<'a, InputValue> +) -> ParseResult> where S: ScalarValue, { @@ -135,12 +135,12 @@ where .map(InputValue::parsed_list)) } -fn parse_object_literal<'a, 'b, S>( - parser: &mut Parser<'a>, +fn parse_object_literal<'b, S>( + parser: &mut Parser<'_>, is_const: bool, schema: &'b SchemaType<'b, S>, object_tpe: Option<&InputObjectMeta<'b, S>>, -) -> ParseResult<'a, InputValue> +) -> ParseResult> where S: ScalarValue, { @@ -153,12 +153,12 @@ where .map(|items| InputValue::parsed_object(items.into_iter().map(|s| s.item).collect()))) } -fn parse_object_field<'a, 'b, S>( - parser: &mut Parser<'a>, +fn parse_object_field<'b, S>( + parser: &mut Parser<'_>, is_const: bool, schema: &'b SchemaType<'b, S>, object_meta: Option<&InputObjectMeta<'b, S>>, -) -> ParseResult<'a, (Spanning, Spanning>)> +) -> ParseResult<(Spanning, Spanning>)> where S: ScalarValue, { @@ -179,7 +179,7 @@ where )) } -fn parse_variable_literal<'a, S>(parser: &mut Parser<'a>) -> ParseResult<'a, InputValue> +fn parse_variable_literal(parser: &mut Parser<'_>) -> ParseResult> where S: ScalarValue, { @@ -199,12 +199,12 @@ where )) } -fn parse_scalar_literal_by_infered_type<'a, 'b, S>( - token: ScalarToken<'a>, +fn parse_scalar_literal_by_infered_type<'b, S>( + token: ScalarToken<'_>, start: &SourcePosition, end: &SourcePosition, schema: &'b SchemaType<'b, S>, -) -> ParseResult<'a, InputValue> +) -> ParseResult> where S: ScalarValue, { diff --git a/juniper/src/schema/meta.rs b/juniper/src/schema/meta.rs index 5ef83cc8..a7d81a8a 100644 --- a/juniper/src/schema/meta.rs +++ b/juniper/src/schema/meta.rs @@ -58,7 +58,7 @@ pub struct ScalarMeta<'a, S> { pub type InputValueParseFn = for<'b> fn(&'b InputValue) -> Result<(), FieldError>; /// Shortcut for a [`ScalarToken`] parsing function. -pub type ScalarTokenParseFn = for<'b> fn(ScalarToken<'b>) -> Result>; +pub type ScalarTokenParseFn = for<'b> fn(ScalarToken<'b>) -> Result; /// List type metadata #[derive(Debug)] diff --git a/juniper/src/types/scalars.rs b/juniper/src/types/scalars.rs index 66e26e74..3f3422e3 100644 --- a/juniper/src/types/scalars.rs +++ b/juniper/src/types/scalars.rs @@ -84,7 +84,7 @@ mod impl_string_scalar { .ok_or_else(|| format!("Expected `String`, found: {}", v)) } - pub(super) fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> { + pub(super) fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult { if let ScalarToken::String(value) = value { let mut ret = String::with_capacity(value.len()); let mut char_iter = value.chars(); @@ -132,12 +132,12 @@ mod impl_string_scalar { } Ok(ret.into()) } else { - Err(ParseError::UnexpectedToken(Token::Scalar(value))) + Err(ParseError::unexpected_token(Token::Scalar(value))) } } } -fn parse_unicode_codepoint<'a, I>(char_iter: &mut I) -> Result> +fn parse_unicode_codepoint(char_iter: &mut I) -> Result where I: Iterator, { @@ -285,9 +285,9 @@ mod impl_boolean_scalar { .ok_or_else(|| format!("Expected `Boolean`, found: {}", v)) } - pub(super) fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> { + pub(super) fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult { // `Boolean`s are parsed separately, they shouldn't reach this code path. - Err(ParseError::UnexpectedToken(Token::Scalar(value))) + Err(ParseError::unexpected_token(Token::Scalar(value))) } } @@ -306,13 +306,13 @@ mod impl_int_scalar { .ok_or_else(|| format!("Expected `Int`, found: {}", v)) } - pub(super) fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> { + pub(super) fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult { if let ScalarToken::Int(v) = value { v.parse() - .map_err(|_| ParseError::UnexpectedToken(Token::Scalar(value))) + .map_err(|_| ParseError::unexpected_token(Token::Scalar(value))) .map(|s: i32| s.into()) } else { - Err(ParseError::UnexpectedToken(Token::Scalar(value))) + Err(ParseError::unexpected_token(Token::Scalar(value))) } } } @@ -332,17 +332,17 @@ mod impl_float_scalar { .ok_or_else(|| format!("Expected `Float`, found: {}", v)) } - pub(super) fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> { + pub(super) fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult { match value { ScalarToken::Int(v) => v .parse() - .map_err(|_| ParseError::UnexpectedToken(Token::Scalar(value))) + .map_err(|_| ParseError::unexpected_token(Token::Scalar(value))) .map(|s: i32| f64::from(s).into()), ScalarToken::Float(v) => v .parse() - .map_err(|_| ParseError::UnexpectedToken(Token::Scalar(value))) + .map_err(|_| ParseError::unexpected_token(Token::Scalar(value))) .map(|s: f64| s.into()), - ScalarToken::String(_) => Err(ParseError::UnexpectedToken(Token::Scalar(value))), + ScalarToken::String(_) => Err(ParseError::unexpected_token(Token::Scalar(value))), } } } diff --git a/juniper/src/value/scalar.rs b/juniper/src/value/scalar.rs index d93b14fa..fa1dd441 100644 --- a/juniper/src/value/scalar.rs +++ b/juniper/src/value/scalar.rs @@ -7,12 +7,12 @@ use crate::parser::{ParseError, ScalarToken}; pub use juniper_codegen::ScalarValue; /// The result of converting a string into a scalar value -pub type ParseScalarResult<'a, S = DefaultScalarValue> = Result>; +pub type ParseScalarResult = Result; /// A trait used to convert a `ScalarToken` into a certain scalar value type pub trait ParseScalarValue { /// See the trait documentation - fn from_str(value: ScalarToken<'_>) -> ParseScalarResult<'_, S>; + fn from_str(value: ScalarToken<'_>) -> ParseScalarResult; } /// A trait marking a type that could be used as internal representation of diff --git a/juniper_codegen/src/graphql_scalar/mod.rs b/juniper_codegen/src/graphql_scalar/mod.rs index 55652980..37b78db7 100644 --- a/juniper_codegen/src/graphql_scalar/mod.rs +++ b/juniper_codegen/src/graphql_scalar/mod.rs @@ -544,7 +544,7 @@ impl Definition { { fn from_str( token: ::juniper::parser::ScalarToken<'_>, - ) -> ::juniper::ParseScalarResult<'_, #scalar> { + ) -> ::juniper::ParseScalarResult<#scalar> { #from_str } } diff --git a/juniper_codegen/src/lib.rs b/juniper_codegen/src/lib.rs index 3158aa0d..19275174 100644 --- a/juniper_codegen/src/lib.rs +++ b/juniper_codegen/src/lib.rs @@ -497,7 +497,7 @@ pub fn derive_enum(input: TokenStream) -> TokenStream { /// .ok_or_else(|| format!("Expected `String` or `Int`, found: {}", v)) /// } /// -/// fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> { +/// fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult { /// >::from_str(value) /// .or_else(|_| >::from_str(value)) /// } @@ -540,7 +540,7 @@ pub fn derive_enum(input: TokenStream) -> TokenStream { /// .ok_or_else(|| format!("Expected `String` or `Int`, found: {}", v)) /// } /// -/// pub(super) fn parse_token(t: ScalarToken<'_>) -> ParseScalarResult<'_, S> { +/// pub(super) fn parse_token(t: ScalarToken<'_>) -> ParseScalarResult { /// >::from_str(t) /// .or_else(|_| >::from_str(t)) /// } @@ -581,7 +581,7 @@ pub fn derive_enum(input: TokenStream) -> TokenStream { /// .ok_or_else(|| format!("Expected `String` or `Int`, found: {}", v)) /// } /// -/// fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> +/// fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult /// where /// S: ScalarValue /// { diff --git a/juniper_graphql_ws/src/lib.rs b/juniper_graphql_ws/src/lib.rs index cfb8b967..e809c009 100644 --- a/juniper_graphql_ws/src/lib.rs +++ b/juniper_graphql_ws/src/lib.rs @@ -358,10 +358,7 @@ enum SubscriptionStartState { id: String, future: BoxFuture< 'static, - Result< - juniper_subscriptions::Connection<'static, S::ScalarValue>, - GraphQLError<'static>, - >, + Result, GraphQLError>, >, }, /// Streaming is the state after we've successfully obtained the event stream for the @@ -629,7 +626,7 @@ mod test { use juniper::{ futures::sink::SinkExt, graphql_input_value, graphql_object, graphql_subscription, graphql_value, graphql_vars, - parser::{ParseError, Spanning, Token}, + parser::{ParseError, Spanning}, DefaultScalarValue, EmptyMutation, FieldError, FieldResult, RootNode, }; @@ -929,9 +926,9 @@ mod test { assert_eq!(id, "foo"); match payload.graphql_error() { GraphQLError::ParseError(Spanning { - item: ParseError::UnexpectedToken(Token::Name("asd")), + item: ParseError::UnexpectedToken(token), .. - }) => {} + }) => assert_eq!(token, "asd"), p @ _ => panic!("expected graphql parse error, got: {:?}", p), } } diff --git a/juniper_graphql_ws/src/server_message.rs b/juniper_graphql_ws/src/server_message.rs index f52c1244..aedc4620 100644 --- a/juniper_graphql_ws/src/server_message.rs +++ b/juniper_graphql_ws/src/server_message.rs @@ -32,7 +32,7 @@ pub struct DataPayload { // _execution_params). pub struct ErrorPayload { _execution_params: Option>, - error: GraphQLError<'static>, + error: GraphQLError, _marker: PhantomPinned, } @@ -41,7 +41,7 @@ impl ErrorPayload { /// execution_params and that execution_params has not been modified or moved. pub(crate) unsafe fn new_unchecked( execution_params: Box, - error: GraphQLError<'_>, + error: GraphQLError, ) -> Self { Self { _execution_params: Some(execution_params), @@ -51,7 +51,7 @@ impl ErrorPayload { } /// Returns the contained GraphQLError. - pub fn graphql_error<'a>(&'a self) -> &GraphQLError<'a> { + pub fn graphql_error(&self) -> &GraphQLError { &self.error } } @@ -77,8 +77,8 @@ impl Serialize for ErrorPayload { } } -impl From> for ErrorPayload { - fn from(error: GraphQLError<'static>) -> Self { +impl From for ErrorPayload { + fn from(error: GraphQLError) -> Self { Self { _execution_params: None, error, diff --git a/juniper_subscriptions/src/lib.rs b/juniper_subscriptions/src/lib.rs index df6c5fe7..6926066d 100644 --- a/juniper_subscriptions/src/lib.rs +++ b/juniper_subscriptions/src/lib.rs @@ -63,8 +63,7 @@ where S: ScalarValue + Send + Sync + 'a, { type Connection = Connection<'a, S>; - - type Error = GraphQLError<'a>; + type Error = GraphQLError; fn subscribe( &'a self, diff --git a/tests/integration/src/codegen/scalar_attr_derive_input.rs b/tests/integration/src/codegen/scalar_attr_derive_input.rs index ccfa3575..e2b30a30 100644 --- a/tests/integration/src/codegen/scalar_attr_derive_input.rs +++ b/tests/integration/src/codegen/scalar_attr_derive_input.rs @@ -32,7 +32,7 @@ mod trivial { .ok_or_else(|| format!("Expected `Counter`, found: {}", v)) } - fn parse_token(t: ScalarToken<'_>) -> ParseScalarResult<'_, S> { + fn parse_token(t: ScalarToken<'_>) -> ParseScalarResult { >::from_str(t) } } @@ -240,7 +240,7 @@ mod all_custom_resolvers { .ok_or_else(|| format!("Expected `Counter`, found: {}", v)) } - fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> { + fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult { >::from_str(value) } @@ -315,7 +315,7 @@ mod explicit_name { .ok_or_else(|| format!("Expected `Counter`, found: {}", v)) } - fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> { + fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult { >::from_str(value) } } @@ -602,7 +602,7 @@ mod with_self { .ok_or_else(|| format!("Expected `Counter`, found: {}", v)) } - fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> { + fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult { >::from_str(value) } } diff --git a/tests/integration/src/codegen/scalar_attr_type_alias.rs b/tests/integration/src/codegen/scalar_attr_type_alias.rs index 9dfd8f6c..66e25442 100644 --- a/tests/integration/src/codegen/scalar_attr_type_alias.rs +++ b/tests/integration/src/codegen/scalar_attr_type_alias.rs @@ -37,7 +37,7 @@ mod all_custom_resolvers { .ok_or_else(|| format!("Expected `Counter`, found: {}", v)) } - fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> { + fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult { >::from_str(value) } @@ -118,7 +118,7 @@ mod explicit_name { .ok_or_else(|| format!("Expected `Counter`, found: {}", v)) } - fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> { + fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult { >::from_str(value) } @@ -437,7 +437,7 @@ mod with_self { .ok_or_else(|| format!("Expected `Counter`, found: {}", v)) } - fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> { + fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult { >::from_str(value) } } diff --git a/tests/integration/src/codegen/scalar_derive.rs b/tests/integration/src/codegen/scalar_derive.rs index a538095f..45bd2a81 100644 --- a/tests/integration/src/codegen/scalar_derive.rs +++ b/tests/integration/src/codegen/scalar_derive.rs @@ -30,7 +30,7 @@ mod trivial { .ok_or_else(|| format!("Expected `Counter`, found: {}", v)) } - fn parse_token(t: ScalarToken<'_>) -> ParseScalarResult<'_, S> { + fn parse_token(t: ScalarToken<'_>) -> ParseScalarResult { >::from_str(t) } } @@ -238,7 +238,7 @@ mod all_custom_resolvers { .ok_or_else(|| format!("Expected `Counter`, found: {}", v)) } - fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> { + fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult { >::from_str(value) } @@ -314,7 +314,7 @@ mod explicit_name { .ok_or_else(|| format!("Expected `Counter`, found: {}", v)) } - fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> { + fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult { >::from_str(value) } } @@ -605,7 +605,7 @@ mod with_self { .ok_or_else(|| format!("Expected `Counter`, found: {}", v)) } - fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> { + fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult { >::from_str(value) } } diff --git a/tests/integration/src/custom_scalar.rs b/tests/integration/src/custom_scalar.rs index 7a8c6f94..b9acecbc 100644 --- a/tests/integration/src/custom_scalar.rs +++ b/tests/integration/src/custom_scalar.rs @@ -107,13 +107,13 @@ mod long { .ok_or_else(|| format!("Expected `MyScalarValue::Long`, found: {}", v)) } - pub(super) fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult<'_, MyScalarValue> { + pub(super) fn parse_token(value: ScalarToken<'_>) -> ParseScalarResult { if let ScalarToken::Int(v) = value { v.parse() - .map_err(|_| ParseError::UnexpectedToken(Token::Scalar(value))) + .map_err(|_| ParseError::unexpected_token(Token::Scalar(value))) .map(|s: i64| s.into()) } else { - Err(ParseError::UnexpectedToken(Token::Scalar(value))) + Err(ParseError::unexpected_token(Token::Scalar(value))) } } } diff --git a/tests/integration/src/lib.rs b/tests/integration/src/lib.rs index 98019c14..39ce67a1 100644 --- a/tests/integration/src/lib.rs +++ b/tests/integration/src/lib.rs @@ -76,9 +76,9 @@ pub(crate) mod util { /// Extracts a single next value from the result returned by /// [`juniper::resolve_into_stream()`] and transforms it into a regular /// [`Value`]. - pub(crate) async fn extract_next<'a, S: ScalarValue>( - input: Result<(Value>, Vec>), GraphQLError<'a>>, - ) -> Result<(Value, Vec>), GraphQLError<'a>> { + pub(crate) async fn extract_next( + input: Result<(Value>, Vec>), GraphQLError>, + ) -> Result<(Value, Vec>), GraphQLError> { let (stream, errs) = input?; if !errs.is_empty() { return Ok((Value::Null, errs));