diff --git a/ffi/src/helpers.rs b/ffi/src/helpers.rs index 08f5759..18545d9 100644 --- a/ffi/src/helpers.rs +++ b/ffi/src/helpers.rs @@ -23,6 +23,7 @@ pub fn handle_error(err: Error) -> c_int { fn map_error(err: &Error) -> c_int { match err { Error::ParsingIncomplete => LCI_ERROR_PARSING_ERROR, + Error::UnconsumedInput(_) => LCI_ERROR_PARSING_ERROR, Error::GenericParsingError(_, _) => LCI_ERROR_PARSING_ERROR, Error::CustomParsingError(_, _) => LCI_ERROR_PARSING_ERROR, Error::PeParsingError(_, _) => LCI_ERROR_PE_PARSING_ERROR, diff --git a/src/error.rs b/src/error.rs index 2c78463..f68eb8d 100644 --- a/src/error.rs +++ b/src/error.rs @@ -10,6 +10,8 @@ use regex; #[derive(Debug)] pub enum Error { ParsingIncomplete, + // The string is the input that was not parsed. + UnconsumedInput(String), /// The first string is the expression parsed, the second is a tag describing the parser that failed. GenericParsingError(String, String), /// The string is the expression parsed. @@ -41,6 +43,11 @@ impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Error::ParsingIncomplete => write!(f, "More input was expected by the parser"), + Error::UnconsumedInput(i) => write!( + f, + "The parser did not consume the following input: \"{}\"", + i + ), Error::GenericParsingError(i, e) => write!( f, "An error was encountered in the parser \"{}\" while parsing the expression \"{}\"", diff --git a/src/lib.rs b/src/lib.rs index ae79d4f..5a9ca41 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -161,8 +161,14 @@ impl str::FromStr for Expression { fn from_str(s: &str) -> Result { parse_expression(nom::types::CompleteStr(s)) - .map(|(_, expression)| expression) .map_err(Error::from) + .and_then(|(remaining_input, expression)| { + if remaining_input.is_empty() { + Ok(expression) + } else { + Err(Error::UnconsumedInput(remaining_input.to_string())) + } + }) } } @@ -502,6 +508,16 @@ mod tests { } } + #[test] + fn expression_parse_should_error_if_it_does_not_consume_the_whole_input() { + let error = Expression::from_str("file(\"Cargo.toml\") foobar").unwrap_err(); + + assert_eq!( + "The parser did not consume the following input: \" foobar\"", + error.to_string() + ); + } + #[test] fn compound_condition_parse_should_handle_a_single_condition() { let result = CompoundCondition::parse("file(\"Cargo.toml\")".into())