---
title: "Edit YAML and keep its comments"
url: https://recursiveai.org/oneyaml/rust/cookbook/edit-yaml-keep-comments/
description: "Change a value, remove a list item and add a key with a comment in a YAML file from Rust, with every other byte and comment kept."
version: "1.2.0"
---

# Edit YAML and keep its comments

Change a YAML file from Rust the way a person would: one value, one list item, one new key, and every comment, blank line and quote elsewhere stays as it was. Parse it into a `Document`, edit, and write it back.

```rust
use oneyaml::Document;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let src = "\
# App settings, edited by hand and by tools.
server:
  host: 0.0.0.0
  port: 8080      # behind the load balancer

# Feature flags
features:
  - auth
  - legacy-export   # remove after the 2.0 release
  - metrics
";
    let mut doc = Document::parse(src)?;

    // Change one value: its trailing comment stays.
    doc.set_path("server.port", 9090)?;

    // Remove a list item: its comment goes with it.
    let removed = doc.get_mut("features")?.remove_at(1)?;
    println!("removed {:?} with {:?}", removed.text(), removed.comments());

    // Add a key with a comment of its own.
    let mut server = doc.get_mut("server")?;
    let mut timeout = server.insert("timeout", "30s")?;
    timeout.set_trailing(Some("per request"))?;

    print!("{doc}");
    Ok(())
}
```

```text
removed "legacy-export   # remove after the 2.0 release" with ["# remove after the 2.0 release"]
# App settings, edited by hand and by tools.
server:
  host: 0.0.0.0
  port: 9090      # behind the load balancer
  timeout: 30s # per request

# Feature flags
features:
  - auth
  - metrics
```

## Good to know

- **Comments stay with their entry.** The `# behind the load balancer` comment stays on `port`, and the comment of the removed item goes with it. Which entry owns a comment is decided by [numbered rules](https://recursiveai.org/oneyaml/rust/docs/comment-attachment/); `doc.explain_comment(id)` says which rule applied.
- **A removed entry isn’t lost.** `remove_at` returns a `Removed` with the entry’s text and comments, which you can put back elsewhere with `insert_removed`. `remove_keep_comments` removes an entry but leaves its comments in place.
- **Values keep their style.** `set_path` and `NodeMut::set` keep the old value’s quotes, block style or tag when they still fit the new value.
- **Comments of your own.** `set_trailing` writes the comment after a value, `set_leading` the lines above it, and `Document::set_header` the comment at the top of the file. `set_blank_lines_before` adds spacing.
- An untouched document writes back byte for byte: `Document::parse(src)?.to_string() == src`.

To change many values at once from a JSON document, use a patch: [merge or patch YAML](https://recursiveai.org/oneyaml/rust/cookbook/patch-yaml/).

The same edit in Go, Rust and C#: [Edit YAML without losing comments](https://recursiveai.org/oneyaml/articles/edit-yaml-keep-comments/).
