Merge pull request #44 from Mrmaxmeier/remove-parser-panic

Remove panic in Parser::next
This commit is contained in:
Magnus Hallin 2017-04-30 14:07:19 +02:00 committed by GitHub
commit 032b03add3
4 changed files with 27 additions and 25 deletions

View file

@ -31,7 +31,7 @@ fn parse_definition<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Def
Ok(Definition::Operation(try!(parse_operation_definition(parser)))),
Token::Name("fragment") =>
Ok(Definition::Fragment(try!(parse_fragment_definition(parser)))),
_ => Err(parser.next().map(ParseError::UnexpectedToken)),
_ => Err(parser.next()?.map(ParseError::UnexpectedToken)),
}
}
@ -130,7 +130,7 @@ fn parse_fragment<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Selec
match parser.peek().item {
Token::Name("on") => {
parser.next();
parser.next()?;
let name = try!(parser.expect_name());
let directives = try!(parse_directives(parser));
let selection_set = try!(parse_selection_set(parser));
@ -185,7 +185,7 @@ fn parse_fragment<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Selec
selection_set: selection_set.item,
})))
},
_ => Err(parser.next().map(ParseError::UnexpectedToken)),
_ => Err(parser.next()?.map(ParseError::UnexpectedToken)),
}
}
@ -244,9 +244,9 @@ fn parse_argument<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, (Spanning<&'a
fn parse_operation_type<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, OperationType> {
match parser.peek().item {
Token::Name("query") => Ok(parser.next().map(|_| OperationType::Query)),
Token::Name("mutation") => Ok(parser.next().map(|_| OperationType::Mutation)),
_ => Err(parser.next().map(ParseError::UnexpectedToken))
Token::Name("query") => Ok(parser.next()?.map(|_| OperationType::Query)),
Token::Name("mutation") => Ok(parser.next()?.map(|_| OperationType::Mutation)),
_ => Err(parser.next()?.map(ParseError::UnexpectedToken))
}
}

View file

@ -54,28 +54,31 @@ impl<'a> Parser<'a> {
}
#[doc(hidden)]
pub fn next(&mut self) -> Spanning<Token<'a>> {
pub fn next(&mut self) -> ParseResult<'a, Token<'a>> {
if self.tokens.len() == 1 {
panic!("Can not parse over EOF marker");
Err(Spanning::start_end(
&self.peek().start.clone(),
&self.peek().end.clone(),
ParseError::UnexpectedEndOfFile))
} else {
Ok(self.tokens.remove(0))
}
self.tokens.remove(0)
}
#[doc(hidden)]
pub fn expect(&mut self, expected: &Token) -> ParseResult<'a, Token<'a>> {
if &self.peek().item != expected {
Err(self.next().map(ParseError::UnexpectedToken))
Err(self.next()?.map(ParseError::UnexpectedToken))
}
else {
Ok(self.next())
self.next()
}
}
#[doc(hidden)]
pub fn skip(&mut self, expected: &Token) -> Result<Option<Spanning<Token<'a>>>, Spanning<ParseError<'a>>> {
if &self.peek().item == expected {
Ok(Some(self.next()))
Ok(Some(self.next()?))
}
else if self.peek().item == Token::EndOfFile {
Err(Spanning::zero_width(
@ -151,7 +154,7 @@ impl<'a> Parser<'a> {
pub fn expect_name(&mut self) -> ParseResult<'a, &'a str> {
match *self.peek() {
Spanning { item: Token::Name(_), .. } =>
Ok(self.next().map(|token|
Ok(self.next()?.map(|token|
if let Token::Name(name) = token {
name
}
@ -163,7 +166,7 @@ impl<'a> Parser<'a> {
&self.peek().start.clone(),
&self.peek().end.clone(),
ParseError::UnexpectedEndOfFile)),
_ => Err(self.next().map(ParseError::UnexpectedToken)),
_ => Err(self.next()?.map(ParseError::UnexpectedToken)),
}
}
}

View file

@ -108,8 +108,7 @@ impl<T> PartialEq for Spanning<T> where T: PartialEq + fmt::Debug {
}
}
impl<T> Eq for Spanning<T> where T: Eq + fmt::Debug {
}
impl<T> Eq for Spanning<T> where T: Eq + fmt::Debug {}
impl<T> Hash for Spanning<T> where T: Hash + fmt::Debug {
fn hash<H: Hasher>(&self, state: &mut H) {

View file

@ -8,11 +8,11 @@ pub fn parse_value_literal<'a>(parser: &mut Parser<'a>, is_const: bool) -> Parse
Spanning { item: Token::CurlyOpen, .. } => parse_object_literal(parser, is_const),
Spanning { item: Token::Dollar, .. } if !is_const => parse_variable_literal(parser),
Spanning { item: Token::Int(i), .. } =>
Ok(parser.next().map(|_| InputValue::int(i))),
Ok(parser.next()?.map(|_| InputValue::int(i))),
Spanning { item: Token::Float(f), .. } =>
Ok(parser.next().map(|_| InputValue::float(f))),
Ok(parser.next()?.map(|_| InputValue::float(f))),
Spanning { item: Token::String(_), .. } =>
Ok(parser.next().map(|t|
Ok(parser.next()?.map(|t|
if let Token::String(s) = t {
InputValue::string(s)
}
@ -20,14 +20,14 @@ pub fn parse_value_literal<'a>(parser: &mut Parser<'a>, is_const: bool) -> Parse
panic!("Internal parser error");
})),
Spanning { item: Token::Name("true"), .. } =>
Ok(parser.next().map(|_| InputValue::boolean(true))),
Ok(parser.next()?.map(|_| InputValue::boolean(true))),
Spanning { item: Token::Name("false"), .. } =>
Ok(parser.next().map(|_| InputValue::boolean(false))),
Ok(parser.next()?.map(|_| InputValue::boolean(false))),
Spanning { item: Token::Name("null"), .. } =>
Ok(parser.next().map(|_| InputValue::null())),
Ok(parser.next()?.map(|_| InputValue::null())),
Spanning { item: Token::Name(name), .. } =>
Ok(parser.next().map(|_| InputValue::enum_value(name.to_owned()))),
_ => Err(parser.next().map(ParseError::UnexpectedToken)),
Ok(parser.next()?.map(|_| InputValue::enum_value(name.to_owned()))),
_ => Err(parser.next()?.map(ParseError::UnexpectedToken)),
}
}