Skip to content

Refuse unsafe documents

Some YAML cannot be round-tripped safely by the underlying parser. yamldoc detects those constructs and reports them. It does not decide what to do about them — that is yours.

f, err := yamldoc.Parse(src)
if err != nil {
    return err
}

if u := f.Unsupported(); len(u) > 0 {
    return fmt.Errorf("cannot safely edit %s: %s", path, u[0])
}

Each report names the reason and the line:

line 12: multi-line flow collection with interior comments (collection spans lines 12-15)

You cannot forget to check

Emitting a file that contains an unsupported construct returns ErrUnsupported rather than bytes:

out, err := f.Bytes()
if errors.Is(err, yamldoc.ErrUnsupported) {
    // nothing was written, and nothing was damaged
}

Checking up front is better — the caller has already made their edits by the time Bytes is reached, and failing then looks arbitrary — but the guard is there either way.

The construct

A flow collection spanning multiple lines with comments inside it:

bounds: {
  min: 1,   # lower bound
  max: 10   # upper bound
}

Re-emitting that swallows the closing brace into the comment, producing YAML that does not parse. Rather than emit a broken document, yamldoc refuses.

Safe flow style is not affected. Single-line flow mappings and sequences, comments above or beside a flow node, and flow collections without interior comments all round-trip normally:

voice: &voice {id: abc, stability: 0.6}   # fine
tiers: [core, ingress, 'tier-1']          # fine
# describes the bounds
bounds: {min: 1, max: 10}                 # fine

Working around it

Rewrite the collection in block style, which has no such problem:

bounds:
  min: 1    # lower bound
  max: 10   # upper bound