Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replacing an InlineTable with a comment with a Table results in invalid syntax #691

Open
nrabulinski opened this issue Feb 26, 2024 · 3 comments
Labels
A-edit Area: TOML editing API C-bug Category: Things not working as expected M-breaking-change Meta: Implementing or merging this will introduce a breaking change.

Comments

@nrabulinski
Copy link

use std::str::FromStr;

use toml_edit::{Document, Item, Table};

fn main() {
    let mut val = Document::from_str(
        r#"
    # hello i'm a comment
    foo = { bar = 1 }
    "#,
    )
    .unwrap();
    println!("before: {}", val.to_string());
    let mut new_foo = Table::new();
    new_foo.insert("bar", Item::Value(1.into()));
    new_foo.insert("baz", Item::Value(2.into()));
    *val.get_mut("foo").unwrap() = Item::Table(new_foo);
    println!("after: {}", val.to_string());
}

Expected output:

before:
    # hello i'm a comment
    foo = { bar = 1 }

after:
    # hello i'm a comment
    [foo]
    bar = 1
    baz = 2

Actual output:

before:
    # hello i'm a comment
    foo = { bar = 1 }

after: [
    # hello i'm a comment
    foo ]
bar = 1
baz = 2
@nrabulinski
Copy link
Author

I tested it on multiple version and it seems like the bug has been here since forever, but I couldn't find any issue which would reference it

@epage epage added C-bug Category: Things not working as expected M-breaking-change Meta: Implementing or merging this will introduce a breaking change. A-edit Area: TOML editing API labels Feb 26, 2024
@epage
Copy link
Member

epage commented Feb 26, 2024

This is another way of accomplishing the end result as in #267.

CertainLach added a commit to CertainLach/deppatcher that referenced this issue Jun 17, 2024
May break formatting for those, who use normal tables syntax fo
dependencies, but will make life easier for sane people

Upstream-Bug: toml-rs/toml#691
@eemed
Copy link

eemed commented Jul 29, 2024

For others searching for a workaround: I set the comment to the table value instead of the key.
Here I'm using the visitor while adding doc strings to the serialized toml.

impl VisitMut for Formatter {
  fn visit_table_like_kv_mut(&mut self, mut key: KeyMut<'_>, node: &mut Item) {
        if node.is_inline_table() {
            let item = std::mem::replace(node, Item::None);
            if let Ok(table) = item.into_table() {
                *node = Item::Table(table);
            }
        }
        ...
        
        if let Ok(doc) = doc {
            let mut comment = String::from("\n");
            for line in doc.lines() {
                let line = format!("# {line}\n");
                comment.push_str(&line);
            }

            match node {
                Item::Table(table) => {
                    // Set the comment to the table instead of key
                    let decor = table.decor_mut();
                    decor.set_prefix(comment);
                }
                _ => {
                    let decor = key.leaf_decor_mut();
                    decor.set_prefix(comment);
                }
            }
        }
        
        ...

    }
}

This produces output

# Comment
[section]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-edit Area: TOML editing API C-bug Category: Things not working as expected M-breaking-change Meta: Implementing or merging this will introduce a breaking change.
Projects
None yet
Development

No branches or pull requests

3 participants