go-toml-edit

#go-toml-edit

Comment-preserving TOML editing library for Go.

#API Reference

#.

Package tomledit provides a comment-preserving TOML parser and editor.

It parses TOML documents into a lossless AST that preserves comments, whitespace, and formatting. Values can be read, set, deleted, and renamed without disturbing unrelated parts of the file. The AST can be serialized back to bytes with Bytes (round-trip fidelity) or reformatted with Format.

Key features: - Lossless round-trip: parse and re-serialize without losing comments or formatting - Path-based access: read and write values using dot-separated paths (e.g. "server.host") - Structural editing: create tables, array-of-tables, rename and delete keys - Diff and merge: compare two documents or merge defaults into an existing document - Walk: traverse all key-value pairs in document order - Unmarshal: decode TOML into Go structs and maps

#Added

const Added    ChangeKind = iota // Added means the key exists in b but not in a.

#Removed

const Removed                    // Removed means the key exists in a but not in b.

#Modified

const Modified                   // Modified means the key exists in both but with different values.

#NodeDocument

const NodeDocument      NodeType = iota // NodeDocument is the root document node.

#NodeTable

const NodeTable                         // NodeTable is a [table] header node.

#NodeArrayTable

const NodeArrayTable                    // NodeArrayTable is an [[array-table]] header node.

#NodeKeyValue

const NodeKeyValue                      // NodeKeyValue is a key = value pair.

#NodeKey

const NodeKey                           // NodeKey is a (possibly dotted) key.

#NodeString

const NodeString                        // NodeString is a string value.

#NodeInteger

const NodeInteger                       // NodeInteger is an integer value.

#NodeFloat

const NodeFloat                         // NodeFloat is a float value.

#NodeBoolean

const NodeBoolean                       // NodeBoolean is a boolean value.

#NodeDateTime

const NodeDateTime                      // NodeDateTime is an offset date-time value.

#NodeLocalDateTime

const NodeLocalDateTime                 // NodeLocalDateTime is a local date-time value (no timezone).

#NodeLocalDate

const NodeLocalDate                     // NodeLocalDate is a local date value.

#NodeLocalTime

const NodeLocalTime                     // NodeLocalTime is a local time value.

#NodeArray

const NodeArray                         // NodeArray is an array value.

#NodeInlineTable

const NodeInlineTable                   // NodeInlineTable is an inline table value.

#NodeComment

const NodeComment                       // NodeComment is a standalone comment line.

#StringBasic

const StringBasic            StringStyle = iota // StringBasic is a double-quoted string ("...").

#StringLiteral

const StringLiteral                             // StringLiteral is a single-quoted string ('...').

#StringMultiLineBasic

const StringMultiLineBasic                      // StringMultiLineBasic is a triple-double-quoted string ("""...""").

#StringMultiLineLiteral

const StringMultiLineLiteral                    // StringMultiLineLiteral is a triple-single-quoted string ('''...''').

#IntegerDecimal

const IntegerDecimal IntegerBase = iota // IntegerDecimal is base-10 (e.g. 42).

#IntegerHex

const IntegerHex                        // IntegerHex is base-16 (e.g. 0xFF).

#IntegerOctal

const IntegerOctal                      // IntegerOctal is base-8 (e.g. 0o77).

#IntegerBinary

const IntegerBinary                     // IntegerBinary is base-2 (e.g. 0b1010).

#TokenBareKey

const TokenBareKey                TokenType = iota // TokenBareKey is an unquoted key (e.g. host).

#TokenBasicString

const TokenBasicString                             // TokenBasicString is a double-quoted string ("...").

#TokenLiteralString

const TokenLiteralString                           // TokenLiteralString is a single-quoted string ('...').

#TokenMultiLineBasicString

const TokenMultiLineBasicString                    // TokenMultiLineBasicString is a triple-double-quoted string.

#TokenMultiLineLiteralString

const TokenMultiLineLiteralString                  // TokenMultiLineLiteralString is a triple-single-quoted string.

#TokenInteger

const TokenInteger                                 // TokenInteger is an integer literal.

#TokenFloat

const TokenFloat                                   // TokenFloat is a float literal.

#TokenBoolean

const TokenBoolean                                 // TokenBoolean is true or false.

#TokenOffsetDateTime

const TokenOffsetDateTime                          // TokenOffsetDateTime is a date-time with timezone offset.

#TokenLocalDateTime

const TokenLocalDateTime                           // TokenLocalDateTime is a local date-time (no timezone).

#TokenLocalDate

const TokenLocalDate                               // TokenLocalDate is a local date (YYYY-MM-DD).

#TokenLocalTime

const TokenLocalTime                               // TokenLocalTime is a local time (HH:MM:SS).

#TokenEquals

const TokenEquals                                  // TokenEquals is the = sign.

#TokenDot

const TokenDot                                     // TokenDot is the . separator in dotted keys.

#TokenComma

const TokenComma                                   // TokenComma is a , separator.

#TokenLeftBracket

const TokenLeftBracket                             // TokenLeftBracket is [.

#TokenRightBracket

const TokenRightBracket                            // TokenRightBracket is ].

#TokenDoubleLeftBracket

const TokenDoubleLeftBracket                       // TokenDoubleLeftBracket is [[.

#TokenDoubleRightBracket

const TokenDoubleRightBracket                      // TokenDoubleRightBracket is ]].

#TokenLeftBrace

const TokenLeftBrace                               // TokenLeftBrace is {.

#TokenRightBrace

const TokenRightBrace                              // TokenRightBrace is }.

#TokenComment

const TokenComment                                 // TokenComment is a # comment.

#TokenWhitespace

const TokenWhitespace                              // TokenWhitespace is spaces or tabs.

#TokenNewline

const TokenNewline                                 // TokenNewline is a line break.

#TokenEOF

const TokenEOF                                     // TokenEOF marks end of input.

#WalkLeaves

const WalkLeaves WalkMode = iota

WalkLeaves visits only scalar (leaf) values. Container nodes (InlineTableNode, ArrayNode) are not passed to fn, but their children are still recursed into.

#WalkAll

const WalkAll

WalkAll visits containers (inline tables, arrays) AND their children. The visitor is called for every node.

#SkipTable

var SkipTable = errors.New("skip table")

SkipTable is a sentinel error returned from a Walk visitor function to skip the current table's children (or inline table's children). Returning SkipTable on a scalar node is a no-op.

#Cursor

type Cursor struct

Cursor provides a fluent, nil-safe API for navigating a TOML document's AST. A Cursor is never nil. If navigation fails at any point, the cursor captures the error and all subsequent operations (Key, At, String, etc.) become no-ops that propagate the original error. Check Err after a chain of calls to see whether the traversal succeeded.

#ChangeKind

type ChangeKind int

ChangeKind identifies the type of difference between two documents.

#Change

type Change struct

Change represents a single difference between two documents. OldValue is nil for Added changes; NewValue is nil for Removed changes.

#ParseError

type ParseError struct

ParseError represents a lexing or parsing error with position information. Line and Column are 1-based. Snippet may contain a fragment of the source near the error for diagnostic purposes.

#FormatConfig

type FormatConfig struct

FormatConfig controls how the formatter normalizes TOML output. Use DefaultFormatConfig to get sensible defaults and WithIndentWidth, WithLineWidth, or WithTableBlankLine to override specific settings.

#FormatOption

type FormatOption func(*FormatConfig)

FormatOption is a functional option for configuring the formatter.

#NodeType

type NodeType int

NodeType identifies the kind of AST node.

#Trivia

type Trivia struct

Trivia holds formatting and comment data attached to a node.

#Node

type Node interface

Node is the interface implemented by all AST nodes. Every node carries its original raw bytes, trivia (whitespace and comments), and a semantic value accessible via Value. Implementation is restricted to this package.

#LocalDateTime

type LocalDateTime struct

LocalDateTime represents a TOML local date-time (no timezone).

#LocalDate

type LocalDate struct

LocalDate represents a TOML local date.

#LocalTime

type LocalTime struct

LocalTime represents a TOML local time.

#StringStyle

type StringStyle int

StringStyle indicates the quoting style for a string node.

#IntegerBase

type IntegerBase int

IntegerBase indicates the numeric base for an integer node.

#DocumentNode

type DocumentNode struct

DocumentNode is the root node of a TOML document.

#TableNode

type TableNode struct

TableNode represents a [table] header and its children.

#ArrayTableNode

type ArrayTableNode struct

ArrayTableNode represents an [[array-table]] header and its children.

#KeyValueNode

type KeyValueNode struct

KeyValueNode represents a key = value pair.

#KeyNode

type KeyNode struct

KeyNode represents a (possibly dotted) key.

#StringNode

type StringNode struct

StringNode represents a string value.

#IntegerNode

type IntegerNode struct

IntegerNode represents an integer value.

#FloatNode

type FloatNode struct

FloatNode represents a float value.

#BooleanNode

type BooleanNode struct

BooleanNode represents a boolean value.

#DateTimeNode

type DateTimeNode struct

DateTimeNode represents an offset date-time value.

#LocalDateTimeNode

type LocalDateTimeNode struct

LocalDateTimeNode represents a local date-time value (no timezone).

#LocalDateNode

type LocalDateNode struct

LocalDateNode represents a local date value.

#LocalTimeNode

type LocalTimeNode struct

LocalTimeNode represents a local time value.

#ArrayNode

type ArrayNode struct

ArrayNode represents an array value.

#InlineTableNode

type InlineTableNode struct

InlineTableNode represents an inline table value.

#CommentNode

type CommentNode struct

CommentNode represents a standalone comment line.

#TokenType

type TokenType int

TokenType identifies the kind of lexical token.

#Token

type Token struct

Token represents a single lexical token from TOML source.

#Unmarshaler

type Unmarshaler interface

Unmarshaler is implemented by types that can unmarshal themselves from a TOML Node. The node passed to UnmarshalTOML is the raw AST node (e.g. a StringNode, IntegerNode, or TableNode), allowing custom decoding logic.

#WalkMode

type WalkMode int

WalkMode controls which nodes the Walk visitor function is called for.

#Diff

func Diff(a, b *DocumentNode) []Change

Diff returns all differences between documents a and b.

It walks both documents to collect all leaf (scalar) values, then compares them. Container nodes (inline tables, arrays) are not compared directly; instead their individual elements are compared. Changes are sorted by path (alphabetical), then by kind (Removed, Modified, Added).

#DefaultFormatConfig

func DefaultFormatConfig() FormatConfig

DefaultFormatConfig returns a FormatConfig with sensible defaults.

#WithIndentWidth

func WithIndentWidth(n int) FormatOption

WithIndentWidth sets the number of spaces per indent level for values under table headers.

#WithLineWidth

func WithLineWidth(n int) FormatOption

WithLineWidth sets the maximum line width before arrays are rendered in multi-line format.

#WithTableBlankLine

func WithTableBlankLine(b bool) FormatOption

WithTableBlankLine controls whether a blank line is inserted before table headers.

#Parse

func Parse(src []byte) (*DocumentNode, error)

Parse lexes and parses TOML source bytes into a DocumentNode AST.

The returned DocumentNode preserves all whitespace, comments, and formatting from the original source. Serializing it back with Bytes produces the exact original bytes (round-trip fidelity).

Returns a *ParseError on any lexing or parsing error, including duplicate key detection and invalid TOML syntax.

#Unmarshal

func Unmarshal(data []byte, v any) error

Unmarshal parses TOML data and decodes it into v.

v must be a non-nil pointer to a struct or map[string]any. Struct fields are matched by their "toml" tag, then by exact field name, then by case-insensitive name. Unknown TOML keys are silently ignored. Types implementing Unmarshaler or encoding.TextUnmarshaler are handled automatically.

#DocumentNode.SetComment

func (d *DocumentNode) SetComment(path string, comment string) error

SetComment sets the inline comment on the node at the given path. The comment string should NOT include the "# " prefix -- it will be added automatically. An empty string removes the comment. For table paths, the comment is set on the table header line. Returns an error if the path does not exist or targets a member of an inline table (TOML forbids comments inside inline tables).

#DocumentNode.SetLeadingComments

func (d *DocumentNode) SetLeadingComments(path string, comments []string) error

SetLeadingComments sets the leading comment lines on the node at the given path. Each string should NOT include the "# " prefix -- it will be added automatically. For table paths, the comments are set on the table header. Returns an error if the path does not exist.

#DocumentNode.Key

func (d *DocumentNode) Key(name string) *Cursor

Key returns a Cursor navigated to the named child of the document root. This is the entry point for the fluent cursor API. Chain additional Key or At calls to traverse deeper, then extract the value with String, Int, etc.

#Cursor.Key

func (c *Cursor) Key(name string) *Cursor

Key navigates to a named child within the current scope.

#Cursor.At

func (c *Cursor) At(index int) *Cursor

At navigates to an array index. Supports negative indices.

#Cursor.Node

func (c *Cursor) Node() Node

Node returns the current node, or nil if the cursor has an error.

#Cursor.Err

func (c *Cursor) Err() error

Err returns the first error encountered during navigation.

#Cursor.String

func (c *Cursor) String() (string, bool)

String extracts a string value from the current node. Returns ("", false) if the cursor has an error or the node is not a string.

#Cursor.Int

func (c *Cursor) Int() (int64, bool)

Int extracts an integer value from the current node. Returns (0, false) if the cursor has an error or the node is not an integer.

#Cursor.Bool

func (c *Cursor) Bool() (bool, bool)

Bool extracts a boolean value from the current node. Returns (false, false) if the cursor has an error or the node is not a boolean.

#Cursor.Float

func (c *Cursor) Float() (float64, bool)

Float extracts a float64 value from the current node. Returns (0, false) if the cursor has an error or the node is not a float.

#Cursor.Time

func (c *Cursor) Time() (time.Time, bool)

Time extracts a time.Time value from the current node. Returns (time.Time{}, false) if the cursor has an error or the node is not an offset date-time.

#ChangeKind.String

func (k ChangeKind) String() string

String returns the human-readable name of the change kind.

#dottedKeyView.Type

func (d *dottedKeyView) Type() NodeType { return NodeKeyValue }

#dottedKeyView.Value

func (d *dottedKeyView) Value() any     { return d.kv.Val }

#dottedKeyGroup.Type

func (g *dottedKeyGroup) Type() NodeType { return NodeTable }

#dottedKeyGroup.Value

func (g *dottedKeyGroup) Value() any     { return g.kvs }

#compoundTableView.Type

func (c *compoundTableView) Type() NodeType { return NodeTable }

#compoundTableView.Value

func (c *compoundTableView) Value() any     { return nil }

#arrayTableCollection.Type

func (a *arrayTableCollection) Type() NodeType { return NodeArrayTable }

#arrayTableCollection.Value

func (a *arrayTableCollection) Value() any     { return a.entries }

#DocumentNode.Get

func (d *DocumentNode) Get(path string) Node

Get resolves the dot-separated path against the document and returns the target node. For key-value pairs, the value node is returned (not the KeyValueNode wrapper). Returns nil if the path is syntactically invalid or the key is not found.

Path syntax uses dots to separate keys (e.g. "server.host"), brackets for array indices (e.g. "items[0]"), and supports negative indices (e.g. "items[-1]" for the last element). Use Resolve for the same operation with error details.

#DocumentNode.Resolve

func (d *DocumentNode) Resolve(path string) (Node, error)

Resolve resolves the dot-separated path against the document and returns the target node. Unlike Get, it returns descriptive errors for both path syntax errors and resolution failures, making it suitable for cases where the caller needs to distinguish "not found" from "invalid path".

#DocumentNode.GetString

func (d *DocumentNode) GetString(path string) (string, bool)

GetString resolves the path and returns the string value. Returns ("", false) if the path is not found or the value is not a string.

#DocumentNode.GetInt

func (d *DocumentNode) GetInt(path string) (int64, bool)

GetInt resolves the path and returns the integer value. Returns (0, false) if the path is not found or the value is not an integer.

#DocumentNode.GetBool

func (d *DocumentNode) GetBool(path string) (bool, bool)

GetBool resolves the path and returns the boolean value. Returns (false, false) if the path is not found or the value is not a boolean.

#DocumentNode.GetFloat

func (d *DocumentNode) GetFloat(path string) (float64, bool)

GetFloat resolves the path and returns the float64 value. Returns (0, false) if the path is not found or the value is not a float.

#DocumentNode.GetTime

func (d *DocumentNode) GetTime(path string) (time.Time, bool)

GetTime resolves the path and returns a time.Time value. Returns (time.Time{}, false) if the path is not found or the value is not an offset date-time.

#DocumentNode.Set

func (d *DocumentNode) Set(path string, value any) error

Set updates the value at the given path. If the final key does not exist in an existing parent, it is created as a new key-value pair. Returns an error if intermediate path segments do not exist.

Supported value types: string, bool, int/int8-64, uint/uint8-64, float32/64, time.Time, LocalDateTime, LocalDate, LocalTime, []any, map[string]any, and any type implementing the Node interface. Use SetCreate to auto-create intermediate tables.

#DocumentNode.SetCreate

func (d *DocumentNode) SetCreate(path string, value any) error

SetCreate is like Set but auto-creates intermediate [table] headers when they do not exist. Missing tables are appended to the document. This is convenient for inserting values into deeply nested paths that may not yet exist.

#DocumentNode.Delete

func (d *DocumentNode) Delete(path string) error

Delete removes the node at the given path from the document. It handles key-value pairs, tables, array-of-tables, and array elements. Returns nil (no error) if the path does not exist, making it safe to call unconditionally.

#DocumentNode.Rename

func (d *DocumentNode) Rename(path string, newKey string) error

Rename changes the key name of the node at the given path to newKey. Returns an error if the path does not exist, if newKey conflicts with an existing sibling key, or if the last path segment is an array index (only key segments can be renamed).

#DocumentNode.NewTable

func (d *DocumentNode) NewTable(path string) error

NewTable creates a new [table] header at the given path and appends it to the document. The path must consist of key segments only (no array indices). Returns an error if a table with that exact path already exists.

#DocumentNode.NewArrayTable

func (d *DocumentNode) NewArrayTable(path string) error

NewArrayTable appends a new [[array-table]] entry at the given path. Multiple entries with the same path are valid in TOML and represent successive elements of the array. The path must consist of key segments only (no array indices).

#ParseError.Error

func (e *ParseError) Error() string

#DocumentNode.Format

func (d *DocumentNode) Format(opts ...FormatOption) []byte

Format returns normalized TOML bytes. It does NOT mutate the document -- it produces a new byte slice by walking the AST and re-rendering every node with consistent formatting, ignoring all raw bytes. This is useful for enforcing a canonical style. Pass zero or more FormatOption values (e.g. WithIndentWidth, WithLineWidth) to customize the output.

#DocumentNode.Items

func (d *DocumentNode) Items(path string) iter.Seq2[int, Node]

Items returns a range-over-func iterator over elements at the given path. Works with ArrayNode elements (inline arrays) and array-of-tables entries. Returns an empty iterator if the path is invalid, not found, or points to a non-array node. Use with a range loop:

for i, node := range doc.Items("servers") { ... }

#DocumentNode.Len

func (d *DocumentNode) Len(path string) int

Len returns the number of elements at the path. Returns -1 if the path is invalid, does not exist, or does not point to an array or array-of-tables.

#Cursor.Items

func (c *Cursor) Items() iter.Seq2[int, Node]

Items returns a range-over-func iterator over elements of the current node. Works with ArrayNode elements and array-of-tables entries. An inert cursor (with error) yields nothing.

#Cursor.Len

func (c *Cursor) Len() int

Len returns the number of elements at the current cursor position. Returns -1 if the cursor has an error or the node isn't an array/array-of-tables.

#DocumentNode.MergeDefaults

func (d *DocumentNode) MergeDefaults(path string, defaults map[string]any) error

MergeDefaults recursively walks defaults and sets keys that do not exist in the document at the given path. If path is empty, merges at the document root.

Maps (map[string]any) merge recursively: only missing keys are set. Scalars and arrays are atomic: existing keys are never overwritten. This is useful for applying default configuration values to a user-provided TOML file.

#DocumentNode.Merge

func (d *DocumentNode) Merge(other *DocumentNode) error

Merge merges all values from the other document into d. Same recursive semantics as MergeDefaults: only keys that do not exist in d are set; existing values are never overwritten.

Comment handling: - For existing keys: other's leading comments are appended to d's leading comments; if d has no inline comment and other does, it is copied. - For new keys: comments from other are brought along with the value.

Array-of-tables are treated atomically: if d already has entries for a given path, all of other's entries for that path are skipped.

#NodeType.String

func (n NodeType) String() string

String returns the human-readable name of the node type.

#nodeBase.Raw

func (n *nodeBase) Raw() []byte

#nodeBase.Comment

func (n *nodeBase) Comment() string

#nodeBase.SetComment

func (n *nodeBase) SetComment(comment string)

#nodeBase.LeadingComments

func (n *nodeBase) LeadingComments() []string

#nodeBase.SetLeadingComments

func (n *nodeBase) SetLeadingComments(comments []string)

#DocumentNode.Type

func (n *DocumentNode) Type() NodeType { return NodeDocument }

#DocumentNode.Value

func (n *DocumentNode) Value() any     { return n.Children }

#TableNode.Type

func (n *TableNode) Type() NodeType { return NodeTable }

#TableNode.Value

func (n *TableNode) Value() any     { return n.Children }

#ArrayTableNode.Type

func (n *ArrayTableNode) Type() NodeType { return NodeArrayTable }

#ArrayTableNode.Value

func (n *ArrayTableNode) Value() any     { return n.Children }

#KeyValueNode.Type

func (n *KeyValueNode) Type() NodeType { return NodeKeyValue }

#KeyValueNode.Value

func (n *KeyValueNode) Value() any     { return n.Val }

#KeyNode.Type

func (n *KeyNode) Type() NodeType { return NodeKey }

#KeyNode.Value

func (n *KeyNode) Value() any     { return n.Parts }

#StringNode.Type

func (n *StringNode) Type() NodeType { return NodeString }

#StringNode.Value

func (n *StringNode) Value() any     { return n.Val }

#IntegerNode.Type

func (n *IntegerNode) Type() NodeType { return NodeInteger }

#IntegerNode.Value

func (n *IntegerNode) Value() any     { return n.Val }

#FloatNode.Type

func (n *FloatNode) Type() NodeType { return NodeFloat }

#FloatNode.Value

func (n *FloatNode) Value() any     { return n.Val }

#BooleanNode.Type

func (n *BooleanNode) Type() NodeType { return NodeBoolean }

#BooleanNode.Value

func (n *BooleanNode) Value() any     { return n.Val }

#DateTimeNode.Type

func (n *DateTimeNode) Type() NodeType { return NodeDateTime }

#DateTimeNode.Value

func (n *DateTimeNode) Value() any     { return n.Val }

#LocalDateTimeNode.Type

func (n *LocalDateTimeNode) Type() NodeType { return NodeLocalDateTime }

#LocalDateTimeNode.Value

func (n *LocalDateTimeNode) Value() any     { return n.Val }

#LocalDateNode.Type

func (n *LocalDateNode) Type() NodeType { return NodeLocalDate }

#LocalDateNode.Value

func (n *LocalDateNode) Value() any     { return n.Val }

#LocalTimeNode.Type

func (n *LocalTimeNode) Type() NodeType { return NodeLocalTime }

#LocalTimeNode.Value

func (n *LocalTimeNode) Value() any     { return n.Val }

#ArrayNode.Type

func (n *ArrayNode) Type() NodeType { return NodeArray }

#ArrayNode.Value

func (n *ArrayNode) Value() any     { return n.Elements }

#InlineTableNode.Type

func (n *InlineTableNode) Type() NodeType { return NodeInlineTable }

#InlineTableNode.Value

func (n *InlineTableNode) Value() any     { return n.Children }

#CommentNode.Type

func (n *CommentNode) Type() NodeType { return NodeComment }

#CommentNode.Value

func (n *CommentNode) Value() any     { return n.Text }

#DocumentNode.Bytes

func (d *DocumentNode) Bytes() []byte

Bytes serializes the document back to TOML bytes.

For clean documents (parsed and never modified), it returns the exact original source bytes (round-trip fidelity). For nodes that have been modified via Set, Delete, or other editing operations, only the affected nodes are re-rendered from their semantic values; unmodified nodes retain their original formatting.

#TokenType.String

func (t TokenType) String() string

String returns the human-readable name of the token type.

#DocumentNode.Decode

func (d *DocumentNode) Decode(v any) error

Decode decodes the document's content into v. v must be a non-nil pointer to a struct or map[string]any. Unlike Unmarshal, Decode operates on an already-parsed DocumentNode, which is useful when you need both the AST (for editing) and the decoded values.

#DocumentNode.Walk

func (d *DocumentNode) Walk(fn func(path string, node Node) error, mode WalkMode) error

Walk visits every key-value pair in the document in order, calling fn with the dot-path and the value node. Tables and array-of-tables are walked into (their children are visited), not yielded as standalone entries. Inline tables and arrays are yielded first, then their children are recursed into.

The mode parameter controls which nodes are visited: - WalkLeaves: only scalar values (containers are recursed but not yielded) - WalkAll: containers AND their children are yielded

The path uses dot-separated keys with bracket indices for array-of-tables entries (e.g. "servers[0].host"). Return SkipTable from fn to skip the children of the current inline table or array. Return any other non-nil error to stop the walk immediately.