Skip to content

Commit

Permalink
WIP: fix: Preserve dotted-key ordering
Browse files Browse the repository at this point in the history
  • Loading branch information
epage committed Sep 3, 2021
1 parent e00fc9e commit 153342a
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 3 deletions.
13 changes: 11 additions & 2 deletions src/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,12 @@ impl Display for InlineTable {
)?;
write!(f, "{}", self.preamble)?;

let children = self.get_values();
let mut children = self.get_values();
children.sort_by_key(|(k, _)| {
let last_index = k.len() - 1;
k[last_index].position().unwrap_or(usize::MAX)
});

for (i, (key_path, value)) in children.into_iter().enumerate() {
let key = key_path_display(&key_path, DEFAULT_INLINE_KEY_DECOR);
if i > 0 {
Expand Down Expand Up @@ -143,7 +148,11 @@ fn visit_table(
path: &[&Key],
is_array_of_tables: bool,
) -> Result {
let children = table.get_values();
let mut children = table.get_values();
children.sort_by_key(|(k, _)| {
let last_index = k.len() - 1;
k[last_index].position().unwrap_or(usize::MAX)
});

if path.is_empty() {
// don't print header for the root node
Expand Down
18 changes: 18 additions & 0 deletions src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub struct Key {
key: InternalString,
pub(crate) repr: Repr,
pub(crate) decor: Decor,
pub(crate) position: Option<usize>,
}

impl Key {
Expand All @@ -45,6 +46,7 @@ impl Key {
key,
repr,
decor: Default::default(),
position: Default::default(),
}
}

Expand All @@ -54,6 +56,12 @@ impl Key {
self
}

/// While creating the `Key`, add a table position to it
pub fn with_position(mut self, position: Option<usize>) -> Self {
self.position = position;
self
}

/// Returns the parsed key value.
pub fn get(&self) -> &str {
&self.key
Expand All @@ -74,6 +82,16 @@ impl Key {
&mut self.decor
}

/// Get the position relative to other keys in parent table
pub fn position(&self) -> Option<usize> {
return self.position;
}

/// Set the position relative to other keys in parent table
pub fn set_position(&mut self, position: Option<usize>) {
self.position = position;
}

fn try_parse(s: &str) -> Result<Key, parser::TomlError> {
use combine::EasyParser;
let result = parser::key_parser().easy_parse(Stream::new(s));
Expand Down
2 changes: 2 additions & 0 deletions src/parser/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ impl TomlParser {
first_key.decor.suffix().unwrap_or_default(),
);
}
kv.key.set_position(Some(self.current_value_position));
self.current_value_position += 1;

let root = self.document.as_table_mut();
let table = Self::descend_path(root, self.current_table_path.as_slice(), 0, false)
Expand Down
4 changes: 3 additions & 1 deletion src/parser/inline_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ fn table_from_pairs(
..Default::default()
};

for (path, kv) in v {
for (position, (path, mut kv)) in v.into_iter().enumerate() {
kv.key.set_position(Some(position));

let table = descend_path(&mut root, &path, 0)?;
if table.contains_key(kv.key.get()) {
return Err(CustomError::DuplicateKey {
Expand Down
8 changes: 8 additions & 0 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ pub(crate) struct TomlParser {
document: Box<Document>,
current_table_path: Vec<Key>,
current_table_position: usize,
// Current position within a table, to help order dotted keys
current_value_position: usize,
}

impl Default for TomlParser {
Expand All @@ -34,6 +36,7 @@ impl Default for TomlParser {
document: Box::new(Document::new()),
current_table_path: Vec::new(),
current_table_position: 0,
current_value_position: 0,
}
}
}
Expand Down Expand Up @@ -391,6 +394,7 @@ trimmed in raw strings.
r#"{a = 1e165}"#,
r#"{ hello = "world", a = 1}"#,
r#"{ hello.world = "a" }"#,
r#"{ hello.world = "a", goodbye = "b", hello.moon = "c" }"#,
];
for input in &inputs {
parsed_value_eq!(input);
Expand Down Expand Up @@ -498,6 +502,10 @@ that
key = "value"
"#,
r#"hello.world = "a"
"#,
r#"hello.world = "a"
goodbye = "b"
hello.moon = "c"
"#,
];
for document in &documents {
Expand Down
2 changes: 2 additions & 0 deletions src/parser/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ impl TomlParser {
let leading = mem::take(&mut self.document.trailing);
let table = self.document.as_table_mut();
self.current_table_position += 1;
self.current_value_position = 0;

let table = Self::descend_path(table, &path[..path.len() - 1], 0, false)?;
let key = &path[path.len() - 1];
Expand Down Expand Up @@ -160,6 +161,7 @@ impl TomlParser {

let leading = mem::take(&mut self.document.trailing);
let table = self.document.as_table_mut();
self.current_value_position = 0;

let key = &path[path.len() - 1];
let table = Self::descend_path(table, &path[..path.len() - 1], 0, false);
Expand Down

0 comments on commit 153342a

Please sign in to comment.