Documentation
¶
Overview ¶
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
Index ¶
- Variables
- func Unmarshal(data []byte, v any) error
- type ArrayNode
- type ArrayTableNode
- func (n *ArrayTableNode) Comment() string
- func (n *ArrayTableNode) LeadingComments() []string
- func (n *ArrayTableNode) Raw() []byte
- func (n *ArrayTableNode) SetComment(comment string)
- func (n *ArrayTableNode) SetLeadingComments(comments []string)
- func (n *ArrayTableNode) Type() NodeType
- func (n *ArrayTableNode) Value() any
- type BooleanNode
- func (n *BooleanNode) Comment() string
- func (n *BooleanNode) LeadingComments() []string
- func (n *BooleanNode) Raw() []byte
- func (n *BooleanNode) SetComment(comment string)
- func (n *BooleanNode) SetLeadingComments(comments []string)
- func (n *BooleanNode) Type() NodeType
- func (n *BooleanNode) Value() any
- type Change
- type ChangeKind
- type CommentNode
- func (n *CommentNode) Comment() string
- func (n *CommentNode) LeadingComments() []string
- func (n *CommentNode) Raw() []byte
- func (n *CommentNode) SetComment(comment string)
- func (n *CommentNode) SetLeadingComments(comments []string)
- func (n *CommentNode) Type() NodeType
- func (n *CommentNode) Value() any
- type Cursor
- func (c *Cursor) At(index int) *Cursor
- func (c *Cursor) Bool() (bool, bool)
- func (c *Cursor) Err() error
- func (c *Cursor) Float() (float64, bool)
- func (c *Cursor) Int() (int64, bool)
- func (c *Cursor) Items() iter.Seq2[int, Node]
- func (c *Cursor) Key(name string) *Cursor
- func (c *Cursor) Len() int
- func (c *Cursor) Node() Node
- func (c *Cursor) String() (string, bool)
- func (c *Cursor) Time() (time.Time, bool)
- type DateTimeNode
- func (n *DateTimeNode) Comment() string
- func (n *DateTimeNode) LeadingComments() []string
- func (n *DateTimeNode) Raw() []byte
- func (n *DateTimeNode) SetComment(comment string)
- func (n *DateTimeNode) SetLeadingComments(comments []string)
- func (n *DateTimeNode) Type() NodeType
- func (n *DateTimeNode) Value() any
- type DocumentNode
- func (d *DocumentNode) Bytes() []byte
- func (n *DocumentNode) Comment() string
- func (d *DocumentNode) Decode(v any) error
- func (d *DocumentNode) Delete(path string) error
- func (d *DocumentNode) Format(opts ...FormatOption) []byte
- func (d *DocumentNode) Get(path string) Node
- func (d *DocumentNode) GetBool(path string) (bool, bool)
- func (d *DocumentNode) GetFloat(path string) (float64, bool)
- func (d *DocumentNode) GetInt(path string) (int64, bool)
- func (d *DocumentNode) GetString(path string) (string, bool)
- func (d *DocumentNode) GetTime(path string) (time.Time, bool)
- func (d *DocumentNode) Items(path string) iter.Seq2[int, Node]
- func (d *DocumentNode) Key(name string) *Cursor
- func (n *DocumentNode) LeadingComments() []string
- func (d *DocumentNode) Len(path string) int
- func (d *DocumentNode) Merge(other *DocumentNode) error
- func (d *DocumentNode) MergeDefaults(path string, defaults map[string]any) error
- func (d *DocumentNode) NewArrayTable(path string) error
- func (d *DocumentNode) NewTable(path string) error
- func (n *DocumentNode) Raw() []byte
- func (d *DocumentNode) Rename(path string, newKey string) error
- func (d *DocumentNode) Resolve(path string) (Node, error)
- func (d *DocumentNode) Set(path string, value any) error
- func (d *DocumentNode) SetComment(path string, comment string) error
- func (d *DocumentNode) SetCreate(path string, value any) error
- func (d *DocumentNode) SetLeadingComments(path string, comments []string) error
- func (n *DocumentNode) Type() NodeType
- func (n *DocumentNode) Value() any
- func (d *DocumentNode) Walk(fn func(path string, node Node) error, mode WalkMode) error
- type FloatNode
- type FormatConfig
- type FormatOption
- type InlineTableNode
- func (n *InlineTableNode) Comment() string
- func (n *InlineTableNode) LeadingComments() []string
- func (n *InlineTableNode) Raw() []byte
- func (n *InlineTableNode) SetComment(comment string)
- func (n *InlineTableNode) SetLeadingComments(comments []string)
- func (n *InlineTableNode) Type() NodeType
- func (n *InlineTableNode) Value() any
- type IntegerBase
- type IntegerNode
- func (n *IntegerNode) Comment() string
- func (n *IntegerNode) LeadingComments() []string
- func (n *IntegerNode) Raw() []byte
- func (n *IntegerNode) SetComment(comment string)
- func (n *IntegerNode) SetLeadingComments(comments []string)
- func (n *IntegerNode) Type() NodeType
- func (n *IntegerNode) Value() any
- type KeyNode
- type KeyValueNode
- func (n *KeyValueNode) Comment() string
- func (n *KeyValueNode) LeadingComments() []string
- func (n *KeyValueNode) Raw() []byte
- func (n *KeyValueNode) SetComment(comment string)
- func (n *KeyValueNode) SetLeadingComments(comments []string)
- func (n *KeyValueNode) Type() NodeType
- func (n *KeyValueNode) Value() any
- type LocalDate
- type LocalDateNode
- func (n *LocalDateNode) Comment() string
- func (n *LocalDateNode) LeadingComments() []string
- func (n *LocalDateNode) Raw() []byte
- func (n *LocalDateNode) SetComment(comment string)
- func (n *LocalDateNode) SetLeadingComments(comments []string)
- func (n *LocalDateNode) Type() NodeType
- func (n *LocalDateNode) Value() any
- type LocalDateTime
- type LocalDateTimeNode
- func (n *LocalDateTimeNode) Comment() string
- func (n *LocalDateTimeNode) LeadingComments() []string
- func (n *LocalDateTimeNode) Raw() []byte
- func (n *LocalDateTimeNode) SetComment(comment string)
- func (n *LocalDateTimeNode) SetLeadingComments(comments []string)
- func (n *LocalDateTimeNode) Type() NodeType
- func (n *LocalDateTimeNode) Value() any
- type LocalTime
- type LocalTimeNode
- func (n *LocalTimeNode) Comment() string
- func (n *LocalTimeNode) LeadingComments() []string
- func (n *LocalTimeNode) Raw() []byte
- func (n *LocalTimeNode) SetComment(comment string)
- func (n *LocalTimeNode) SetLeadingComments(comments []string)
- func (n *LocalTimeNode) Type() NodeType
- func (n *LocalTimeNode) Value() any
- type Node
- type NodeType
- type ParseError
- type StringNode
- type StringStyle
- type TableNode
- type Token
- type TokenType
- type Trivia
- type Unmarshaler
- type WalkMode
Examples ¶
Constants ¶
This section is empty.
Variables ¶
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.
Functions ¶
func Unmarshal ¶
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.
Example ¶
type Config struct {
Title string `toml:"title"`
Server struct {
Host string `toml:"host"`
Port int `toml:"port"`
} `toml:"server"`
}
var cfg Config
err := tomledit.Unmarshal([]byte(`title = "My App"
[server]
host = "0.0.0.0"
port = 443
`), &cfg)
if err != nil {
panic(err)
}
fmt.Println(cfg.Title)
fmt.Println(cfg.Server.Host)
fmt.Println(cfg.Server.Port)
Output: My App 0.0.0.0 443
Types ¶
type ArrayNode ¶
type ArrayNode struct {
Elements []Node
TrailingComments [][]byte // comments after the last element, before ']'
// contains filtered or unexported fields
}
ArrayNode represents an array value.
func (*ArrayNode) LeadingComments ¶
func (n *ArrayNode) LeadingComments() []string
func (*ArrayNode) SetComment ¶
func (n *ArrayNode) SetComment(comment string)
func (*ArrayNode) SetLeadingComments ¶
func (n *ArrayNode) SetLeadingComments(comments []string)
type ArrayTableNode ¶
type ArrayTableNode struct {
KeyPath []string
Children []Node
// contains filtered or unexported fields
}
ArrayTableNode represents an [[array-table]] header and its children.
func (*ArrayTableNode) LeadingComments ¶
func (n *ArrayTableNode) LeadingComments() []string
func (*ArrayTableNode) SetComment ¶
func (n *ArrayTableNode) SetComment(comment string)
func (*ArrayTableNode) SetLeadingComments ¶
func (n *ArrayTableNode) SetLeadingComments(comments []string)
func (*ArrayTableNode) Type ¶
func (n *ArrayTableNode) Type() NodeType
func (*ArrayTableNode) Value ¶
func (n *ArrayTableNode) Value() any
type BooleanNode ¶
type BooleanNode struct {
Val bool
// contains filtered or unexported fields
}
BooleanNode represents a boolean value.
func (*BooleanNode) LeadingComments ¶
func (n *BooleanNode) LeadingComments() []string
func (*BooleanNode) SetComment ¶
func (n *BooleanNode) SetComment(comment string)
func (*BooleanNode) SetLeadingComments ¶
func (n *BooleanNode) SetLeadingComments(comments []string)
func (*BooleanNode) Type ¶
func (n *BooleanNode) Type() NodeType
func (*BooleanNode) Value ¶
func (n *BooleanNode) Value() any
type Change ¶
type Change struct {
Kind ChangeKind
Path string
OldValue any // nil for Added
NewValue any // nil for Removed
}
Change represents a single difference between two documents. OldValue is nil for Added changes; NewValue is nil for Removed changes.
func 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).
Example ¶
a, _ := tomledit.Parse([]byte(`name = "Alice"
age = 30
`))
b, _ := tomledit.Parse([]byte(`name = "Bob"
email = "bob@example.com"
`))
changes := tomledit.Diff(a, b)
for _, c := range changes {
fmt.Printf("%s: %s\n", c.Kind, c.Path)
}
Output: removed: age added: email modified: name
type ChangeKind ¶
type ChangeKind int
ChangeKind identifies the type of difference between two documents.
const ( Added ChangeKind = iota // Added means the key exists in b but not in a. Removed // Removed means the key exists in a but not in b. Modified // Modified means the key exists in both but with different values. )
func (ChangeKind) String ¶
func (k ChangeKind) String() string
String returns the human-readable name of the change kind.
type CommentNode ¶
type CommentNode struct {
Text string
// contains filtered or unexported fields
}
CommentNode represents a standalone comment line.
func (*CommentNode) LeadingComments ¶
func (n *CommentNode) LeadingComments() []string
func (*CommentNode) SetComment ¶
func (n *CommentNode) SetComment(comment string)
func (*CommentNode) SetLeadingComments ¶
func (n *CommentNode) SetLeadingComments(comments []string)
func (*CommentNode) Type ¶
func (n *CommentNode) Type() NodeType
func (*CommentNode) Value ¶
func (n *CommentNode) Value() any
type Cursor ¶
type Cursor struct {
// contains filtered or unexported fields
}
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.
func (*Cursor) 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.
func (*Cursor) Float ¶
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.
func (*Cursor) Int ¶
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.
func (*Cursor) Items ¶
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.
func (*Cursor) Len ¶
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.
type DateTimeNode ¶
DateTimeNode represents an offset date-time value.
func (*DateTimeNode) LeadingComments ¶
func (n *DateTimeNode) LeadingComments() []string
func (*DateTimeNode) SetComment ¶
func (n *DateTimeNode) SetComment(comment string)
func (*DateTimeNode) SetLeadingComments ¶
func (n *DateTimeNode) SetLeadingComments(comments []string)
func (*DateTimeNode) Type ¶
func (n *DateTimeNode) Type() NodeType
func (*DateTimeNode) Value ¶
func (n *DateTimeNode) Value() any
type DocumentNode ¶
type DocumentNode struct {
Children []Node
// contains filtered or unexported fields
}
DocumentNode is the root node of a TOML document.
func 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.
Example ¶
doc, err := tomledit.Parse([]byte(`[server]
host = "localhost"
port = 8080
`))
if err != nil {
panic(err)
}
fmt.Println(doc.GetString("server.host"))
fmt.Println(doc.GetInt("server.port"))
Output: localhost true 8080 true
func (*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.
func (*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.
func (*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.
Example ¶
doc, err := tomledit.Parse([]byte(`[server]
host = "localhost"
port = 8080
debug = true
`))
if err != nil {
panic(err)
}
err = doc.Delete("server.debug")
if err != nil {
panic(err)
}
fmt.Println(doc.GetBool("server.debug"))
Output: false false
func (*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.
Example ¶
doc, err := tomledit.Parse([]byte(`name="Alice"
[server]
host="localhost"
port=8080
`))
if err != nil {
panic(err)
}
formatted := doc.Format(tomledit.WithIndentWidth(2))
fmt.Print(string(formatted))
Output: name = "Alice" [server] host = "localhost" port = 8080
func (*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.
func (*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.
func (*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.
func (*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.
func (*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.
func (*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.
func (*DocumentNode) Items ¶
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") { ... }
func (*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.
Example ¶
doc, err := tomledit.Parse([]byte(`[database]
host = "localhost"
port = 5432
`))
if err != nil {
panic(err)
}
host, ok := doc.Key("database").Key("host").String()
fmt.Println(host, ok)
port, ok := doc.Key("database").Key("port").Int()
fmt.Println(port, ok)
Output: localhost true 5432 true
func (*DocumentNode) LeadingComments ¶
func (n *DocumentNode) LeadingComments() []string
func (*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.
func (*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.
Example ¶
base, _ := tomledit.Parse([]byte(`[server]
host = "localhost"
`))
defaults, _ := tomledit.Parse([]byte(`[server]
host = "0.0.0.0"
port = 8080
`))
err := base.Merge(defaults)
if err != nil {
panic(err)
}
// host was already set, so it keeps "localhost".
fmt.Println(base.GetString("server.host"))
// port was missing, so it was added from defaults.
fmt.Println(base.GetInt("server.port"))
Output: localhost true 8080 true
func (*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.
func (*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).
func (*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.
func (*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).
func (*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".
func (*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.
Example ¶
doc, err := tomledit.Parse([]byte(`[server]
host = "localhost"
port = 8080
`))
if err != nil {
panic(err)
}
err = doc.Set("server.port", 9090)
if err != nil {
panic(err)
}
fmt.Println(doc.GetInt("server.port"))
Output: 9090 true
func (*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).
func (*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.
Example ¶
doc, err := tomledit.Parse([]byte(`title = "example"
`))
if err != nil {
panic(err)
}
// SetCreate auto-creates intermediate [database] table.
err = doc.SetCreate("database.host", "db.example.com")
if err != nil {
panic(err)
}
fmt.Println(doc.GetString("database.host"))
Output: db.example.com true
func (*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.
func (*DocumentNode) Type ¶
func (n *DocumentNode) Type() NodeType
func (*DocumentNode) Value ¶
func (n *DocumentNode) Value() any
func (*DocumentNode) Walk ¶
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.
Example ¶
doc, err := tomledit.Parse([]byte(`name = "example"
[server]
host = "localhost"
port = 8080
`))
if err != nil {
panic(err)
}
err = doc.Walk(func(path string, node tomledit.Node) error {
fmt.Printf("%s = %v\n", path, node.Value())
return nil
}, tomledit.WalkLeaves)
if err != nil {
panic(err)
}
Output: name = example server.host = localhost server.port = 8080
type FloatNode ¶
type FloatNode struct {
Val float64
// contains filtered or unexported fields
}
FloatNode represents a float value.
func (*FloatNode) LeadingComments ¶
func (n *FloatNode) LeadingComments() []string
func (*FloatNode) SetComment ¶
func (n *FloatNode) SetComment(comment string)
func (*FloatNode) SetLeadingComments ¶
func (n *FloatNode) SetLeadingComments(comments []string)
type FormatConfig ¶
type FormatConfig struct {
IndentWidth int // spaces per indent level (default: 0, no indentation of values)
LineWidth int // max line width before arrays go multi-line (default: 80)
TableBlankLine bool // insert blank line before tables (default: true)
}
FormatConfig controls how the formatter normalizes TOML output. Use DefaultFormatConfig to get sensible defaults and WithIndentWidth, WithLineWidth, or WithTableBlankLine to override specific settings.
func DefaultFormatConfig ¶
func DefaultFormatConfig() FormatConfig
DefaultFormatConfig returns a FormatConfig with sensible defaults.
type FormatOption ¶
type FormatOption func(*FormatConfig)
FormatOption is a functional option for configuring the formatter.
func WithIndentWidth ¶
func WithIndentWidth(n int) FormatOption
WithIndentWidth sets the number of spaces per indent level for values under table headers.
func WithLineWidth ¶
func WithLineWidth(n int) FormatOption
WithLineWidth sets the maximum line width before arrays are rendered in multi-line format.
func WithTableBlankLine ¶
func WithTableBlankLine(b bool) FormatOption
WithTableBlankLine controls whether a blank line is inserted before table headers.
type InlineTableNode ¶
type InlineTableNode struct {
Children []Node // KeyValueNode entries
// contains filtered or unexported fields
}
InlineTableNode represents an inline table value.
func (*InlineTableNode) LeadingComments ¶
func (n *InlineTableNode) LeadingComments() []string
func (*InlineTableNode) SetComment ¶
func (n *InlineTableNode) SetComment(comment string)
func (*InlineTableNode) SetLeadingComments ¶
func (n *InlineTableNode) SetLeadingComments(comments []string)
func (*InlineTableNode) Type ¶
func (n *InlineTableNode) Type() NodeType
func (*InlineTableNode) Value ¶
func (n *InlineTableNode) Value() any
type IntegerBase ¶
type IntegerBase int
IntegerBase indicates the numeric base for an integer node.
const ( IntegerDecimal IntegerBase = iota // IntegerDecimal is base-10 (e.g. 42). IntegerHex // IntegerHex is base-16 (e.g. 0xFF). IntegerOctal // IntegerOctal is base-8 (e.g. 0o77). IntegerBinary // IntegerBinary is base-2 (e.g. 0b1010). )
type IntegerNode ¶
type IntegerNode struct {
Val int64
Base IntegerBase
// contains filtered or unexported fields
}
IntegerNode represents an integer value.
func (*IntegerNode) LeadingComments ¶
func (n *IntegerNode) LeadingComments() []string
func (*IntegerNode) SetComment ¶
func (n *IntegerNode) SetComment(comment string)
func (*IntegerNode) SetLeadingComments ¶
func (n *IntegerNode) SetLeadingComments(comments []string)
func (*IntegerNode) Type ¶
func (n *IntegerNode) Type() NodeType
func (*IntegerNode) Value ¶
func (n *IntegerNode) Value() any
type KeyNode ¶
type KeyNode struct {
Parts []string // semantic parts (e.g. ["server", "host"])
RawParts [][]byte // original bytes for each part
Styles []StringStyle // quoting style per part
// contains filtered or unexported fields
}
KeyNode represents a (possibly dotted) key.
func (*KeyNode) LeadingComments ¶
func (n *KeyNode) LeadingComments() []string
func (*KeyNode) SetComment ¶
func (n *KeyNode) SetComment(comment string)
func (*KeyNode) SetLeadingComments ¶
func (n *KeyNode) SetLeadingComments(comments []string)
type KeyValueNode ¶
KeyValueNode represents a key = value pair.
func (*KeyValueNode) LeadingComments ¶
func (n *KeyValueNode) LeadingComments() []string
func (*KeyValueNode) SetComment ¶
func (n *KeyValueNode) SetComment(comment string)
func (*KeyValueNode) SetLeadingComments ¶
func (n *KeyValueNode) SetLeadingComments(comments []string)
func (*KeyValueNode) Type ¶
func (n *KeyValueNode) Type() NodeType
func (*KeyValueNode) Value ¶
func (n *KeyValueNode) Value() any
type LocalDate ¶
type LocalDate struct {
Year, Month, Day int
}
LocalDate represents a TOML local date.
type LocalDateNode ¶
type LocalDateNode struct {
Val LocalDate
// contains filtered or unexported fields
}
LocalDateNode represents a local date value.
func (*LocalDateNode) LeadingComments ¶
func (n *LocalDateNode) LeadingComments() []string
func (*LocalDateNode) SetComment ¶
func (n *LocalDateNode) SetComment(comment string)
func (*LocalDateNode) SetLeadingComments ¶
func (n *LocalDateNode) SetLeadingComments(comments []string)
func (*LocalDateNode) Type ¶
func (n *LocalDateNode) Type() NodeType
func (*LocalDateNode) Value ¶
func (n *LocalDateNode) Value() any
type LocalDateTime ¶
LocalDateTime represents a TOML local date-time (no timezone).
type LocalDateTimeNode ¶
type LocalDateTimeNode struct {
Val LocalDateTime
// contains filtered or unexported fields
}
LocalDateTimeNode represents a local date-time value (no timezone).
func (*LocalDateTimeNode) LeadingComments ¶
func (n *LocalDateTimeNode) LeadingComments() []string
func (*LocalDateTimeNode) SetComment ¶
func (n *LocalDateTimeNode) SetComment(comment string)
func (*LocalDateTimeNode) SetLeadingComments ¶
func (n *LocalDateTimeNode) SetLeadingComments(comments []string)
func (*LocalDateTimeNode) Type ¶
func (n *LocalDateTimeNode) Type() NodeType
func (*LocalDateTimeNode) Value ¶
func (n *LocalDateTimeNode) Value() any
type LocalTimeNode ¶
type LocalTimeNode struct {
Val LocalTime
// contains filtered or unexported fields
}
LocalTimeNode represents a local time value.
func (*LocalTimeNode) LeadingComments ¶
func (n *LocalTimeNode) LeadingComments() []string
func (*LocalTimeNode) SetComment ¶
func (n *LocalTimeNode) SetComment(comment string)
func (*LocalTimeNode) SetLeadingComments ¶
func (n *LocalTimeNode) SetLeadingComments(comments []string)
func (*LocalTimeNode) Type ¶
func (n *LocalTimeNode) Type() NodeType
func (*LocalTimeNode) Value ¶
func (n *LocalTimeNode) Value() any
type Node ¶
type Node interface {
Type() NodeType
Value() any
Comment() string
LeadingComments() []string
Raw() []byte
// contains filtered or unexported methods
}
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.
type NodeType ¶
type NodeType int
NodeType identifies the kind of AST node.
const ( NodeDocument NodeType = iota // NodeDocument is the root document node. NodeTable // NodeTable is a [table] header node. NodeArrayTable // NodeArrayTable is an [[array-table]] header node. NodeKeyValue // NodeKeyValue is a key = value pair. NodeKey // NodeKey is a (possibly dotted) key. NodeString // NodeString is a string value. NodeInteger // NodeInteger is an integer value. NodeFloat // NodeFloat is a float value. NodeBoolean // NodeBoolean is a boolean value. NodeDateTime // NodeDateTime is an offset date-time value. NodeLocalDateTime // NodeLocalDateTime is a local date-time value (no timezone). NodeLocalDate // NodeLocalDate is a local date value. NodeLocalTime // NodeLocalTime is a local time value. NodeArray // NodeArray is an array value. NodeInlineTable // NodeInlineTable is an inline table value. NodeComment // NodeComment is a standalone comment line. )
type ParseError ¶
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.
func (*ParseError) Error ¶
func (e *ParseError) Error() string
type StringNode ¶
type StringNode struct {
Val string
Style StringStyle
// contains filtered or unexported fields
}
StringNode represents a string value.
func (*StringNode) LeadingComments ¶
func (n *StringNode) LeadingComments() []string
func (*StringNode) SetComment ¶
func (n *StringNode) SetComment(comment string)
func (*StringNode) SetLeadingComments ¶
func (n *StringNode) SetLeadingComments(comments []string)
func (*StringNode) Type ¶
func (n *StringNode) Type() NodeType
func (*StringNode) Value ¶
func (n *StringNode) Value() any
type StringStyle ¶
type StringStyle int
StringStyle indicates the quoting style for a string node.
const ( StringBasic StringStyle = iota // StringBasic is a double-quoted string ("..."). StringLiteral // StringLiteral is a single-quoted string ('...'). StringMultiLineBasic // StringMultiLineBasic is a triple-double-quoted string ("""..."""). StringMultiLineLiteral // StringMultiLineLiteral is a triple-single-quoted string (”'...”'). )
type TableNode ¶
type TableNode struct {
KeyPath []string
Children []Node
// contains filtered or unexported fields
}
TableNode represents a [table] header and its children.
func (*TableNode) LeadingComments ¶
func (n *TableNode) LeadingComments() []string
func (*TableNode) SetComment ¶
func (n *TableNode) SetComment(comment string)
func (*TableNode) SetLeadingComments ¶
func (n *TableNode) SetLeadingComments(comments []string)
type Token ¶
type Token struct {
Type TokenType
Raw []byte // exact bytes from source
Line int // 1-based
Column int // 1-based
}
Token represents a single lexical token from TOML source.
type TokenType ¶
type TokenType int
TokenType identifies the kind of lexical token.
const ( TokenBareKey TokenType = iota // TokenBareKey is an unquoted key (e.g. host). TokenBasicString // TokenBasicString is a double-quoted string ("..."). TokenLiteralString // TokenLiteralString is a single-quoted string ('...'). TokenMultiLineBasicString // TokenMultiLineBasicString is a triple-double-quoted string. TokenMultiLineLiteralString // TokenMultiLineLiteralString is a triple-single-quoted string. TokenInteger // TokenInteger is an integer literal. TokenFloat // TokenFloat is a float literal. TokenBoolean // TokenBoolean is true or false. TokenOffsetDateTime // TokenOffsetDateTime is a date-time with timezone offset. TokenLocalDateTime // TokenLocalDateTime is a local date-time (no timezone). TokenLocalDate // TokenLocalDate is a local date (YYYY-MM-DD). TokenLocalTime // TokenLocalTime is a local time (HH:MM:SS). TokenEquals // TokenEquals is the = sign. TokenDot // TokenDot is the . separator in dotted keys. TokenComma // TokenComma is a , separator. TokenLeftBracket // TokenLeftBracket is [. TokenRightBracket // TokenRightBracket is ]. TokenDoubleLeftBracket // TokenDoubleLeftBracket is [[. TokenDoubleRightBracket // TokenDoubleRightBracket is ]]. TokenLeftBrace // TokenLeftBrace is {. TokenRightBrace // TokenRightBrace is }. TokenComment // TokenComment is a # comment. TokenWhitespace // TokenWhitespace is spaces or tabs. TokenNewline // TokenNewline is a line break. TokenEOF // TokenEOF marks end of input. )
type Trivia ¶
type Trivia struct {
LeadingWhitespace []byte
LeadingComments [][]byte // each is a full "# ...\n" line
InlineComment []byte // "# ..." after value on same line
TrailingNewline []byte
}
Trivia holds formatting and comment data attached to a node.
type Unmarshaler ¶
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.
type WalkMode ¶ added in v0.1.1
type WalkMode int
WalkMode controls which nodes the Walk visitor function is called for.
const ( // WalkLeaves visits only scalar (leaf) values. Container nodes // (InlineTableNode, ArrayNode) are not passed to fn, but their // children are still recursed into. WalkLeaves WalkMode = iota // WalkAll visits containers (inline tables, arrays) AND their children. // The visitor is called for every node. WalkAll )