diff --git a/src/parsers/comments/mod.rs b/src/parsers/comments/mod.rs index 860c4d1e..6b6d9a8c 100644 --- a/src/parsers/comments/mod.rs +++ b/src/parsers/comments/mod.rs @@ -33,16 +33,13 @@ fn construct_lint_from(parse_error: ParseError, file_name: &str) -> Diagnostic { expected, } => { // TODO: should use Display like in Slice parser. - let message = format!( - "expected one of {}, but found '{token_kind:?}'", - clean_message(&expected), - ); + let message = generate_message(&expected, token_kind); Diagnostic::new(Lint::MalformedDocComment { message }).set_span(&Span::new(start, end, file_name)) } // The parser hit EOF in the middle of a grammar rule. ParseError::UnrecognizedEof { location, expected } => { - let message = format!("expected one of {}, but found 'EOF'", clean_message(&expected)); + let message = generate_message(&expected, "EOF"); Diagnostic::new(Lint::MalformedDocComment { message }).set_span(&Span::new(location, location, file_name)) } @@ -52,13 +49,15 @@ fn construct_lint_from(parse_error: ParseError, file_name: &str) -> Diagnostic { // TODO: we should convert the LALRpop keywords to human words like we do for the Slice parser. // TODO: this is identical to the bottom of parsers/slice/mod.rs, we should roll them into a helper function. -fn clean_message(expected: &[String]) -> String { - match expected { - [first] => first.to_owned(), - [first, second] => format!("{first} or {second}"), +fn generate_message(expected: &[String], found: impl std::fmt::Debug) -> String { + let expected_message = match expected { + [] => "expected no tokens".to_owned(), + [first] => format!("expected one of {first}"), + [first, second] => format!("expected one of {first} or {second}"), many => { let (last, others) = many.split_last().unwrap(); - format!("{}, or {last}", others.join(", ")) + format!("expected one of {}, or {last}", others.join(", ")) } - } + }; + format!("{expected_message}, but found '{found:?}'") } diff --git a/src/parsers/preprocessor/mod.rs b/src/parsers/preprocessor/mod.rs index 683a2c6f..a66b41af 100644 --- a/src/parsers/preprocessor/mod.rs +++ b/src/parsers/preprocessor/mod.rs @@ -35,16 +35,13 @@ fn construct_error_from(parse_error: ParseError, file_name: &str) -> Diagnostic token: (start, token_kind, end), expected, } => { - let message = format!( - "expected one of {}, but found '{token_kind:?}'", - clean_message(&expected) - ); + let message = generate_message(&expected, token_kind); Diagnostic::new(Error::Syntax { message }).set_span(&Span::new(start, end, file_name)) } // The parser hit EOF in the middle of a grammar rule. ParseError::UnrecognizedEof { location, expected } => { - let message = format!("expected one of {}, but found 'EOF'", clean_message(&expected)); + let message = generate_message(&expected, "EOF"); Diagnostic::new(Error::Syntax { message }).set_span(&Span::new(location, location, file_name)) } @@ -57,13 +54,15 @@ fn construct_error_from(parse_error: ParseError, file_name: &str) -> Diagnostic } } -fn clean_message(expected: &[String]) -> String { - match expected { - [first] => first.to_owned(), - [first, second] => format!("{first} or {second}"), +fn generate_message(expected: &[String], found: impl std::fmt::Debug) -> String { + let expected_message = match expected { + [] => "expected no tokens".to_owned(), + [first] => format!("expected one of {first}"), + [first, second] => format!("expected one of {first} or {second}"), many => { let (last, others) = many.split_last().unwrap(); - format!("{}, or {last}", others.join(", ")) + format!("expected one of {}, or {last}", others.join(", ")) } - } + }; + format!("{expected_message}, but found '{found:?}'") } diff --git a/src/parsers/slice/mod.rs b/src/parsers/slice/mod.rs index 8d53bc61..c961dc8f 100644 --- a/src/parsers/slice/mod.rs +++ b/src/parsers/slice/mod.rs @@ -32,13 +32,13 @@ fn construct_error_from(parse_error: ParseError, file_name: &str) -> Diagnostic token: (start, token_kind, end), expected, } => { - let message = format!("expected one of {}, but found '{token_kind}'", clean_message(&expected)); + let message = generate_message(&expected, token_kind); Diagnostic::new(Error::Syntax { message }).set_span(&Span::new(start, end, file_name)) } // The parser hit EOF in the middle of a grammar rule. ParseError::UnrecognizedEof { location, expected } => { - let message = format!("expected one of {}, but found 'EOF'", clean_message(&expected)); + let message = generate_message(&expected, "EOF"); Diagnostic::new(Error::Syntax { message }).set_span(&Span::new(location, location, file_name)) } @@ -47,7 +47,7 @@ fn construct_error_from(parse_error: ParseError, file_name: &str) -> Diagnostic } // TODO: simplify this or merge the match statements in this function and tokens.rs together. -fn clean_message(expected: &[String]) -> String { +fn generate_message(expected: &[String], found: impl std::fmt::Display) -> String { let keyword = expected .iter() .map(|s| match s.as_str() { @@ -123,12 +123,14 @@ fn clean_message(expected: &[String]) -> String { .map(|s| format!("'{s}'")) .collect::>(); - match &keyword[..] { - [first] => first.to_owned(), - [first, second] => format!("{first} or {second}"), + let expected_message = match &keyword[..] { + [] => "expected no tokens".to_owned(), + [first] => format!("expected one of {first}"), + [first, second] => format!("expected one of {first} or {second}"), many => { let (last, others) = many.split_last().unwrap(); - format!("{}, or {last}", others.join(", ")) + format!("expected one of {}, or {last}", others.join(", ")) } - } + }; + format!("{expected_message}, but found '{found}'") }