Assisted-by: GLM 5.3 Flash
This commit is contained in:
@@ -25,6 +25,8 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"iter"
|
||||
"os"
|
||||
"reflect"
|
||||
"slices"
|
||||
@@ -526,6 +528,69 @@ func Marshal(v any) ([]byte, error) {
|
||||
return MarshalContext(context.Background(), v)
|
||||
}
|
||||
|
||||
// A Statement is one top-level statement of a document, what Statements
|
||||
// yields: a key with its value, a table with its node, or one element of an
|
||||
// array of tables with its node.
|
||||
type Statement struct {
|
||||
// Key is the key as the document wrote it.
|
||||
Key string
|
||||
// Value is the value of a key/value statement, and the value map of a
|
||||
// table statement.
|
||||
Value any
|
||||
// Table is the node of a table or array-of-tables statement, carrying the
|
||||
// written key order and the comments; nil for a plain key/value.
|
||||
Table *Table
|
||||
// Index is the element's position when the statement is one element of an
|
||||
// array of tables, and -1 otherwise.
|
||||
Index int
|
||||
}
|
||||
|
||||
// Statements reads a TOML document from r and returns an iterator over its
|
||||
// top-level statements in written order: key/value statements, a [table]
|
||||
// header as one statement carrying its Table node, and an [[array of
|
||||
// tables]] as one statement per element, each with the element's node and
|
||||
// its Index. Iteration stops at the first error, which arrives as the second
|
||||
// value, and at a false yield: a caller that breaks after the statement it
|
||||
// wanted reads no further ones.
|
||||
//
|
||||
// The reader is consumed in full before the first statement is yielded,
|
||||
// because the parser scans the source in place; processing the yielded
|
||||
// statements one at a time is what bounds what the caller holds, and a
|
||||
// later direct-to-target parse removes the whole-source hold.
|
||||
func Statements(r io.Reader) iter.Seq2[Statement, error] {
|
||||
return func(yield func(Statement, error) bool) {
|
||||
data, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
yield(Statement{Index: -1}, err)
|
||||
return
|
||||
}
|
||||
doc, err := Parse(data)
|
||||
if err != nil {
|
||||
yield(Statement{Index: -1}, err)
|
||||
return
|
||||
}
|
||||
for _, e := range doc.Root().Entries() {
|
||||
if els := e.Elements(); len(els) > 0 {
|
||||
for i, el := range els {
|
||||
if !yield(Statement{Key: e.Key(), Value: e.Value(), Table: el, Index: i}, nil) {
|
||||
return
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if child := e.Table(); child != nil {
|
||||
if !yield(Statement{Key: e.Key(), Value: e.Value(), Table: child, Index: -1}, nil) {
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
if !yield(Statement{Key: e.Key(), Value: e.Value(), Index: -1}, nil) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalAppend appends the TOML encoding of v to buf and returns the extended
|
||||
// buffer, the shape json.MarshalAppend has. A failed encoding leaves buf
|
||||
// untouched and comes back with a nil slice.
|
||||
|
||||
Reference in New Issue
Block a user