toml-rs/toml

[BUG] decor set_prefix is not working

Closed this issue · 7 comments

BUG

decor set_prefix is not working

reproduce

    let mut formatted = Formatted::new(el);
    let decor = formatted.decor_mut();
    decor.set_prefix("\n    ");
    arr.push(Value::String(formatted));

actual

    "existing", "added",
]

expected

    "existing",
    "added",
]

Could you provide a complete reproduction case? In example output mentions "foo" and "bar" but only one element is pushed and it isn't clear which one.

Updated.

Given original toml array ends with "existing",\n].

After op, toml array ends with "existing", "added"\n].

But expected added to new line.

Same problem existing when cargo new --lib.

New member path is added to same line of .members field last element.

But expect it add to another line.

So, I want to implement it myself, but seems toml-edit does not support it.

Could you provide a complete reproduction case?

cargo new --lib reproduce

If you are concerned about cargo news editing of a workspace, that would involve opening an issue on Cargo's repo, not here. I'm looking for a complete reproduction case using toml_edits API.

use {
    std::{
        fs::File,
        io::{BufReader, BufWriter, Read, Write},
    },
    toml_edit::{DocumentMut, Formatted, Value},
};

fn main() {
    let input_file = File::open("Cargo.toml").unwrap();
    let mut reader = BufReader::new(input_file);
    let mut buf = Vec::new();
    reader.read_to_end(&mut buf).unwrap();

    let content = String::from_utf8(buf).unwrap();
    let mut doc = content.parse::<DocumentMut>().unwrap();
    let members = doc["workspace"]["members"].as_array_mut().unwrap();

    let mut formatted = Formatted::new("reproduce".to_string());
    let decor = formatted.decor_mut();
    decor.set_prefix("\n    ");
    members.push(Value::String(formatted));

    let output_data = doc.to_string();

    let output_file = File::create("/tmp/Cargo.toml").unwrap();
    let mut writer = BufWriter::new(output_file);
    writer.write_all(output_data.as_bytes()).unwrap();
    writer.flush().unwrap();
}

Output

    "foo", "reproduce",
]

Expected

    "foo",
    "reproduce",
]

I've simplified that down and in a way to narrow down the problem

#!/usr/bin/env nargo
---
[dependencies]
toml_edit = "*"
---

use {
    std::{
        fs::File,
        io::{BufReader, BufWriter, Read, Write},
    },
    toml_edit::{DocumentMut, Formatted, Value},
};

fn main() {
    let content = r#"
[workspace]
members = ["foo"]
"#;
    let mut doc = content.parse::<DocumentMut>().unwrap();
    let members = doc["workspace"]["members"].as_array_mut().unwrap();

    let mut formatted = Formatted::new("reproduce".to_string());
    let decor = formatted.decor_mut();
    decor.set_prefix("\n    ");
    let value = Value::String(formatted);
    dbg!(&value);
    members.push(value);
    dbg!(&doc);
    println!("{doc}");
}

Its the Array::push call.

The documentation for that calls says

Appends a new value to the end of the array, applying default formatting to it.

If you switch to push_formatted, it should work.