Skip to content

Commit eb85928

Browse files
pelletierjcmfernandesclaude
authored
Support TOML v1.1.0 (#1068)
Co-authored-by: João Fernandes <joao@bckground.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent a7fae34 commit eb85928

8 files changed

Lines changed: 1839 additions & 527 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Go library for the [TOML](https://toml.io/en/) format.
44

5-
This library supports [TOML v1.0.0](https://toml.io/en/v1.0.0).
5+
This library supports [TOML v1.1.0](https://toml.io/en/v1.1.0).
66

77
[🐞 Bug Reports](https://github.com/pelletier/go-toml/issues)
88

@@ -70,7 +70,7 @@ this use-case, go-toml provides [`LocalDate`][tld], [`LocalTime`][tlt], and
7070
making them convenient yet unambiguous structures for their respective TOML
7171
representation.
7272

73-
[ldt]: https://toml.io/en/v1.0.0#local-date-time
73+
[ldt]: https://toml.io/en/v1.1.0#local-date-time
7474
[tld]: https://pkg.go.dev/github.com/pelletier/go-toml/v2#LocalDate
7575
[tlt]: https://pkg.go.dev/github.com/pelletier/go-toml/v2#LocalTime
7676
[tldt]: https://pkg.go.dev/github.com/pelletier/go-toml/v2#LocalDateTime

decode.go

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ func parseLocalDateTime(b []byte) (LocalDateTime, []byte, error) {
162162

163163
const localDateTimeByteMinLen = 11
164164
if len(b) < localDateTimeByteMinLen {
165-
return dt, nil, unstable.NewParserError(b, "local datetimes are expected to have the format YYYY-MM-DDTHH:MM:SS[.NNNNNNNNN]")
165+
return dt, nil, unstable.NewParserError(b, "local datetimes are expected to have the format YYYY-MM-DDTHH:MM[:SS[.NNNNNNNNN]]")
166166
}
167167

168168
date, err := parseLocalDate(b[:10])
@@ -194,10 +194,10 @@ func parseLocalTime(b []byte) (LocalTime, []byte, error) {
194194
t LocalTime
195195
)
196196

197-
// check if b matches to have expected format HH:MM:SS[.NNNNNN]
198-
const localTimeByteLen = 8
199-
if len(b) < localTimeByteLen {
200-
return t, nil, unstable.NewParserError(b, "times are expected to have the format HH:MM:SS[.NNNNNN]")
197+
// check if b matches to have expected format HH:MM[:SS[.NNNNNN]]
198+
const localTimeByteMinLen = 5
199+
if len(b) < localTimeByteMinLen {
200+
return t, nil, unstable.NewParserError(b, "times are expected to have the format HH:MM[:SS[.NNNNNN]]")
201201
}
202202

203203
var err error
@@ -221,22 +221,33 @@ func parseLocalTime(b []byte) (LocalTime, []byte, error) {
221221
if t.Minute > 59 {
222222
return t, nil, unstable.NewParserError(b[3:5], "minutes cannot be greater 59")
223223
}
224-
if b[5] != ':' {
225-
return t, nil, unstable.NewParserError(b[5:6], "expecting colon between minutes and seconds")
226-
}
227224

228-
t.Second, err = parseDecimalDigits(b[6:8])
229-
if err != nil {
230-
return t, nil, err
231-
}
225+
b = b[5:]
232226

233-
if t.Second > 59 {
234-
return t, nil, unstable.NewParserError(b[6:8], "seconds cannot be greater than 59")
235-
}
227+
// Seconds are optional (TOML v1.1.0). Fractional seconds may only appear
228+
// when seconds are present:
229+
// partial-time = time-hour ":" time-minute [ ":" time-second [ time-secfrac ] ]
230+
secondsPresent := false
231+
232+
if len(b) >= 1 && b[0] == ':' {
233+
if len(b) < 3 {
234+
return t, nil, unstable.NewParserError(b, "incomplete seconds")
235+
}
236236

237-
b = b[8:]
237+
t.Second, err = parseDecimalDigits(b[1:3])
238+
if err != nil {
239+
return t, nil, err
240+
}
241+
242+
if t.Second > 59 {
243+
return t, nil, unstable.NewParserError(b[1:3], "seconds cannot be greater than 59")
244+
}
245+
246+
b = b[3:]
247+
secondsPresent = true
248+
}
238249

239-
if len(b) >= 1 && b[0] == '.' {
250+
if secondsPresent && len(b) >= 1 && b[0] == '.' {
240251
frac := 0
241252
precision := 0
242253
digits := 0

localtime_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ func TestLocalTime_UnmarshalMarshalText(t *testing.T) {
6767
assert.Error(t, err)
6868
}
6969

70+
func TestLocalTime_UnmarshalText_WithoutSeconds(t *testing.T) {
71+
d := toml.LocalTime{}
72+
err := d.UnmarshalText([]byte("14:15"))
73+
assert.NoError(t, err)
74+
assert.Equal(t, toml.LocalTime{14, 15, 0, 0, 0}, d)
75+
}
76+
7077
func TestLocalTime_RoundTrip(t *testing.T) {
7178
var d struct{ A toml.LocalTime }
7279
err := toml.Unmarshal([]byte("a=20:12:01.500"), &d)

toml_testgen_support_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
//go:generate go run github.com/toml-lang/toml-test/cmd/toml-test@v1.6.0 -copy ./tests
2-
//go:generate go run ./cmd/tomltestgen/main.go -r v1.6.0 -o toml_testgen_test.go
1+
//go:generate go run github.com/toml-lang/toml-test/v2/cmd/toml-test@v2.1.0 copy -toml 1.1 ./tests
2+
//go:generate go run ./cmd/tomltestgen/main.go -r v2.1.0 -o toml_testgen_test.go
33

44
package toml_test
55

0 commit comments

Comments
 (0)