Skip to content

Commit

Permalink
feat: Basic dotted key support (#152)
Browse files Browse the repository at this point in the history
This let's us parse dotted keys in tables.

This does not include
- Format preserving
- Error if dotted keys insert into table
- Error if table insets into dotted keys
- Anything for inline tables
  • Loading branch information
epage authored Sep 2, 2021
1 parent b2f6eee commit 0ef4700
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 22 deletions.
49 changes: 29 additions & 20 deletions src/parser/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ use crate::document::Document;
use crate::key::Key;
use crate::parser::errors::CustomError;
use crate::parser::inline_table::KEYVAL_SEP;
use crate::parser::key::simple_key;
use crate::parser::key::key;
use crate::parser::table::table;
use crate::parser::trivia::{comment, line_ending, line_trailing, newline, ws};
use crate::parser::value::value;
use crate::parser::{TomlError, TomlParser};
use crate::repr::{Decor, Repr};
use crate::repr::Decor;
use crate::table::TableKeyValue;
use crate::Item;
use combine::parser::char::char;
Expand Down Expand Up @@ -35,12 +35,12 @@ toml_parser!(parse_newline, parser, {
});

toml_parser!(keyval, parser, {
parse_keyval().and_then(|kv| parser.borrow_mut().deref_mut().on_keyval(kv))
parse_keyval().and_then(|(p, kv)| parser.borrow_mut().deref_mut().on_keyval(p, kv))
});

// keyval = key keyval-sep val
parser! {
fn parse_keyval['a, I]()(I) -> TableKeyValue
fn parse_keyval['a, I]()(I) -> (Vec<Key>, TableKeyValue)
where
[I: RangeStream<
Range = &'a str,
Expand All @@ -53,21 +53,22 @@ parser! {
From<crate::parser::errors::CustomError>
] {
(
(simple_key(), ws()),
key(),
char(KEYVAL_SEP),
(ws(), value(), line_trailing())
).map(|(k, _, v)| {
let ((raw, key), suf) = k;
let key_repr = Repr::new_unchecked(raw);
let key_decor = Decor::new("", suf);
let key = Key::new_unchecked(key_repr, key, key_decor);
).map(|(key, _, v)| {
let mut path = key.into_vec();
let key = path.pop().expect("Was vec1, so at least one exists");

let (pre, v, suf) = v;
let v = v.decorated(pre, suf);
TableKeyValue {
key,
value: Item::Value(v),
}
(
path,
TableKeyValue {
key,
value: Item::Value(v),
}
)
})
}
}
Expand Down Expand Up @@ -117,16 +118,24 @@ impl TomlParser {
self.document.trailing.push_str(e);
}

fn on_keyval(&mut self, mut kv: TableKeyValue) -> Result<(), CustomError> {
let prefix = mem::take(&mut self.document.trailing);
kv.key.decor = Decor::new(
prefix + kv.key.decor.prefix().unwrap_or_default(),
kv.key.decor.suffix().unwrap_or_default(),
);
fn on_keyval(&mut self, mut path: Vec<Key>, mut kv: TableKeyValue) -> Result<(), CustomError> {
{
let prefix = mem::take(&mut self.document.trailing);
let first_key = if path.is_empty() {
&mut kv.key
} else {
&mut path[0]
};
first_key.decor = Decor::new(
prefix + first_key.decor.prefix().unwrap_or_default(),
first_key.decor.suffix().unwrap_or_default(),
);
}

let root = self.document.as_table_mut();
let table = Self::descend_path(root, self.current_table_path.as_slice(), 0)
.expect("the table path is valid; qed");
let table = Self::descend_path(table, &path, 0)?;
if table.contains_key(kv.key.get()) {
Err(CustomError::DuplicateKey {
key: kv.key.into(),
Expand Down
2 changes: 0 additions & 2 deletions tests/decoder_compliance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ fn main() {
harness
.ignore([
"valid/inline-table/key-dotted.toml",
"valid/key/dotted.toml",
"valid/key/numeric-dotted.toml",
"valid/string/multiline-quotes.toml",
])
.unwrap();
Expand Down

0 comments on commit 0ef4700

Please sign in to comment.