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 <tyranron@gmail.com>
This commit is contained in:
Benno Tielen 2022-07-08 20:21:23 +02:00 committed by GitHub
parent eb974fe3ac
commit 5332db0a4b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 211 additions and 187 deletions

View file

@ -205,10 +205,7 @@ where
.ok_or_else(|| format!("Expected `String` or `Int`, found: {}", v))
}
fn parse_token<S>(value: ScalarToken<'_>) -> ParseScalarResult<'_, S>
where
S: ScalarValue
{
fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<S> {
<String as ParseScalarValue<S>>::from_str(value)
.or_else(|_| <i32 as ParseScalarValue<S>>::from_str(value))
}
@ -258,7 +255,7 @@ impl StringOrInt {
.ok_or_else(|| format!("Expected `String` or `Int`, found: {}", v))
}
fn parse_token<S>(value: ScalarToken<'_>) -> ParseScalarResult<'_, S>
fn parse_token<S>(value: ScalarToken<'_>) -> ParseScalarResult<S>
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<S>(value: ScalarToken<'_>) -> ParseScalarResult<'_, S>
pub(super) fn parse_token<S>(value: ScalarToken<'_>) -> ParseScalarResult<S>
where
S: ScalarValue,
{

View file

@ -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

View file

@ -814,13 +814,13 @@ impl<S> ExecutionError<S> {
/// 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<S>,
operation: &'b Spanning<Operation<S>>,
root_node: &RootNode<QueryT, MutationT, SubscriptionT, S>,
variables: &Variables<S>,
context: &QueryT::Context,
) -> Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError<'a>>
) -> Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError>
where
S: ScalarValue,
QueryT: GraphQLType<S>,
@ -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<S>,
context: &QueryT::Context,
) -> Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError<'a>>
) -> Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError>
where
QueryT: GraphQLTypeAsync<S>,
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<Operation<'d, S>>, GraphQLError<'e>>
) -> Result<&'b Spanning<Operation<'d, S>>, 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<S>,
context: &'r QueryT::Context,
) -> Result<(Value<ValuesStream<'r, S>>, Vec<ExecutionError<S>>), GraphQLError<'r>>
) -> Result<(Value<ValuesStream<'r, S>>, Vec<ExecutionError<S>>), GraphQLError>
where
'r: 'exec_ref,
'd: 'r,

View file

@ -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<QueryT, MutationT, SubscriptionT, S>,
pub fn execute_sync<QueryT, MutationT, SubscriptionT>(
&self,
root_node: &RootNode<QueryT, MutationT, SubscriptionT, S>,
context: &QueryT::Context,
) -> GraphQLResponse<'a, S>
) -> GraphQLResponse<S>
where
S: ScalarValue,
QueryT: GraphQLType<S>,
@ -114,7 +114,7 @@ where
&'a self,
root_node: &'a RootNode<'a, QueryT, MutationT, SubscriptionT, S>,
context: &'a QueryT::Context,
) -> GraphQLResponse<'a, S>
) -> GraphQLResponse<S>
where
QueryT: GraphQLTypeAsync<S>,
QueryT::TypeInfo: Sync,
@ -140,7 +140,7 @@ pub async fn resolve_into_stream<'req, 'rn, 'ctx, 'a, QueryT, MutationT, Subscri
req: &'req GraphQLRequest<S>,
root_node: &'rn RootNode<'a, QueryT, MutationT, SubscriptionT, S>,
context: &'ctx QueryT::Context,
) -> Result<(Value<ValuesStream<'a, S>>, Vec<ExecutionError<S>>), GraphQLError<'a>>
) -> Result<(Value<ValuesStream<'a, S>>, Vec<ExecutionError<S>>), 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<S>, Vec<ExecutionError<S>>), GraphQLError<'a>>,
pub struct GraphQLResponse<S = DefaultScalarValue>(
Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError>,
);
impl<'a, S> GraphQLResponse<'a, S>
impl<S> GraphQLResponse<S>
where
S: ScalarValue,
{
/// Constructs new `GraphQLResponse` using the given result
pub fn from_result(r: Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError<'a>>) -> Self {
pub fn from_result(r: Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError>) -> Self {
Self(r)
}
@ -193,12 +193,11 @@ where
}
}
impl<'a, T> Serialize for GraphQLResponse<'a, T>
impl<T> Serialize for GraphQLResponse<T>
where
T: Serialize + ScalarValue,
Value<T>: Serialize,
ExecutionError<T>: Serialize,
GraphQLError<'a>: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@ -272,7 +271,7 @@ where
&'a self,
root_node: &'a RootNode<QueryT, MutationT, SubscriptionT, S>,
context: &QueryT::Context,
) -> GraphQLBatchResponse<'a, S>
) -> GraphQLBatchResponse<S>
where
QueryT: GraphQLType<S>,
MutationT: GraphQLType<S, Context = QueryT::Context>,
@ -298,7 +297,7 @@ where
&'a self,
root_node: &'a RootNode<'a, QueryT, MutationT, SubscriptionT, S>,
context: &'a QueryT::Context,
) -> GraphQLBatchResponse<'a, S>
) -> GraphQLBatchResponse<S>
where
QueryT: GraphQLTypeAsync<S>,
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<S = DefaultScalarValue>
where
S: ScalarValue,
{
/// Result of a single operation in a GraphQL request.
Single(GraphQLResponse<'a, S>),
Single(GraphQLResponse<S>),
/// Result of a batch operation in a GraphQL request.
Batch(Vec<GraphQLResponse<'a, S>>),
Batch(Vec<GraphQLResponse<S>>),
}
impl<'a, S> GraphQLBatchResponse<'a, S>
where
S: ScalarValue,
{
impl<S: ScalarValue> GraphQLBatchResponse<S> {
/// 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 {

View file

@ -42,7 +42,7 @@ impl<T: Serialize> Serialize for ExecutionError<T> {
}
}
impl<'a> Serialize for GraphQLError<'a> {
impl Serialize for GraphQLError {
fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
#[derive(Serialize)]
struct Helper {
@ -247,7 +247,7 @@ impl Serialize for SourcePosition {
}
}
impl<'a> Serialize for Spanning<ParseError<'a>> {
impl Serialize for Spanning<ParseError> {
fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
let mut map = ser.serialize_map(Some(2))?;

View file

@ -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<ParseError<'a>>),
pub enum GraphQLError {
ParseError(Spanning<ParseError>),
ValidationError(Vec<RuleError>),
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<QueryT, MutationT, SubscriptionT, S>,
variables: &Variables<S>,
context: &QueryT::Context,
) -> Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError<'a>>
) -> Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError>
where
S: ScalarValue,
QueryT: GraphQLType<S>,
@ -172,7 +184,7 @@ pub async fn execute<'a, S, QueryT, MutationT, SubscriptionT>(
root_node: &'a RootNode<'a, QueryT, MutationT, SubscriptionT, S>,
variables: &Variables<S>,
context: &QueryT::Context,
) -> Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError<'a>>
) -> Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError>
where
QueryT: GraphQLTypeAsync<S>,
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<S>,
context: &'a QueryT::Context,
) -> Result<(Value<ValuesStream<'a, S>>, Vec<ExecutionError<S>>), GraphQLError<'a>>
) -> Result<(Value<ValuesStream<'a, S>>, Vec<ExecutionError<S>>), GraphQLError>
where
QueryT: GraphQLTypeAsync<S>,
QueryT::TypeInfo: Sync,
@ -259,7 +271,7 @@ pub fn introspect<'a, S, QueryT, MutationT, SubscriptionT>(
root_node: &'a RootNode<QueryT, MutationT, SubscriptionT, S>,
context: &QueryT::Context,
format: IntrospectionFormat,
) -> Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError<'a>>
) -> Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError>
where
S: ScalarValue,
QueryT: GraphQLType<S>,
@ -278,8 +290,8 @@ where
)
}
impl<'a> From<Spanning<ParseError<'a>>> for GraphQLError<'a> {
fn from(f: Spanning<ParseError<'a>>) -> GraphQLError<'a> {
GraphQLError::ParseError(f)
impl From<Spanning<ParseError>> for GraphQLError {
fn from(err: Spanning<ParseError>) -> Self {
Self::ParseError(err)
}
}

View file

@ -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<OwnedDocument<'a, S>>
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<OwnedDocument<'a, S>>
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<Definition<'a, S>>
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<Operation<'a, S>>
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<Fragment<'a, S>>
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<Selection<'a, S>>>
) -> OptionParseResult<Vec<Selection<'a, S>>>
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<Selection<'a, S>>>
) -> ParseResult<Vec<Selection<'a, S>>>
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<Selection<'a, S>>
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<Selection<'a, S>>
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<Field<'a, S>>
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<Arguments<'a, S>>
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<InputValue<S>>)>
) -> ParseResult<(Spanning<&'a str>, Spanning<InputValue<S>>)>
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<OperationType> {
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<VariableDefinitions<'a, S>>
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<Spanning<Directive<'a, S>>>>
) -> OptionParseResult<Vec<Spanning<Directive<'a, S>>>>
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<Directive<'a, S>>
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<Type<'a>> {
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<Type<'a>>,
) -> ParseResult<'a, Type<'a>> {
fn wrap_non_null<'a>(parser: &mut Parser<'a>, inner: Spanning<Type<'a>>) -> ParseResult<Type<'a>> {
let Spanning { end: end_pos, .. } = parser.expect(&Token::ExclamationMark)?;
let wrapped = match inner.item {

View file

@ -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<T>, Spanning<ParseError<'a>>>;
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<T, Spanning<ParseError<'a>>>;
pub type ParseResult<T> = Result<Spanning<T>, Spanning<ParseError>>;
#[doc(hidden)]
pub type OptionParseResult<'a, T> = Result<Option<Spanning<T>>, Spanning<ParseError<'a>>>;
pub type UnlocatedParseResult<T> = Result<T, Spanning<ParseError>>;
#[doc(hidden)]
pub type OptionParseResult<T> = Result<Option<Spanning<T>>, Spanning<ParseError>>;
#[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<Token<'a>> {
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<Token<'a>> {
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<Option<Spanning<Token<'a>>>, Spanning<ParseError<'a>>> {
) -> Result<Option<Spanning<Token<'a>>>, Spanning<ParseError>> {
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<Spanning<T>>>
) -> ParseResult<Vec<Spanning<T>>>
where
T: fmt::Debug,
F: Fn(&mut Parser<'a>) -> ParseResult<'a, T>,
F: Fn(&mut Parser<'a>) -> ParseResult<T>,
{
let Spanning {
start: start_pos, ..
@ -123,10 +164,10 @@ impl<'a> Parser<'a> {
opening: &Token,
parser: F,
closing: &Token,
) -> ParseResult<'a, Vec<Spanning<T>>>
) -> ParseResult<Vec<Spanning<T>>>
where
T: fmt::Debug,
F: Fn(&mut Parser<'a>) -> ParseResult<'a, T>,
F: Fn(&mut Parser<'a>) -> ParseResult<T>,
{
let Spanning {
start: start_pos, ..
@ -148,10 +189,10 @@ impl<'a> Parser<'a> {
opening: &Token,
parser: F,
closing: &Token,
) -> ParseResult<'a, Vec<T>>
) -> ParseResult<Vec<T>>
where
T: fmt::Debug,
F: Fn(&mut Parser<'a>) -> UnlocatedParseResult<'a, T>,
F: Fn(&mut Parser<'a>) -> UnlocatedParseResult<T>,
{
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> {}

View file

@ -19,10 +19,7 @@ where
.expect(&format!("Parse error on input {:#?}", s))
}
fn parse_document_error<'a, S>(s: &'a str) -> Spanning<ParseError<'a>>
where
S: ScalarValue,
{
fn parse_document_error<S: ScalarValue>(s: &str) -> Spanning<ParseError> {
match parse_document_source::<S>(
s,
&SchemaType::new::<QueryRoot, MutationRoot, SubscriptionRoot>(&(), &(), &()),
@ -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)
)
);
}

View file

@ -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<S>>
) -> ParseResult<InputValue<S>>
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<S>>
) -> ParseResult<InputValue<S>>
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<S>>
) -> ParseResult<InputValue<S>>
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<String>, Spanning<InputValue<S>>)>
) -> ParseResult<(Spanning<String>, Spanning<InputValue<S>>)>
where
S: ScalarValue,
{
@ -179,7 +179,7 @@ where
))
}
fn parse_variable_literal<'a, S>(parser: &mut Parser<'a>) -> ParseResult<'a, InputValue<S>>
fn parse_variable_literal<S>(parser: &mut Parser<'_>) -> ParseResult<InputValue<S>>
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<S>>
) -> ParseResult<InputValue<S>>
where
S: ScalarValue,
{

View file

@ -58,7 +58,7 @@ pub struct ScalarMeta<'a, S> {
pub type InputValueParseFn<S> = for<'b> fn(&'b InputValue<S>) -> Result<(), FieldError<S>>;
/// Shortcut for a [`ScalarToken`] parsing function.
pub type ScalarTokenParseFn<S> = for<'b> fn(ScalarToken<'b>) -> Result<S, ParseError<'b>>;
pub type ScalarTokenParseFn<S> = for<'b> fn(ScalarToken<'b>) -> Result<S, ParseError>;
/// List type metadata
#[derive(Debug)]

View file

@ -84,7 +84,7 @@ mod impl_string_scalar {
.ok_or_else(|| format!("Expected `String`, found: {}", v))
}
pub(super) fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> {
pub(super) fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<S> {
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<char, ParseError<'a>>
fn parse_unicode_codepoint<I>(char_iter: &mut I) -> Result<char, ParseError>
where
I: Iterator<Item = char>,
{
@ -285,9 +285,9 @@ mod impl_boolean_scalar {
.ok_or_else(|| format!("Expected `Boolean`, found: {}", v))
}
pub(super) fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> {
pub(super) fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<S> {
// `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<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> {
pub(super) fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<S> {
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<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> {
pub(super) fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<S> {
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))),
}
}
}

View file

@ -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<S, ParseError<'a>>;
pub type ParseScalarResult<S = DefaultScalarValue> = Result<S, ParseError>;
/// A trait used to convert a `ScalarToken` into a certain scalar value type
pub trait ParseScalarValue<S = DefaultScalarValue> {
/// See the trait documentation
fn from_str(value: ScalarToken<'_>) -> ParseScalarResult<'_, S>;
fn from_str(value: ScalarToken<'_>) -> ParseScalarResult<S>;
}
/// A trait marking a type that could be used as internal representation of

View file

@ -544,7 +544,7 @@ impl Definition {
{
fn from_str(
token: ::juniper::parser::ScalarToken<'_>,
) -> ::juniper::ParseScalarResult<'_, #scalar> {
) -> ::juniper::ParseScalarResult<#scalar> {
#from_str
}
}

View file

@ -497,7 +497,7 @@ pub fn derive_enum(input: TokenStream) -> TokenStream {
/// .ok_or_else(|| format!("Expected `String` or `Int`, found: {}", v))
/// }
///
/// fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> {
/// fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<S> {
/// <String as ParseScalarValue<S>>::from_str(value)
/// .or_else(|_| <i32 as ParseScalarValue<S>>::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<S: ScalarValue>(t: ScalarToken<'_>) -> ParseScalarResult<'_, S> {
/// pub(super) fn parse_token<S: ScalarValue>(t: ScalarToken<'_>) -> ParseScalarResult<S> {
/// <String as ParseScalarValue<S>>::from_str(t)
/// .or_else(|_| <i32 as ParseScalarValue<S>>::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<S>(value: ScalarToken<'_>) -> ParseScalarResult<'_, S>
/// fn parse_token<S>(value: ScalarToken<'_>) -> ParseScalarResult<S>
/// where
/// S: ScalarValue
/// {

View file

@ -358,10 +358,7 @@ enum SubscriptionStartState<S: Schema> {
id: String,
future: BoxFuture<
'static,
Result<
juniper_subscriptions::Connection<'static, S::ScalarValue>,
GraphQLError<'static>,
>,
Result<juniper_subscriptions::Connection<'static, S::ScalarValue>, 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),
}
}

View file

@ -32,7 +32,7 @@ pub struct DataPayload<S> {
// _execution_params).
pub struct ErrorPayload {
_execution_params: Option<Box<dyn Any + Send>>,
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<dyn Any + Send>,
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<GraphQLError<'static>> for ErrorPayload {
fn from(error: GraphQLError<'static>) -> Self {
impl From<GraphQLError> for ErrorPayload {
fn from(error: GraphQLError) -> Self {
Self {
_execution_params: None,
error,

View file

@ -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,

View file

@ -32,7 +32,7 @@ mod trivial {
.ok_or_else(|| format!("Expected `Counter`, found: {}", v))
}
fn parse_token<S: ScalarValue>(t: ScalarToken<'_>) -> ParseScalarResult<'_, S> {
fn parse_token<S: ScalarValue>(t: ScalarToken<'_>) -> ParseScalarResult<S> {
<i32 as ParseScalarValue<S>>::from_str(t)
}
}
@ -240,7 +240,7 @@ mod all_custom_resolvers {
.ok_or_else(|| format!("Expected `Counter`, found: {}", v))
}
fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> {
fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<S> {
<i32 as ParseScalarValue<S>>::from_str(value)
}
@ -315,7 +315,7 @@ mod explicit_name {
.ok_or_else(|| format!("Expected `Counter`, found: {}", v))
}
fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> {
fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<S> {
<i32 as ParseScalarValue<S>>::from_str(value)
}
}
@ -602,7 +602,7 @@ mod with_self {
.ok_or_else(|| format!("Expected `Counter`, found: {}", v))
}
fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> {
fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<S> {
<i32 as ParseScalarValue<S>>::from_str(value)
}
}

View file

@ -37,7 +37,7 @@ mod all_custom_resolvers {
.ok_or_else(|| format!("Expected `Counter`, found: {}", v))
}
fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> {
fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<S> {
<i32 as ParseScalarValue<S>>::from_str(value)
}
@ -118,7 +118,7 @@ mod explicit_name {
.ok_or_else(|| format!("Expected `Counter`, found: {}", v))
}
fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> {
fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<S> {
<i32 as ParseScalarValue<S>>::from_str(value)
}
@ -437,7 +437,7 @@ mod with_self {
.ok_or_else(|| format!("Expected `Counter`, found: {}", v))
}
fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> {
fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<S> {
<i32 as ParseScalarValue<S>>::from_str(value)
}
}

View file

@ -30,7 +30,7 @@ mod trivial {
.ok_or_else(|| format!("Expected `Counter`, found: {}", v))
}
fn parse_token<S: ScalarValue>(t: ScalarToken<'_>) -> ParseScalarResult<'_, S> {
fn parse_token<S: ScalarValue>(t: ScalarToken<'_>) -> ParseScalarResult<S> {
<i32 as ParseScalarValue<S>>::from_str(t)
}
}
@ -238,7 +238,7 @@ mod all_custom_resolvers {
.ok_or_else(|| format!("Expected `Counter`, found: {}", v))
}
fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> {
fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<S> {
<i32 as ParseScalarValue<S>>::from_str(value)
}
@ -314,7 +314,7 @@ mod explicit_name {
.ok_or_else(|| format!("Expected `Counter`, found: {}", v))
}
fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> {
fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<S> {
<i32 as ParseScalarValue<S>>::from_str(value)
}
}
@ -605,7 +605,7 @@ mod with_self {
.ok_or_else(|| format!("Expected `Counter`, found: {}", v))
}
fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> {
fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<S> {
<i32 as ParseScalarValue<S>>::from_str(value)
}
}

View file

@ -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<MyScalarValue> {
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)))
}
}
}

View file

@ -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<ValuesStream<'a, S>>, Vec<ExecutionError<S>>), GraphQLError<'a>>,
) -> Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError<'a>> {
pub(crate) async fn extract_next<S: ScalarValue>(
input: Result<(Value<ValuesStream<'_, S>>, Vec<ExecutionError<S>>), GraphQLError>,
) -> Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError> {
let (stream, errs) = input?;
if !errs.is_empty() {
return Ok((Value::Null, errs));