How to use `toml_edit` to insert keys in table?

I am writing a function to edit Cargo.toml files using toml_edit. It works great to edit keys that already exist, but new keys are inserted unformatted to the top.

The function currently looks like this:

use toml_edit::DocumentMut;

pub fn main() -> anyhow::Result<()> {
    let cargo_toml = std::fs::read_to_string(PathBuf::from("Cargo.toml"))?;
    let mut cargo_toml = cargo_toml.parse::<DocumentMut>()?;

    cargo_toml["patch"]["crates-io"]["creusot-contracts"]["path"] =
        toml_edit::value("test");

    let mut file = std::fs::File::create("Cargo.toml")?;
    file.write_all(cargo_toml.to_string().as_bytes())?;
    Ok(())   
}

Input, an almost empty Cargo.toml:

[package]
name = "test"

Output, the patch table is inserted at the top:

patch = { crates-io = { creusot-contracts = { path = "test" } } }
[package]
name = "test"

How to insert it at the bottom instead?


I saw that the Cargo API contains a module toml_mut that wraps toml_edit but I'm even more lost about how to use it.

You can set the position of a table in a DocumentMut via Table::set_position:

use toml_edit::DocumentMut;

pub fn main() -> anyhow::Result<()> {
    let cargo_toml = r#"
[package]
name = "test"
    "#;

    let mut cargo_toml = cargo_toml.parse::<DocumentMut>()?;

    cargo_toml["patch"] = toml_edit::table();
    cargo_toml["patch"].as_table_mut().unwrap().set_position(1);

    cargo_toml["patch"]["crates-io"]["creusot-contract"]["path"] = toml_edit::value("test");

    println!("{cargo_toml}");
    Ok(())
}

Playground.

Thank you!

1 Like