diff --git a/Cargo.toml b/Cargo.toml index acd7659..dcf9e18 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ authors = ["Paul Colomiets "] edition = "2018" [dependencies] -combine = "3.2.0" +combine = "4.6.0" thiserror = "1.0.11" [dev-dependencies] diff --git a/src/common.rs b/src/common.rs index c5189fa..ae6521d 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,9 +1,8 @@ use std::{fmt, collections::BTreeMap}; -use combine::{parser, ParseResult, Parser}; +use combine::{parser, StdParseResult, Parser, many, many1, optional, position, choice}; use combine::easy::Error; use combine::error::StreamError; -use combine::combinator::{many, many1, optional, position, choice}; use crate::tokenizer::{Kind as T, Token, TokenStream}; use crate::helpers::{punct, ident, kind, name}; @@ -12,7 +11,7 @@ use crate::position::Pos; /// Text abstracts over types that hold a string value. /// It is used to make the AST generic over the string type. pub trait Text<'a>: 'a { - type Value: 'a + From<&'a str> + AsRef + std::borrow::Borrow + PartialEq + Eq + PartialOrd + Ord + fmt::Debug + Clone; + type Value: 'a + From<&'a str> + AsRef + std::borrow::Borrow + PartialEq + Eq + PartialOrd + Ord + fmt::Debug + Clone; } impl<'a> Text<'a> for &'a str { @@ -98,9 +97,8 @@ impl From for Number { } } -pub fn directives<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult>, TokenStream<'a>> - where T: Text<'a>, +pub fn directives<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult>, TokenStream<'a>> + where T: Text<'a>, { many(position() .skip(punct("@")) @@ -109,11 +107,10 @@ pub fn directives<'a, T>(input: &mut TokenStream<'a>) .map(|((position, name), arguments)| { Directive { position, name, arguments } })) - .parse_stream(input) + .parse_stream(input).into() } -pub fn arguments<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult)>, TokenStream<'a>> +pub fn arguments<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult)>, TokenStream<'a>> where T: Text<'a>, { optional( @@ -125,25 +122,23 @@ pub fn arguments<'a, T>(input: &mut TokenStream<'a>) .map(|opt| { opt.unwrap_or_else(Vec::new) }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn int_value<'a, S>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn int_value<'a, S>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where S: Text<'a> { kind(T::IntValue).and_then(|tok| tok.value.parse()) .map(Number).map(Value::Int) - .parse_stream(input) + .parse_stream(input).into() } -pub fn float_value<'a, S>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn float_value<'a, S>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where S: Text<'a> { kind(T::FloatValue).and_then(|tok| tok.value.parse()) .map(Value::Float) - .parse_stream(input) + .parse_stream(input).into() } fn unquote_block_string<'a>(src: &'a str) -> Result, Token<'a>>> { @@ -182,7 +177,7 @@ fn unquote_block_string<'a>(src: &'a str) -> Result, Tok Ok(result) } -fn unquote_string<'a>(s: &'a str) -> Result> +fn unquote_string<'a>(s: &'a str) -> Result> { let mut res = String::with_capacity(s.len()); debug_assert!(s.starts_with('"') && s.ends_with('"')); @@ -203,7 +198,7 @@ fn unquote_string<'a>(s: &'a str) -> Result> for _ in 0..4 { match chars.next() { Some(inner_c) => temp_code_point.push(inner_c), - None => return Err(Error::unexpected_message( + None => return Err(Error::unexpected_format( format_args!("\\u must have 4 characters after it, only found '{}'", temp_code_point) )), } @@ -213,13 +208,13 @@ fn unquote_string<'a>(s: &'a str) -> Result> match u32::from_str_radix(&temp_code_point, 16).map(std::char::from_u32) { Ok(Some(unicode_char)) => res.push(unicode_char), _ => { - return Err(Error::unexpected_message( + return Err(Error::unexpected_format( format_args!("{} is not a valid unicode code point", temp_code_point))) } } }, c => { - return Err(Error::unexpected_message( + return Err(Error::unexpected_format( format_args!("bad escaped char {:?}", c))); } } @@ -231,35 +226,31 @@ fn unquote_string<'a>(s: &'a str) -> Result> Ok(res) } -pub fn string<'a>(input: &mut TokenStream<'a>) - -> ParseResult> +pub fn string<'a>(input: &mut TokenStream<'a>) -> StdParseResult> { choice(( kind(T::StringValue).and_then(|tok| unquote_string(tok.value)), kind(T::BlockString).and_then(|tok| unquote_block_string(tok.value)), - )).parse_stream(input) + )).parse_stream(input).into() } -pub fn string_value<'a, S>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn string_value<'a, S>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where S: Text<'a>, { kind(T::StringValue).and_then(|tok| unquote_string(tok.value)) .map(Value::String) - .parse_stream(input) + .parse_stream(input).into() } -pub fn block_string_value<'a, S>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn block_string_value<'a, S>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where S: Text<'a>, { kind(T::BlockString).and_then(|tok| unquote_block_string(tok.value)) .map(Value::String) - .parse_stream(input) + .parse_stream(input).into() } -pub fn plain_value<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn plain_value<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { ident("true").map(|_| Value::Boolean(true)) @@ -270,11 +261,10 @@ pub fn plain_value<'a, T>(input: &mut TokenStream<'a>) .or(parser(float_value)) .or(parser(string_value)) .or(parser(block_string_value)) - .parse_stream(input) + .parse_stream(input).into() } -pub fn value<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn value<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { parser(plain_value) @@ -285,11 +275,10 @@ pub fn value<'a, T>(input: &mut TokenStream<'a>) .with(many(name::<'a, T>().skip(punct(":")).and(parser(value)))) .skip(punct("}")) .map(Value::Object)) - .parse_stream(input) + .parse_stream(input).into() } -pub fn default_value<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn default_value<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { parser(plain_value) @@ -299,11 +288,10 @@ pub fn default_value<'a, T>(input: &mut TokenStream<'a>) .with(many(name::<'a, T>().skip(punct(":")).and(parser(default_value)))) .skip(punct("}")) .map(Value::Object)) - .parse_stream(input) + .parse_stream(input).into() } -pub fn parse_type<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn parse_type<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { name::<'a, T>().map(Type::NamedType) @@ -320,7 +308,7 @@ pub fn parse_type<'a, T>(input: &mut TokenStream<'a>) typ } ) - .parse_stream(input) + .parse_stream(input).into() } #[cfg(test)] diff --git a/src/helpers.rs b/src/helpers.rs index 079cbd2..48402f2 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -1,6 +1,6 @@ use std::marker::PhantomData; -use combine::{Parser, ConsumedResult, satisfy, StreamOnce}; +use combine::{Parser, ParseResult, satisfy, StreamOnce}; use combine::error::{Tracked}; use combine::stream::easy::{Error, Errors, Info}; @@ -17,7 +17,7 @@ pub struct TokenMatch<'a> { } #[derive(Debug, Clone)] -pub struct NameMatch<'a, T> +pub struct NameMatch<'a, T> where T: Text<'a> { phantom: PhantomData<&'a T>, @@ -38,7 +38,7 @@ pub fn kind<'x>(kind: Kind) -> TokenMatch<'x> { } } -pub fn name<'a, T>() -> NameMatch<'a, T> +pub fn name<'a, T>() -> NameMatch<'a, T> where T: Text<'a> { NameMatch { @@ -46,21 +46,16 @@ pub fn name<'a, T>() -> NameMatch<'a, T> } } -impl<'a> Parser for TokenMatch<'a> { - type Input = TokenStream<'a>; +impl<'a> Parser> for TokenMatch<'a> { type Output = Token<'a>; type PartialState = (); #[inline] - fn parse_lazy(&mut self, input: &mut Self::Input) - -> ConsumedResult - { + fn parse_lazy(&mut self, input: &mut TokenStream<'a>) -> ParseResult as StreamOnce>::Error> { satisfy(|c: Token<'a>| c.kind == self.kind).parse_lazy(input) } - fn add_error(&mut self, - error: &mut Tracked, Token<'a>, Pos>>) - { + fn add_error(&mut self, error: &mut Tracked, Token<'a>, Pos>>) { error.error.add_error(Error::Expected(Info::Owned( format!("{:?}", self.kind)))); } @@ -82,38 +77,32 @@ pub fn ident<'s>(value: &'static str) -> Value<'s> { } } -impl<'a> Parser for Value<'a> { - type Input = TokenStream<'a>; +impl<'a> Parser> for Value<'a> { type Output = Token<'a>; type PartialState = (); #[inline] - fn parse_lazy(&mut self, input: &mut Self::Input) - -> ConsumedResult - { + fn parse_lazy(&mut self, input: &mut TokenStream<'a>) -> ParseResult as StreamOnce>::Error> { satisfy(|c: Token<'a>| { c.kind == self.kind && c.value == self.value }).parse_lazy(input) } fn add_error(&mut self, - error: &mut Tracked<::Error>) + error: &mut Tracked< as StreamOnce>::Error>) { - error.error.add_error(Error::Expected(Info::Borrowed(self.value))); + error.error.add_error(Error::Expected(Info::Static(self.value))); } } -impl<'a, S> Parser for NameMatch<'a, S> +impl<'a, S> Parser> for NameMatch<'a, S> where S: Text<'a>, { - type Input = TokenStream<'a>; type Output = S::Value; type PartialState = (); #[inline] - fn parse_lazy(&mut self, input: &mut Self::Input) - -> ConsumedResult - { + fn parse_lazy(&mut self, input: &mut TokenStream<'a>) -> ParseResult as StreamOnce>::Error> { satisfy(|c: Token<'a>| c.kind == Kind::Name) .map(|t: Token<'a>| -> S::Value { S::Value::from(t.value) } ) .parse_lazy(input) @@ -122,6 +111,6 @@ impl<'a, S> Parser for NameMatch<'a, S> fn add_error(&mut self, error: &mut Tracked, Token<'a>, Pos>>) { - error.error.add_error(Error::Expected(Info::Borrowed("Name"))); + error.error.add_error(Error::Expected(Info::Static("Name"))); } } diff --git a/src/query/grammar.rs b/src/query/grammar.rs index 363fc16..6f33732 100644 --- a/src/query/grammar.rs +++ b/src/query/grammar.rs @@ -1,5 +1,4 @@ -use combine::{parser, ParseResult, Parser}; -use combine::combinator::{many1, eof, optional, position}; +use combine::{parser, StdParseResult, Parser, many1, eof, optional, position}; use crate::common::{Directive}; use crate::common::{directives, arguments, default_value, parse_type}; @@ -8,8 +7,7 @@ use crate::helpers::{punct, ident, name}; use crate::query::error::{ParseError}; use crate::query::ast::*; -pub fn field<'a, S>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn field<'a, S>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where S: Text<'a> { ( @@ -34,11 +32,10 @@ pub fn field<'a, S>(input: &mut TokenStream<'a>) }), } }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn selection<'a, S>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn selection<'a, S>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where S: Text<'a> { parser(field).map(Selection::Field) @@ -60,11 +57,10 @@ pub fn selection<'a, S>(input: &mut TokenStream<'a>) }) .map(Selection::FragmentSpread)) )) - .parse_stream(input) + .parse_stream(input).into() } -pub fn selection_set<'a, S>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn selection_set<'a, S>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where S: Text<'a>, { ( @@ -72,11 +68,10 @@ pub fn selection_set<'a, S>(input: &mut TokenStream<'a>) many1(parser(selection)), position().skip(punct("}")), ).map(|(start, items, end)| SelectionSet { span: (start, end), items }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn query<'a, T: Text<'a>>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn query<'a, T: Text<'a>>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { position() @@ -86,7 +81,7 @@ pub fn query<'a, T: Text<'a>>(input: &mut TokenStream<'a>) Query { position, name, selection_set, variable_definitions, directives, }) - .parse_stream(input) + .parse_stream(input).into() } /// A set of attributes common to a Query and a Mutation @@ -98,8 +93,7 @@ type OperationCommon<'a, T: Text<'a>> = ( SelectionSet<'a, T>, ); -pub fn operation_common<'a, T: Text<'a>>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn operation_common<'a, T: Text<'a>>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { optional(name::<'a, T>()) @@ -123,11 +117,10 @@ pub fn operation_common<'a, T: Text<'a>>(input: &mut TokenStream<'a>) .and(parser(directives)) .and(parser(selection_set)) .map(|(((a, b), c), d)| (a, b, c, d)) - .parse_stream(input) + .parse_stream(input).into() } -pub fn mutation<'a, T: Text<'a>>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn mutation<'a, T: Text<'a>>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { position() @@ -137,11 +130,10 @@ pub fn mutation<'a, T: Text<'a>>(input: &mut TokenStream<'a>) Mutation { position, name, selection_set, variable_definitions, directives, }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn subscription<'a, T: Text<'a>>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn subscription<'a, T: Text<'a>>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { position() @@ -151,22 +143,20 @@ pub fn subscription<'a, T: Text<'a>>(input: &mut TokenStream<'a>) Subscription { position, name, selection_set, variable_definitions, directives, }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn operation_definition<'a, S>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn operation_definition<'a, S>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where S: Text<'a>, { parser(selection_set).map(OperationDefinition::SelectionSet) .or(parser(query).map(OperationDefinition::Query)) .or(parser(mutation).map(OperationDefinition::Mutation)) .or(parser(subscription).map(OperationDefinition::Subscription)) - .parse_stream(input) + .parse_stream(input).into() } -pub fn fragment_definition<'a, T: Text<'a>>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn fragment_definition<'a, T: Text<'a>>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { ( @@ -180,16 +170,15 @@ pub fn fragment_definition<'a, T: Text<'a>>(input: &mut TokenStream<'a>) position, name, type_condition, directives, selection_set, } }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn definition<'a, S>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn definition<'a, S>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where S: Text<'a>, { parser(operation_definition).map(Definition::Operation) .or(parser(fragment_definition).map(Definition::Fragment)) - .parse_stream(input) + .parse_stream(input).into() } /// Parses a piece of query language and returns an AST @@ -197,13 +186,12 @@ pub fn parse_query<'a, S>(s: &'a str) -> Result, ParseError> where S: Text<'a>, { let mut tokens = TokenStream::new(s); - let (doc, _) = many1(parser(definition)) - .map(|d| Document { definitions: d }) - .skip(eof()) - .parse_stream(&mut tokens) - .map_err(|e| e.into_inner().error)?; - - Ok(doc) + match many1(parser(definition)).map(|d| Document { definitions: d }) .skip(eof()) .parse_stream(&mut tokens) { + combine::ParseResult::CommitOk(doc) => Ok(doc), + combine::ParseResult::PeekOk(doc) => Ok(doc), + combine::ParseResult::CommitErr(err) => Err(err.into()), + combine::ParseResult::PeekErr(err) => Err(err.error.into()), + } } /// Parses a single ExecutableDefinition and returns an AST as well as the diff --git a/src/schema/grammar.rs b/src/schema/grammar.rs index ee31bda..1d00a3e 100644 --- a/src/schema/grammar.rs +++ b/src/schema/grammar.rs @@ -1,8 +1,6 @@ -use combine::{parser, ParseResult, Parser}; +use combine::{parser, StdParseResult, Parser, sep_by1, many, many1, eof, optional, position, choice}; use combine::easy::{Error, Errors}; use combine::error::StreamError; -use combine::combinator::{many, many1, eof, optional, position, choice}; -use combine::combinator::{sep_by1}; use crate::tokenizer::{Kind as T, Token, TokenStream}; use crate::helpers::{punct, ident, kind, name}; @@ -11,8 +9,7 @@ use crate::schema::error::{ParseError}; use crate::schema::ast::*; -pub fn schema<'a, S>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn schema<'a, S>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where S: Text<'a>, { ( @@ -71,11 +68,10 @@ pub fn schema<'a, S>(input: &mut TokenStream<'a>) position, directives, query, mutation, subscription, }) }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn scalar_type<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn scalar_type<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { ( @@ -86,11 +82,10 @@ pub fn scalar_type<'a, T>(input: &mut TokenStream<'a>) .map(|(position, name, directives)| { ScalarType { position, description: None, name, directives } }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn scalar_type_extension<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn scalar_type_extension<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { ( @@ -108,11 +103,10 @@ pub fn scalar_type_extension<'a, T>(input: &mut TokenStream<'a>) } Ok(ScalarTypeExtension { position, name, directives }) }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn implements_interfaces<'a, X>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn implements_interfaces<'a, X>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where X: Text<'a>, { optional( @@ -121,11 +115,10 @@ pub fn implements_interfaces<'a, X>(input: &mut TokenStream<'a>) .with(sep_by1(name::<'a, X>(), punct("&"))) ) .map(|opt| opt.unwrap_or_else(Vec::new)) - .parse_stream(input) + .parse_stream(input).into() } -pub fn input_value<'a, X>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn input_value<'a, X>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where X: Text<'a>, { ( @@ -142,20 +135,18 @@ pub fn input_value<'a, X>(input: &mut TokenStream<'a>) position, description, name, value_type, default_value, directives, } }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn arguments_definition<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult>, TokenStream<'a>> +pub fn arguments_definition<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult>, TokenStream<'a>> where T: Text<'a>, { optional(punct("(").with(many1(parser(input_value))).skip(punct(")"))) .map(|v| v.unwrap_or_else(Vec::new)) - .parse_stream(input) + .parse_stream(input).into() } -pub fn field<'a, S>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn field<'a, S>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where S: Text<'a>, { ( @@ -171,21 +162,19 @@ pub fn field<'a, S>(input: &mut TokenStream<'a>) position, description, name, arguments, field_type, directives } }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn fields<'a, S>(input: &mut TokenStream<'a>) - -> ParseResult>, TokenStream<'a>> +pub fn fields<'a, S>(input: &mut TokenStream<'a>) -> StdParseResult>, TokenStream<'a>> where S: Text<'a>, { optional(punct("{").with(many1(parser(field))).skip(punct("}"))) .map(|v| v.unwrap_or_else(Vec::new)) - .parse_stream(input) + .parse_stream(input).into() } -pub fn object_type<'a, S>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn object_type<'a, S>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where S: Text<'a>, { ( @@ -202,11 +191,10 @@ pub fn object_type<'a, S>(input: &mut TokenStream<'a>) description: None, // is filled in described_definition } }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn object_type_extension<'a, S>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn object_type_extension<'a, S>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where S: Text<'a>, { ( @@ -231,11 +219,10 @@ pub fn object_type_extension<'a, S>(input: &mut TokenStream<'a>) implements_interfaces: interfaces, }) }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn interface_type<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn interface_type<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { ( @@ -253,11 +240,10 @@ pub fn interface_type<'a, T>(input: &mut TokenStream<'a>) description: None, // is filled in described_definition } }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn interface_type_extension<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn interface_type_extension<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { ( @@ -281,20 +267,18 @@ pub fn interface_type_extension<'a, T>(input: &mut TokenStream<'a>) directives, fields, }) }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn union_members<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn union_members<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { optional(punct("|")) .with(sep_by1(name::<'a, T>(), punct("|"))) - .parse_stream(input) + .parse_stream(input).into() } -pub fn union_type<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn union_type<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { ( @@ -310,11 +294,10 @@ pub fn union_type<'a, T>(input: &mut TokenStream<'a>) description: None, // is filled in described_definition } }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn union_type_extension<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn union_type_extension<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { ( @@ -336,11 +319,10 @@ pub fn union_type_extension<'a, T>(input: &mut TokenStream<'a>) types: types.unwrap_or_else(Vec::new), }) }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn enum_values<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult>, TokenStream<'a>> +pub fn enum_values<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult>, TokenStream<'a>> where T: Text<'a>, { punct("{") @@ -356,11 +338,10 @@ pub fn enum_values<'a, T>(input: &mut TokenStream<'a>) }) )) .skip(punct("}")) - .parse_stream(input) + .parse_stream(input).into() } -pub fn enum_type<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn enum_type<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { ( @@ -376,11 +357,10 @@ pub fn enum_type<'a, T>(input: &mut TokenStream<'a>) description: None, // is filled in described_definition } }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn enum_type_extension<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn enum_type_extension<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { ( @@ -402,20 +382,18 @@ pub fn enum_type_extension<'a, T>(input: &mut TokenStream<'a>) values: values.unwrap_or_else(Vec::new), }) }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn input_fields<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult>, TokenStream<'a>> +pub fn input_fields<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult>, TokenStream<'a>> where T: Text<'a>, { optional(punct("{").with(many1(parser(input_value))).skip(punct("}"))) .map(|v| v.unwrap_or_else(Vec::new)) - .parse_stream(input) + .parse_stream(input).into() } -pub fn input_object_type<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn input_object_type<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { ( @@ -430,11 +408,10 @@ pub fn input_object_type<'a, T>(input: &mut TokenStream<'a>) description: None, // is filled in described_definition } }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn input_object_type_extension<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn input_object_type_extension<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { ( @@ -455,11 +432,10 @@ pub fn input_object_type_extension<'a, T>(input: &mut TokenStream<'a>) position, name, directives, fields, }) }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn directive_locations<'a>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn directive_locations<'a>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> { optional( optional(punct("|")) @@ -469,11 +445,10 @@ pub fn directive_locations<'a>(input: &mut TokenStream<'a>) punct("|"))) ) .map(|opt| opt.unwrap_or_else(Vec::new)) - .parse_stream(input) + .parse_stream(input).into() } -pub fn directive_definition<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn directive_definition<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { ( @@ -490,11 +465,10 @@ pub fn directive_definition<'a, T>(input: &mut TokenStream<'a>) description: None, // is filled in described_definition } }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn described_definition<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn described_definition<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { use self::TypeDefinition::*; @@ -532,11 +506,10 @@ pub fn described_definition<'a, T>(input: &mut TokenStream<'a>) } def }) - .parse_stream(input) + .parse_stream(input).into() } -pub fn type_extension<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn type_extension<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { ident("extend") @@ -548,19 +521,18 @@ pub fn type_extension<'a, T>(input: &mut TokenStream<'a>) parser(enum_type_extension).map(TypeExtension::Enum), parser(input_object_type_extension).map(TypeExtension::InputObject), ))) - .parse_stream(input) + .parse_stream(input).into() } -pub fn definition<'a, T>(input: &mut TokenStream<'a>) - -> ParseResult, TokenStream<'a>> +pub fn definition<'a, T>(input: &mut TokenStream<'a>) -> StdParseResult, TokenStream<'a>> where T: Text<'a>, { choice(( parser(schema).map(Definition::SchemaDefinition), parser(type_extension).map(Definition::TypeExtension), parser(described_definition), - )).parse_stream(input) + )).parse_stream(input).into() } /// Parses a piece of schema language and returns an AST @@ -568,13 +540,12 @@ pub fn parse_schema<'a, T>(s: &'a str) -> Result, ParseError> where T: Text<'a>, { let mut tokens = TokenStream::new(s); - let (doc, _) = many1(parser(definition)) - .map(|d| Document { definitions: d }) - .skip(eof()) - .parse_stream(&mut tokens) - .map_err(|e| e.into_inner().error)?; - - Ok(doc) + match many1(parser(definition)).map(|d| Document { definitions: d }).skip(eof()).parse_stream(&mut tokens) { + combine::ParseResult::CommitOk(doc) => Ok(doc), + combine::ParseResult::PeekOk(doc) => Ok(doc), + combine::ParseResult::CommitErr(err) => Err(err.into()), + combine::ParseResult::PeekErr(err) => Err(err.error.into()), + } } diff --git a/src/tokenizer.rs b/src/tokenizer.rs index 1bec4ab..1f192f5 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -2,7 +2,7 @@ use std::fmt; use combine::{StreamOnce, Positioned}; use combine::error::{StreamError}; -use combine::stream::{Resetable}; +use combine::stream::{ResetStream}; use combine::easy::{Error, Errors}; use crate::position::Pos; @@ -46,12 +46,12 @@ pub struct Checkpoint { } impl<'a> StreamOnce for TokenStream<'a> { - type Item = Token<'a>; + type Token = Token<'a>; type Range = Token<'a>; type Position = Pos; type Error = Errors, Token<'a>, Pos>; - fn uncons(&mut self) -> Result, Token<'a>>> { + fn uncons(&mut self) -> Result> { if let Some((at, tok, off, pos)) = self.next_state { if at == self.off { self.off = off; @@ -75,7 +75,7 @@ impl<'a> Positioned for TokenStream<'a> { } } -impl<'a> Resetable for TokenStream<'a> { +impl<'a> ResetStream for TokenStream<'a> { type Checkpoint = Checkpoint; fn checkpoint(&self) -> Self::Checkpoint { Checkpoint { @@ -83,9 +83,10 @@ impl<'a> Resetable for TokenStream<'a> { off: self.off, } } - fn reset(&mut self, checkpoint: Checkpoint) { + fn reset(&mut self, checkpoint: Checkpoint) -> Result<(), Self::Error> { self.position = checkpoint.position; self.off = checkpoint.off; + Ok(()) } } @@ -185,7 +186,7 @@ impl<'a> TokenStream<'a> { // seem like this would be a good place to handle that, // but instead this code allows this token to propagate up // to the parser which is better equipped to make specific - // error messages about unmatched pairs. + // error messages about unmatched pairs. // The case where recursion limit would overflow but instead // saturates is just a specific case of the more general // occurrence above. @@ -198,7 +199,7 @@ impl<'a> TokenStream<'a> { self.advance_token(Punctuator, 3) } else { Err( - Error::unexpected_message( + Error::unexpected_format( format_args!("bare dot {:?} is not supported, \ only \"...\"", cur_char) ) @@ -242,7 +243,7 @@ impl<'a> TokenStream<'a> { let value = &self.buf[self.off..][..len]; if !check_float(value, exponent, real) { return Err( - Error::unexpected_message( + Error::unexpected_format( format_args!("unsupported float {:?}", value) ) ); @@ -255,7 +256,7 @@ impl<'a> TokenStream<'a> { let value = &self.buf[self.off..][..len]; if !check_int(value) { return Err( - Error::unexpected_message( + Error::unexpected_format( format_args!("unsupported integer {:?}", value) ) ); @@ -274,7 +275,7 @@ impl<'a> TokenStream<'a> { } Err( - Error::unexpected_message( + Error::unexpected_static_message( "unterminated block string value" ) ) @@ -292,7 +293,7 @@ impl<'a> TokenStream<'a> { } '\n' => { return Err( - Error::unexpected_message( + Error::unexpected_static_message( "unterminated string value" ) ); @@ -307,14 +308,14 @@ impl<'a> TokenStream<'a> { escaped = !escaped && cur_char == '\\'; } Err( - Error::unexpected_message( + Error::unexpected_static_message( "unterminated string value" ) ) } } _ => Err( - Error::unexpected_message( + Error::unexpected_format( format_args!("unexpected character {:?}", cur_char) ) ),