- Fix dupl lint: add nolint:dupl to parseInlineTable and parseValArray
which have intentionally similar loop structures
- Fix gci lint: correct alignment in multiline basic string test entries
- Add unmarshaler tests for new TOML v1.1.0 features exercising public
APIs: multiline inline tables with comments, trailing commas, leading
commas, error cases (comma at start, missing separator, double comma,
incomplete table), escape sequences, and type mismatch errors
- Add parser test for inline table comment handling with KeepComments
- Coverage increases from 97.37% to 97.44% vs v2 base
https://claude.ai/code/session_01RdiWykFQdmwkQ2nbLwJwwP
TOML v1.1.0 allows times to be specified as HH:MM without the seconds
component (previously HH:MM:SS was required). This applies to local
times, local datetimes, and offset datetimes.
TOML v1.1.0 introduces the \xHH escape notation for basic strings,
allowing two-digit hex escapes for Unicode code points U+0000 to
U+00FF.
We keep emitting \u00XX for backwards compatibility.
Return a type mismatch error instead of panicking when datetime values
(DateTime, LocalDate, LocalTime, LocalDateTime) are unmarshaled into
incompatible Go types. This makes the decoder safer for processing
untrusted TOML input.
https://claude.ai/code/session_011jwvtDS5M2KncLrqJpgMr5
Co-authored-by: Claude <noreply@anthropic.com>
When a type implements encoding.TextUnmarshaler, the unmarshaler now
skips calling UnmarshalText for Array and InlineTable TOML values.
This allows types to support both:
- Simple string values via UnmarshalText
- Structured table values via field-by-field unmarshaling
Previously, UnmarshalText was called unconditionally, which prevented
proper struct unmarshaling when the TOML value was a table or array
of tables.
Co-authored-by: Claude <noreply@anthropic.com>
When marshaling a map with nil pointer values, the keys were being
silently dropped, breaking round-trip fidelity. For example:
map[string]*struct{}{"foo": nil}
Would produce an empty TOML document instead of "[foo]".
This change converts nil pointer values in maps to their zero values
(consistent with how nil pointers in slices are handled), allowing the
keys to be preserved as empty tables.
Nil interface values (map[string]any{"foo": nil}) are still skipped
since there's no type information to derive a zero value.
Fixes#975
Also, pin golangci-lint version to v2.8.0 in CI and document in AGENTS.md
- Explicitly set golangci-lint version in lint.yml to ensure consistent
behavior across CI runs
- Update AGENTS.md with instructions to use the same linter version locally
---------
Co-authored-by: Claude <noreply@anthropic.com>
The omitzero tag now respects custom IsZero() methods on types,
similar to how encoding/json handles this. Previously, only
reflect.Value.IsZero() was used, which ignores user-defined
implementations.
Fixes#1003
Co-authored-by: Claude <noreply@anthropic.com>
Go's time.Date() normalizes leap seconds (second=60) by adding 1 minute.
When parsing the maximum valid TOML date 9999-12-31 23:59:60z, this causes
the year to overflow to 10000, which exceeds the valid TOML year range
(0000-9999) and breaks round-trip serialization.
The fix rejects leap seconds (second > 59) during parsing. This is
consistent with the resolution of issue #913 which determined that
emitting an error is less surprising than silently normalizing leap
seconds.
Fixes#1015
Co-authored-by: Claude <noreply@anthropic.com>
Removes all unsafe operations from go-toml, making the codebase
fully safe Go code. The internal/danger package that contained
unsafe operations has been deleted.
Changes:
- Replace pointer-based node navigation with index-based navigation
- Node.next and Node.child now store absolute indices into the
backing nodes slice instead of relative offsets
- Add nodes pointer to Node and Iterator for safe navigation
- Replace danger.TypeID with reflect.Type for cache keys
- Delete internal/danger package entirely
Performance overhead is under 10% compared to the unsafe version,
which is acceptable for the safety and maintainability benefits.
[Cursor][claude-sonnet-4-20250514]
This file provides a concise summary of the contribution guidelines
from CONTRIBUTING.md, specifically tailored for AI agents working on
the codebase. It covers testing requirements, backward compatibility,
performance considerations, and code style expectations.
Co-authored-by: Claude <noreply@anthropic.com>
Recent versions of Go object to the use of non-constant variables a
format strings. This commit fixes errors like this:
cli.go:26:47: non-constant format string in call to fmt.Fprintf
Signed-off-by: W. Michael Petullo <mike@flyn.org>
Only 3 consecutive quotation marks need to be quoted. We choose to quote
all quotation marks in a sequence if there are 3 or more consecutive
present.
Fixes#990
---------
Co-authored-by: Thomas Pelletier <thomas@pelletier.dev>
As recommended, an `internal/assert` package was added with a reduced set of assertions. All tests were then refactored to use the internal assertions. When more complex assertions were used, they have been rewritten using logic and the simplified assertions.
Fancy formatting for failures was omitted. The `internal/assert/assertions.diff` function could be overwritten for better formatting. That is where diff libraries are used in other test suites.
Refs: #872
Co-authored-by: Alex Mikitik <alex.mikitik@oracle.com>
This way, calls to Unmarshal or Decoder.Decode allocate once
at the start rather than twice.
│ old │ new │
│ allocs/op │ allocs/op vs base │
Unmarshal/HugoFrontMatter-8 141.0 ± 0% 140.0 ± 0% -0.71% (p=0.002 n=6)
* go.mod: bump minimum and language to 1.21
CI only tests Go 1.21 and 1.22, and older versions of Go are no longer
getting any bug or security fixes, so advertise that we only support
Go 1.21 or later via go.mod.
While here, ensure the module is tidy and resolve deprecation warnings,
and remove now-unnecessary Go version build tags.
* replace sort.Slice with slices.SortFunc
The latter is more efficient, and allocates less, since sort.Slice
needs to go through sort.Interface which causes allocations.
goos: linux
goarch: amd64
pkg: github.com/pelletier/go-toml/v2/benchmark
cpu: AMD Ryzen 7 PRO 5850U with Radeon Graphics
│ old │ new │
│ sec/op │ sec/op vs base │
Marshal/HugoFrontMatter-8 7.612µ ± 1% 6.730µ ± 1% -11.59% (p=0.002 n=6)
│ old │ new │
│ B/s │ B/s vs base │
Marshal/HugoFrontMatter-8 65.52Mi ± 1% 74.11Mi ± 1% +13.11% (p=0.002 n=6)
│ old │ new │
│ B/op │ B/op vs base │
Marshal/HugoFrontMatter-8 5.672Ki ± 0% 5.266Ki ± 0% -7.16% (p=0.002 n=6)
│ old │ new │
│ allocs/op │ allocs/op vs base │
Marshal/HugoFrontMatter-8 85.00 ± 0% 73.00 ± 0% -14.12% (p=0.002 n=6)