From fe79d63c004f75e79764aa0ef640365b4cd3c3e9 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 29 Dec 2021 11:47:26 -0600 Subject: [PATCH] fix(error): Improve dotted key overwrite error Fixes #252 --- src/parser/errors.rs | 12 ++++++++++++ src/parser/inline_table.rs | 6 +++--- src/parser/table.rs | 12 ++++++++++-- tests/fixtures/invalid/duplicate-keys-dotted.stderr | 6 ++++++ tests/fixtures/invalid/duplicate-keys-dotted.toml | 4 ++++ 5 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 tests/fixtures/invalid/duplicate-keys-dotted.stderr create mode 100644 tests/fixtures/invalid/duplicate-keys-dotted.toml diff --git a/src/parser/errors.rs b/src/parser/errors.rs index 3539ba27..295d3c5b 100644 --- a/src/parser/errors.rs +++ b/src/parser/errors.rs @@ -239,6 +239,10 @@ pub(crate) enum CustomError { key: String, table: Option>, }, + DottedKeyExtendWrongType { + key: Vec, + actual: &'static str, + }, InvalidHexEscape(u32), UnparsedLine, OutOfRange, @@ -265,6 +269,14 @@ impl Display for CustomError { writeln!(f, "Duplicate key `{}`", key) } } + CustomError::DottedKeyExtendWrongType { key, actual } => { + let path = key.iter().join("."); + writeln!( + f, + "Dotted key `{}` attempted to extend non-table type (`{}`)", + path, actual + ) + } CustomError::InvalidHexEscape(h) => { writeln!(f, "Invalid hex escape code: {:x} ", h) } diff --git a/src/parser/inline_table.rs b/src/parser/inline_table.rs index c51737c6..7cc9d43a 100644 --- a/src/parser/inline_table.rs +++ b/src/parser/inline_table.rs @@ -1,7 +1,7 @@ use crate::key::Key; use crate::parser::errors::CustomError; use crate::parser::key::key; -use crate::parser::table::duplicate_key; +use crate::parser::table::extend_wrong_type; use crate::parser::trivia::ws; use crate::parser::value::value; use crate::table::TableKeyValue; @@ -57,8 +57,8 @@ fn descend_path<'a>( Value::InlineTable(ref mut sweet_child_of_mine) => { table = sweet_child_of_mine; } - _ => { - return Err(duplicate_key(path, i)); + ref v => { + return Err(extend_wrong_type(path, i, v.type_name())); } } } diff --git a/src/parser/table.rs b/src/parser/table.rs index f73c4c6e..6c17df75 100644 --- a/src/parser/table.rs +++ b/src/parser/table.rs @@ -76,6 +76,14 @@ pub(crate) fn duplicate_key(path: &[Key], i: usize) -> CustomError { } } +pub(crate) fn extend_wrong_type(path: &[Key], i: usize, actual: &'static str) -> CustomError { + assert!(i < path.len()); + CustomError::DottedKeyExtendWrongType { + key: path[..=i].to_vec(), + actual, + } +} + impl TomlParser { pub(crate) fn descend_path<'t, 'k>( mut table: &'t mut Table, @@ -91,8 +99,8 @@ impl TomlParser { Item::Table(new_table) }); match *entry { - Item::Value(..) => { - return Err(duplicate_key(path, i)); + Item::Value(ref v) => { + return Err(extend_wrong_type(path, i, v.type_name())); } Item::ArrayOfTables(ref mut array) => { debug_assert!(!array.is_empty()); diff --git a/tests/fixtures/invalid/duplicate-keys-dotted.stderr b/tests/fixtures/invalid/duplicate-keys-dotted.stderr new file mode 100644 index 00000000..c6d08ac6 --- /dev/null +++ b/tests/fixtures/invalid/duplicate-keys-dotted.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 3, column 1 + | +3 | ssl-version.min = 'tlsv1.2' + | ^ +Dotted key `ssl-version` attempted to extend non-table type (`string`) + diff --git a/tests/fixtures/invalid/duplicate-keys-dotted.toml b/tests/fixtures/invalid/duplicate-keys-dotted.toml new file mode 100644 index 00000000..199f36e7 --- /dev/null +++ b/tests/fixtures/invalid/duplicate-keys-dotted.toml @@ -0,0 +1,4 @@ +[http] +ssl-version = 'tlsv1.1' +ssl-version.min = 'tlsv1.2' +ssl-version.max = 'tlsv1.3'