feat: add field comments, local time zone decoding and in-value cancellation
Test / test (push) Successful in 1m32s

Assisted-by: GLM 5.3 Flash
This commit is contained in:
2026-09-22 00:44:23 +02:00
parent 71bd82a7a5
commit d18935ebc2
8 changed files with 307 additions and 11 deletions
+30
View File
@@ -29,6 +29,7 @@ import (
"reflect"
"slices"
"strings"
"time"
)
// A SyntaxError describes a malformed TOML document. Line is the 1-based line
@@ -321,6 +322,7 @@ type Decoder struct {
useNumber bool
maxDepth int
maxInputSize int
localLoc *time.Location
}
// NewDecoder returns a Decoder.
@@ -343,6 +345,17 @@ func (d *Decoder) UseNumber() *Decoder {
return d
}
// LocalTimeLocation sets the zone a local date-time is placed in when it
// decodes into a time.Time destination. Without the option a local date-time
// fills only its own wrapper type (LocalDateTime, LocalDate, LocalTime),
// whose embedded time.Time is UTC; with the option, a time.Time destination
// takes the value too, carried in the location given. A nil location restores
// the default.
func (d *Decoder) LocalTimeLocation(loc *time.Location) *Decoder {
d.localLoc = loc
return d
}
// MaxDepth bounds how deeply arrays and inline tables may nest in a document
// this decoder accepts. The parser is a recursive descent, so a document that
// nests without bound would exhaust the stack; one that nests deeper than the
@@ -388,6 +401,7 @@ func (d *Decoder) DecodeContext(ctx context.Context, data []byte, v any) error {
dec.disallowUnknown = d.disallowUnknown
dec.ctx = ctx
dec.nodes = indexNodes(doc.Root())
dec.loc = d.localLoc
return dec.decode(tree, v)
}
@@ -552,6 +566,7 @@ type Encoder struct {
omitEmptyArrays bool // default false; set via (*Encoder).OmitEmptyArrays
literalMultilineAt int // default 0; set via (*Encoder).UseLiteralMultiline
inlineTablesAt int // default 0; set via (*Encoder).InlineTables
emitFieldComments bool // default false; set via (*Encoder).EmitFieldComments
}
// NewEncoder returns an Encoder with default options.
@@ -602,6 +617,21 @@ func (e *Encoder) InlineTables(threshold int) *Encoder {
return e
}
// EmitFieldComments turns on printing the comment a field's `toml` tag
// carries in a `comment=` option, above the field's line or header, the
// comments a round trip through the Go type would otherwise drop:
//
// Port int `toml:"port,comment=The port to listen on"`
//
// Go doc comments are not visible to reflection, so the tag is the channel
// that carries the text. Off by default, and a field without a `comment=`
// option prints none. Multi-line comments carry newlines in the tag, each
// line printed with its own "# " marker.
func (e *Encoder) EmitFieldComments() *Encoder {
e.emitFieldComments = true
return e
}
// Marshal encodes v to TOML bytes. It is equivalent to calling Marshal with v.
//
// Marshal is equivalent to MarshalContext with context.Background.