Skip to content

Commit

Permalink
fix(error): Clean up duplicate key error
Browse files Browse the repository at this point in the history
- We specify which table in a case where we knew the name
- For inline tables, instead of saying `<unknown> table`, we just don't
  say anything (making the parser stateful to show table didn't seem
  worth it at this time).
- We now say `document root` instead of `'[]' table`
- We no longer include `[]` (which was wrong for array of tables)

We also share the rendering logic between the different paths.

Fixes #251
  • Loading branch information
epage committed Dec 29, 2021
1 parent 4f02601 commit 1b3ccd6
Show file tree
Hide file tree
Showing 12 changed files with 46 additions and 20 deletions.
4 changes: 2 additions & 2 deletions src/parser/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ impl TomlParser {
if mixed_table_types {
return Err(CustomError::DuplicateKey {
key: kv.key.get().into(),
table: "<unknown>".into(), // TODO: get actual table name
table: None,
});
}

Expand All @@ -170,7 +170,7 @@ impl TomlParser {
if duplicate_key {
return Err(CustomError::DuplicateKey {
key: key.as_str().into(),
table: "<unknown>".into(), // TODO: get actual table name
table: Some(self.current_table_path.clone()),
});
}

Expand Down
24 changes: 19 additions & 5 deletions src/parser/errors.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::Key;
use combine::easy::Errors as ParseError;
use combine::stream::easy::Error;
use combine::stream::position::SourcePosition;
use itertools::Itertools;
use std::error::Error as StdError;
use std::fmt::{Display, Formatter, Result};

Expand Down Expand Up @@ -233,7 +235,10 @@ mod test_translate_position {

#[derive(Debug, Clone)]
pub(crate) enum CustomError {
DuplicateKey { key: String, table: String },
DuplicateKey {
key: String,
table: Option<Vec<Key>>,
},
InvalidHexEscape(u32),
UnparsedLine,
OutOfRange,
Expand All @@ -247,11 +252,20 @@ impl StdError for CustomError {

impl Display for CustomError {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
match *self {
CustomError::DuplicateKey { ref key, ref table } => {
writeln!(f, "Duplicate key `{}` in `{}` table", key, table)
match self {
CustomError::DuplicateKey { key, table } => {
if let Some(table) = table {
if table.is_empty() {
writeln!(f, "Duplicate key `{}` in document root", key)
} else {
let path = table.iter().join(".");
writeln!(f, "Duplicate key `{}` in table `{}`", key, path)
}
} else {
writeln!(f, "Duplicate key `{}`", key)
}
}
CustomError::InvalidHexEscape(ref h) => {
CustomError::InvalidHexEscape(h) => {
writeln!(f, "Invalid hex escape code: {:x} ", h)
}
CustomError::UnparsedLine => writeln!(f, "Could not parse the line"),
Expand Down
2 changes: 1 addition & 1 deletion src/parser/inline_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fn table_from_pairs(
if duplicate_key {
return Err(CustomError::DuplicateKey {
key: key.as_str().into(),
table: "inline".into(),
table: None,
});
}
}
Expand Down
7 changes: 1 addition & 6 deletions src/parser/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use combine::parser::byte::byte;
use combine::parser::range::range;
use combine::stream::RangeStream;
use combine::*;
use itertools::Itertools;
use std::cell::RefCell;
use std::mem;
// https://github.com/rust-lang/rust/issues/41358
Expand Down Expand Up @@ -71,13 +70,9 @@ parser! {

pub(crate) fn duplicate_key(path: &[Key], i: usize) -> CustomError {
assert!(i < path.len());
let header = path[..i]
.iter()
.map(|k| k.to_repr().as_ref().as_raw().to_owned())
.join(".");
CustomError::DuplicateKey {
key: path[i].to_repr().as_ref().as_raw().into(),
table: format!("[{}]", header),
table: Some(path[..i].to_vec()),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ TOML parse error at line 5, column 1
|
5 | apple.color = "red"
| ^
Duplicate key `color` in `<unknown>` table
Duplicate key `color`

Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ TOML parse error at line 6, column 1
|
6 | size = "small"
| ^
Duplicate key `size` in `<unknown>` table
Duplicate key `size`

2 changes: 1 addition & 1 deletion tests/fixtures/invalid/duplicate-key-table.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ TOML parse error at line 4, column 1
|
4 | [fruit.type]
| ^
Duplicate key `type` in `[fruit]` table
Duplicate key `type` in table `fruit`

While parsing a Table Header
6 changes: 6 additions & 0 deletions tests/fixtures/invalid/duplicate-keys-cargo.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
TOML parse error at line 7, column 1
|
7 | categories = ["algorithms"]
| ^
Duplicate key `categories` in table `project`

11 changes: 11 additions & 0 deletions tests/fixtures/invalid/duplicate-keys-cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[project]

name = "dep1"
version = "0.5.0"
authors = ["[email protected]"]
categories = ["algorithms"]
categories = ["algorithms"]

[lib]

name = "dep1"
2 changes: 1 addition & 1 deletion tests/fixtures/invalid/duplicate-keys.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ TOML parse error at line 2, column 1
|
2 | dupe = true
| ^
Duplicate key `dupe` in `<unknown>` table
Duplicate key `dupe` in document root

2 changes: 1 addition & 1 deletion tests/fixtures/invalid/duplicate-tables.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ TOML parse error at line 2, column 1
|
2 | [a]
| ^
Duplicate key `a` in `[]` table
Duplicate key `a` in document root

While parsing a Table Header
2 changes: 1 addition & 1 deletion tests/fixtures/invalid/table-array-implicit.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ TOML parse error at line 13, column 1
|
13 | [[albums]]
| ^
Duplicate key `albums` in `[]` table
Duplicate key `albums` in document root

While parsing a Table Header

0 comments on commit 1b3ccd6

Please sign in to comment.